package com.gcsc.connection.apihub.dto;

import com.gcsc.connection.service.dto.ServiceApiResponse;
import com.gcsc.connection.service.entity.SnpApiDomain;
import com.gcsc.connection.service.entity.SnpService;
import com.gcsc.connection.service.entity.SnpServiceApi;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public record ServiceCatalogResponse(
    Long serviceId,
    String serviceCode,
    String serviceName,
    String serviceUrl,
    String description,
    String healthStatus,
    int apiCount,
    List<DomainGroup> domains
) {

    /**
     * 도메인 메타 정보(아이콘, 정렬) 없이 도메인명 기준 알파벳 정렬로 카탈로그 생성
     */
    public static ServiceCatalogResponse from(SnpService service, List<SnpServiceApi> apis) {
        return from(service, apis, Map.of());
    }

    /**
     * 도메인 메타 정보(아이콘, 정렬)를 포함하여 카탈로그 생성
     *
     * @param domainMap domainName → SnpApiDomain 매핑
     */
    public static ServiceCatalogResponse from(SnpService service, List<SnpServiceApi> apis,
                                              Map<String, SnpApiDomain> domainMap) {
        Map<String, List<ServiceApiResponse>> byDomain = apis.stream()
            .collect(Collectors.groupingBy(
                api -> api.getApiDomain() != null ? api.getApiDomain() : "",
                Collectors.mapping(ServiceApiResponse::from, Collectors.toList())
            ));

        List<DomainGroup> domainGroups = byDomain.entrySet().stream()
            .sorted((a, b) -> {
                SnpApiDomain da = domainMap.get(a.getKey());
                SnpApiDomain db = domainMap.get(b.getKey());
                int orderA = da != null ? da.getSortOrder() : Integer.MAX_VALUE;
                int orderB = db != null ? db.getSortOrder() : Integer.MAX_VALUE;
                if (orderA != orderB) {
                    return Integer.compare(orderA, orderB);
                }
                return a.getKey().compareTo(b.getKey());
            })
            .map(entry -> {
                SnpApiDomain domainMeta = domainMap.get(entry.getKey());
                String iconPath = domainMeta != null ? domainMeta.getIconPath() : null;
                int sortOrder = domainMeta != null ? domainMeta.getSortOrder() : Integer.MAX_VALUE;
                return new DomainGroup(entry.getKey(), iconPath, sortOrder, entry.getValue());
            })
            .toList();

        return new ServiceCatalogResponse(
            service.getServiceId(),
            service.getServiceCode(),
            service.getServiceName(),
            service.getServiceUrl(),
            service.getDescription(),
            service.getHealthStatus().name(),
            apis.size(),
            domainGroups
        );
    }
}
