package com.ga.api.service.upload;

import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * 업로드 템플릿의 target_table 별로 사용 가능한 컬럼(target_field) 메타데이터.
 * 화이트리스트 역할 + 프론트 Select 옵션 제공.
 */
@Service
public class TargetFieldMetaService {

    public record TargetFieldMeta(
            String field,        // DB 컬럼명 (e.g. policy_no)
            String label,        // 한글 표시명
            String type,         // STRING / NUMBER / DECIMAL / DATE / INTEGER
            boolean required) {}

    private static final Map<String, List<TargetFieldMeta>> META = Map.of(
            "recruit_ledger", List.of(
                    new TargetFieldMeta("policy_no",       "증권번호",       "STRING",  true),
                    new TargetFieldMeta("agent_id",        "설계사ID",       "INTEGER", false),
                    new TargetFieldMeta("contract_id",     "계약ID",         "INTEGER", false),
                    new TargetFieldMeta("company_code",    "보험사코드",     "STRING",  false),
                    new TargetFieldMeta("product_code",    "상품코드",       "STRING",  false),
                    new TargetFieldMeta("insurance_type",  "보험종류",       "STRING",  false),
                    new TargetFieldMeta("commission_year", "회차",           "INTEGER", false),
                    new TargetFieldMeta("premium",         "보험료",         "DECIMAL", true),
                    new TargetFieldMeta("pay_method",      "납입주기",       "STRING",  false),
                    new TargetFieldMeta("company_rate",    "회사율(%)",      "DECIMAL", false),
                    new TargetFieldMeta("company_amount",  "회사수수료",     "DECIMAL", true),
                    new TargetFieldMeta("payout_rate",     "지급율(%)",      "DECIMAL", false),
                    new TargetFieldMeta("agent_amount",    "설계사수수료",   "DECIMAL", false),
                    new TargetFieldMeta("settle_month",    "정산월",         "STRING",  true),
                    new TargetFieldMeta("status",          "상태",           "STRING",  false)
            ),
            "maintain_ledger", List.of(
                    new TargetFieldMeta("policy_no",       "증권번호",       "STRING",  true),
                    new TargetFieldMeta("agent_id",        "설계사ID",       "INTEGER", false),
                    new TargetFieldMeta("contract_id",     "계약ID",         "INTEGER", false),
                    new TargetFieldMeta("company_code",    "보험사코드",     "STRING",  false),
                    new TargetFieldMeta("product_code",    "상품코드",       "STRING",  false),
                    new TargetFieldMeta("insurance_type",  "보험종류",       "STRING",  false),
                    new TargetFieldMeta("commission_year", "회차",           "INTEGER", true),
                    new TargetFieldMeta("premium",         "보험료",         "DECIMAL", true),
                    new TargetFieldMeta("company_amount",  "회사수수료",     "DECIMAL", true),
                    new TargetFieldMeta("agent_amount",    "설계사수수료",   "DECIMAL", false),
                    new TargetFieldMeta("settle_month",    "정산월",         "STRING",  true)
            ),
            "contract", List.of(
                    new TargetFieldMeta("policy_no",       "증권번호",       "STRING",  true),
                    new TargetFieldMeta("agent_id",        "설계사ID",       "INTEGER", true),
                    new TargetFieldMeta("product_id",      "상품ID",         "INTEGER", true),
                    new TargetFieldMeta("contractor_name", "계약자",         "STRING",  false),
                    new TargetFieldMeta("insured_name",    "피보험자",       "STRING",  false),
                    new TargetFieldMeta("premium",         "보험료",         "DECIMAL", false),
                    new TargetFieldMeta("pay_cycle",       "납입주기",       "STRING",  false),
                    new TargetFieldMeta("contract_date",   "계약일",         "DATE",    true),
                    new TargetFieldMeta("effective_date",  "효력발생일",     "DATE",    false),
                    new TargetFieldMeta("status",          "상태",           "STRING",  false)
            ),
            "agent", List.of(
                    new TargetFieldMeta("agent_name",  "설계사명",   "STRING",  true),
                    new TargetFieldMeta("license_no",  "사번",       "STRING",  false),
                    new TargetFieldMeta("org_id",      "조직ID",     "INTEGER", true),
                    new TargetFieldMeta("grade_id",    "직급ID",     "INTEGER", true),
                    new TargetFieldMeta("phone",       "전화번호",   "STRING",  false),
                    new TargetFieldMeta("email",       "이메일",     "STRING",  false),
                    new TargetFieldMeta("bank_code",   "은행코드",   "STRING",  false),
                    new TargetFieldMeta("account_no",  "계좌번호",   "STRING",  false),
                    new TargetFieldMeta("status",      "상태",       "STRING",  false),
                    new TargetFieldMeta("join_date",   "입사일",     "DATE",    false)
            ),
            "commission_rate", List.of(
                    new TargetFieldMeta("product_id",      "상품ID",         "INTEGER", true),
                    new TargetFieldMeta("commission_year", "회차",           "INTEGER", true),
                    new TargetFieldMeta("rate_pct",        "수수료율(%)",    "DECIMAL", true),
                    new TargetFieldMeta("pay_method_cond", "납입조건",       "STRING",  false),
                    new TargetFieldMeta("min_premium",     "최소보험료",     "DECIMAL", false),
                    new TargetFieldMeta("effective_from",  "적용시작",       "DATE",    true),
                    new TargetFieldMeta("effective_to",    "적용종료",       "DATE",    false)
            ),
            "payout_rule", List.of(
                    new TargetFieldMeta("grade_id",        "직급ID",         "INTEGER", true),
                    new TargetFieldMeta("insurance_type",  "보험종류",       "STRING",  true),
                    new TargetFieldMeta("commission_year", "회차",           "INTEGER", true),
                    new TargetFieldMeta("payout_pct",      "지급율(%)",      "DECIMAL", true),
                    new TargetFieldMeta("pay_method_cond", "납입조건",       "STRING",  false),
                    new TargetFieldMeta("performance_grade","실적등급",      "STRING",  false),
                    new TargetFieldMeta("effective_from",  "적용시작",       "DATE",    true)
            ),
            "chargeback_rule", List.of(
                    new TargetFieldMeta("company_code",    "보험사코드",     "STRING",  true),
                    new TargetFieldMeta("insurance_type",  "보험종류",       "STRING",  true),
                    new TargetFieldMeta("lapse_month_from","실효시작월",     "INTEGER", true),
                    new TargetFieldMeta("lapse_month_to",  "실효종료월",     "INTEGER", true),
                    new TargetFieldMeta("cb_rate",         "환수율(%)",      "DECIMAL", true),
                    new TargetFieldMeta("include_override","오버라이드포함", "STRING",  false)
            ),
            "exception_ledger", List.of(
                    new TargetFieldMeta("agent_id",       "설계사ID",       "INTEGER", true),
                    new TargetFieldMeta("exception_code", "예외코드",       "STRING",  true),
                    new TargetFieldMeta("amount",         "금액",           "DECIMAL", true),
                    new TargetFieldMeta("settle_month",   "정산월",         "STRING",  true),
                    new TargetFieldMeta("policy_no",      "증권번호",       "STRING",  false),
                    new TargetFieldMeta("description",    "내용",           "STRING",  false)
            ),
            "payment", List.of(
                    new TargetFieldMeta("settle_id",   "정산ID",     "INTEGER", true),
                    new TargetFieldMeta("agent_id",    "설계사ID",   "INTEGER", true),
                    new TargetFieldMeta("pay_month",   "지급월",     "STRING",  true),
                    new TargetFieldMeta("net_amount",  "지급액",     "DECIMAL", true),
                    new TargetFieldMeta("bank_code",   "은행코드",   "STRING",  false),
                    new TargetFieldMeta("account_no",  "계좌번호",   "STRING",  false)
            )
    );

    public List<TargetFieldMeta> getFields(String targetTable) {
        if (targetTable == null) {
            throw new BizException(ErrorCode.INVALID_PARAMETER, "target_table 누락");
        }
        List<TargetFieldMeta> fields = META.get(targetTable);
        if (fields == null) {
            throw new BizException(ErrorCode.INVALID_PARAMETER,
                    "허용되지 않은 target_table: " + targetTable + " (가능: " + META.keySet() + ")");
        }
        return fields;
    }

    public List<String> getAvailableTables() {
        return List.copyOf(META.keySet());
    }
}
