package go.kr.project.api.config.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
@ConfigurationProperties(prefix = "vmis")
@Validated
public class VmisProperties {

    @NotNull
    private IntegrationProps integration = new IntegrationProps();
    @NotNull
    private RestTemplateProps restTemplate = new RestTemplateProps();
    @NotNull
    private SystemProps system = new SystemProps();
    @NotNull
    private GpkiProps gpki = new GpkiProps();
    @NotNull
    private GovProps gov = new GovProps();
    @NotNull
    private ExternalProps external = new ExternalProps();

    @Data
    public static class IntegrationProps {
        @NotBlank
        private String mode = "external";
    }

    @Data
    public static class ExternalProps {
        @NotNull
        private ApiProps api = new ApiProps();

        @Data
        public static class ApiProps {
            @NotNull
            private UrlProps url = new UrlProps();

            @Data
            public static class UrlProps {
                @NotBlank
                private String base = "http://localhost:8081/api/v1/vehicles"; // 기본 Base URL
                @NotBlank
                private String basic = "/basic";   // 자동차기본정보 엔드포인트 경로
                @NotBlank
                private String ledger = "/ledger"; // 자동차등록원부 엔드포인트 경로

                // 중요: 외부 VMIS-interface 호출용 전체 URL 조합 헬퍼 (공통 RestTemplate 타임아웃 설정 사용)
                public String buildBasicUrl() { return join(base, basic); }
                public String buildLedgerUrl() { return join(base, ledger); }

                private String join(String base, String path) {
                    String b = base;
                    String p = path;
                    if (b.endsWith("/")) {
                        b = b.substring(0, b.length() - 1);
                    }
                    if (!p.startsWith("/")) {
                        p = "/" + p;
                    }
                    return b + p;
                }
            }
        }
    }

    @Data
    public static class SystemProps {
        @NotBlank
        private String infoSysId;
        /** INFO_SYS_IP */
        private String infoSysIp;
        /** 시군구코드 (SIGUNGU_CODE) */
        private String sigunguCode;
        private String departmentCode;
        // 담당자 정보
        private String chargerId;
        private String chargerIp;
        private String chargerNm;
    }

    @Data
    public static class GpkiProps {
        /** "Y" 또는 "N" */
        @NotBlank
        private String enabled = "N";
        private boolean useSign = true;
        @NotBlank
        private String charset = "UTF-8";
        @NotBlank
        private String certServerId;
        @NotBlank
        private String targetServerId;
        // Optional advanced config for native GPKI util
        private Boolean ldap;               // null -> util default
        private String gpkiLicPath;         // e.g., C:/gpki2/gpkisecureweb/conf
        private String certFilePath;        // directory for target cert files when LDAP=false
        private String envCertFilePathName; // ..._env.cer
        private String envPrivateKeyFilePathName; // ..._env.key
        private String envPrivateKeyPasswd;
        private String sigCertFilePathName; // ..._sig.cer
        private String sigPrivateKeyFilePathName; // ..._sig.key
        private String sigPrivateKeyPasswd;

        public boolean isEnabledFlag() { return "Y".equalsIgnoreCase(enabled); }
    }

    @Data
    public static class RestTemplateProps {
        @NotNull
        private ModeConfig internal = new ModeConfig();
        @NotNull
        private ModeConfig external = new ModeConfig();

        @Data
        public static class ModeConfig {
            @NotNull
            private TimeoutConfig timeout = new TimeoutConfig();
            @NotNull
            private ConnectionPoolConfig connectionPool = new ConnectionPoolConfig();
            @NotNull
            private RateLimitConfig rateLimit = new RateLimitConfig();

            @Data
            public static class TimeoutConfig {
                private int connectTimeoutMillis = 10000;
                private int readTimeoutMillis = 12000;
            }

            @Data
            public static class ConnectionPoolConfig {
                private int maxTotal = 100;
                private int maxPerRoute = 20;
            }

            @Data
            public static class RateLimitConfig {
                private double permitsPerSecond = 5.0;
            }
        }
    }

    @Data
    public static class GovProps {
        @NotBlank
        private String scheme = "http";
        @NotBlank
        private String host;
        @NotBlank
        private String basePath;
        @NotNull
        private Services services = new Services();

        public String buildServiceUrl(String path) {
            StringBuilder sb = new StringBuilder();
            sb.append(scheme).append("://").append(host);
            if (basePath != null && !basePath.isEmpty()) {
                if (!basePath.startsWith("/")) sb.append('/');
                sb.append(basePath);
            }
            if (path != null && !path.isEmpty()) {
                if (!path.startsWith("/")) sb.append('/');
                sb.append(path);
            }
            return sb.toString();
        }

        @Data
        public static class Services {
            @NotNull
            private Service basic = new Service();
            @NotNull
            private Service ledger = new Service();
        }

        @Data
        public static class Service {
            @NotBlank
            private String path;
            @NotBlank
            private String cntcInfoCode;
            @NotBlank
            private String apiKey;
            @NotBlank
            private String cvmisApikey;
        }
    }
}
