package go.kr.project.carInspectionPenalty.registrationOm.service.impl;

import egovframework.util.DateUtil;
import egovframework.util.StringUtil;
import go.kr.project.api.model.response.NewLedgerResponse;

/**
 * 과태료 대상 미필 비교 비고(Remark) 생성 유틸리티 클래스
 *
 * <p>각 비교 로직별 비고 문자열을 생성하는 메서드를 제공합니다.</p>
 * <p>미필의 경우 부과일자 = 검사유효기간 종료일 + 146일</p>
 *
 * <p>비고 패턴:</p>
 * <ul>
 *   <li>1. 상품용: 상품용</li>
 *   <li>2. 명의이전 소유자 확인: 명의이전(25.5.19.) 이전소유자 상품용, 시군구명/ 소유자명</li>
 *   <li>3. 미수검명의이전: 미수검명의이전(25.5.19.)(차량번호)</li>
 *   <li>4. 이첩: 시군구명/ 소유자명, 115일 도래지</li>
 * </ul>
 */
public class ComparisonOmRemarkBuilder {

    /**
     * 상품용 비고 생성 - 미필
     * 비고 형식: 상품용
     *
     * @return 비고 문자열
     */
    public static String buildProductUseRemark() {
        return "상품용";
    }

    /**
     * 명의이전 이전소유자 상품용 비고 생성 - 미필
     * 비고 형식: 명의이전(25.9.5.) 이전소유자 상품용
     *
     * @param ledgerRecord 조건에 맞는 갑부 레코드 (명의이전 레코드)
     * @return 비고 문자열
     */
    public static String buildProductCloseLevyRemark(NewLedgerResponse.Record ledgerRecord) {
        String chgYmdFormatted = DateUtil.formatToShortDate(ledgerRecord.getChgYmd());
        return String.format("명의이전(%s) 이전소유자 상품용", chgYmdFormatted);
    }

    /**
     * 미수검명의이전 비고 생성 - 미필
     * 비고 형식: 시군구명/ 소유자명, 미수검명의이전(25.5.19.)(차량번호)
     *
     * @param ledgerRecord 조건에 맞는 갑부 레코드 (명의이전 레코드)
     * @param sggNm 시군구명
     * @param ownerNm 소유자명
     * @param vhclno 차량번호
     * @return 비고 문자열
     */
    public static String buildOwnerChangeRemark(NewLedgerResponse.Record ledgerRecord,
                                                 String sggNm, String ownerNm, String vhclno) {
        String chgYmdFormatted = DateUtil.formatToShortDate(ledgerRecord.getChgYmd());
        return String.format("%s/ %s, 미수검명의이전(%s)(%s)",
                StringUtil.nvl(sggNm), StringUtil.nvl(ownerNm), chgYmdFormatted, StringUtil.nvl(vhclno));
    }

    /**
     * 이첩 비고 생성 - 미필
     * 비고 형식: 시군구명/ 소유자명, 115일 도래지
     *
     * @param sggNm 시군구명
     * @param ownerNm 소유자명
     * @return 비고 문자열
     */
    public static String buildTransferRemark(String sggNm, String ownerNm) {
        return String.format("%s/ %s, 115일 도래지", StringUtil.nvl(sggNm), StringUtil.nvl(ownerNm));
    }

    // ========================== 비고 상세 (RMRK_DTL) 생성 메서드 ==========================

    /**
     * 상품용 비고 상세 생성 - 미필
     *
     * @param vhclno 차량번호
     * @param inspVldPrdEnd 검사유효기간 종료일
     * @param levyCrtrYmd 부과기준일자 (검사유효기간+146일)
     * @param step1OwnerNm Step1 소유자명 (부과일자 기준)
     * @param targetChgYmd 갑부 변경일자
     * @param step4OwnerNm Step4 소유자명 (변경일 전일 기준)
     * @return 비고 상세 문자열
     */
    public static String buildProductUseRemarkDetail(String vhclno, String inspVldPrdEnd,
                                                      String levyCrtrYmd, String step1OwnerNm,
                                                      String targetChgYmd, String step4OwnerNm) {
        StringBuilder sb = new StringBuilder();
        sb.append("[상품용 판정 - 미필]\n\n");

        sb.append("=== 기본 정보 ===\n");
        sb.append("차량번호: ").append(StringUtil.nvl(vhclno)).append("\n");
        sb.append("검사유효기간 종료일: ").append(DateUtil.formatDateString(inspVldPrdEnd)).append("\n");
        sb.append("부과기준일자 계산: 검사유효기간 종료일 + 146일 = ").append(DateUtil.formatDateString(levyCrtrYmd)).append("\n");
        sb.append("검사유효기간 종료일 + 31일 기준일: ").append(DateUtil.formatDateString(
            DateUtil.parseDate(inspVldPrdEnd).plusDays(31).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
        )).append("\n\n");

        sb.append("=== API 호출 및 비교 과정 ===\n");
        sb.append("Step1) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차량번호 + 부과일자(").append(DateUtil.formatDateString(levyCrtrYmd)).append(")\n");
        sb.append("  - 소유자명: ").append(StringUtil.nvl(step1OwnerNm)).append("\n");
        sb.append("  - 조건 확인: 소유자명에 '상품용' 포함 여부 → O\n\n");

        sb.append("Step2) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차대번호 + 오늘일자\n");
        sb.append("  - 목적: 차량번호, 성명, 주민번호, 법정동코드 조회\n\n");

        sb.append("Step3) 자동차등록원부(갑) 조회\n");
        sb.append("  - 조회 기준: 차량번호 + 성명 + 주민번호 + 법정동코드\n");
        sb.append("  - 검색 조건:\n");
        sb.append("    · 변경업무구분코드(CHG_TASK_SE_CD) = '11' (명의이전)\n");
        sb.append("    · 변경일자(CHG_YMD) ≤ 검사유효기간 종료일+31일 (").append(DateUtil.formatDateString(
            DateUtil.parseDate(inspVldPrdEnd).plusDays(31).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
        )).append(")\n");
        sb.append("    · 조건 충족하는 레코드 중 가장 마지막 일자 선택\n");
        sb.append("  - 선택된 갑부 변경일자: ").append(DateUtil.formatDateString(targetChgYmd)).append("\n\n");

        sb.append("Step4) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차대번호 + 갑부 변경일자(").append(DateUtil.formatDateString(targetChgYmd)).append(")\n");
        sb.append("  - 변경일 기준 소유자명: ").append(StringUtil.nvl(step4OwnerNm)).append("\n");
        sb.append("  - 조건 확인: Step1 대표소유자 회원번호 = Step4 대표소유자 회원번호 → 일치\n\n");

        sb.append("=== 판정 근거 ===\n");
        sb.append("1. 부과일자(검사유효기간 종료일+146일) 기준 소유자명에 '상품용' 포함\n");
        sb.append("2. 갑부 상세에서 변경업무구분코드 '11'(명의이전) 레코드가 검사유효기간 종료일+31일 이내에 존재\n");
        sb.append("3. 갑부 변경일자 시점의 대표소유자 회원번호와 부과일자 기준 대표소유자 회원번호가 동일\n");
        sb.append("→ 상품용 판정 (처리상태: 02_상품용)\n");

        return sb.toString();
    }

    /**
     * 명의이전 이전소유자 상품용 비고 상세 생성 - 미필
     *
     * @param vhclno 차량번호
     * @param inspVldPrdEnd 검사유효기간 종료일
     * @param levyCrtrYmd 부과기준일자 (검사유효기간+146일)
     * @param step1OwnerNm Step1 소유자명
     * @param targetChgYmd 갑부 명의이전 일자
     * @param step4OwnerNm Step4 소유자명 (명의이전 전 소유자)
     * @return 비고 상세 문자열
     */
    public static String buildProductCloseLevyRemarkDetail(String vhclno, String inspVldPrdEnd,
                                                            String levyCrtrYmd, String step1OwnerNm,
                                                            String targetChgYmd, String step4OwnerNm) {
        StringBuilder sb = new StringBuilder();
        sb.append("[명의이전 이전소유자 상품용 판정 - 미필]\n\n");

        sb.append("=== 기본 정보 ===\n");
        sb.append("차량번호: ").append(StringUtil.nvl(vhclno)).append("\n");
        sb.append("검사유효기간 종료일: ").append(DateUtil.formatDateString(inspVldPrdEnd)).append("\n");
        sb.append("부과기준일자 계산: 검사유효기간 종료일 + 146일 = ").append(DateUtil.formatDateString(levyCrtrYmd)).append("\n");
        sb.append("검사유효기간 종료일 + 31일 기준일: ").append(DateUtil.formatDateString(
            DateUtil.parseDate(inspVldPrdEnd).plusDays(31).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
        )).append("\n\n");

        sb.append("=== API 호출 및 비교 과정 ===\n");
        sb.append("Step1) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차량번호 + 부과일자(").append(DateUtil.formatDateString(levyCrtrYmd)).append(")\n");
        sb.append("  - 소유자명: ").append(StringUtil.nvl(step1OwnerNm)).append("\n");
        sb.append("  - 조건 확인: 소유자명에 '상품용' 포함 여부 → X\n\n");

        sb.append("Step2) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차대번호 + 오늘일자\n");
        sb.append("  - 목적: 차량번호, 성명, 주민번호, 법정동코드 조회\n\n");

        sb.append("Step3) 자동차등록원부(갑) 조회\n");
        sb.append("  - 조회 기준: 차량번호 + 성명 + 주민번호 + 법정동코드\n");
        sb.append("  - 검색 조건:\n");
        sb.append("    · 변경업무구분코드(CHG_TASK_SE_CD) = '11' (명의이전)\n");
        sb.append("    · 변경일자(CHG_YMD) > 검사유효기간 종료일+31일 (").append(DateUtil.formatDateString(
            DateUtil.parseDate(inspVldPrdEnd).plusDays(31).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
        )).append(")\n");
        sb.append("    · 조건 충족하는 레코드 중 가장 마지막 일자 선택\n");
        sb.append("  - 선택된 갑부 명의이전 일자: ").append(DateUtil.formatDateString(targetChgYmd)).append("\n\n");

        sb.append("Step4) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차대번호 + 명의이전일자-1일(").append(DateUtil.formatDateString(
            DateUtil.parseDate(targetChgYmd).minusDays(1).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
        )).append(")\n");
        sb.append("  - 명의이전 전 소유자명: ").append(StringUtil.nvl(step4OwnerNm)).append("\n");
        sb.append("  - 조건 확인: 명의이전 전 소유자명에 '상품용' 포함 → O\n\n");

        sb.append("=== 판정 근거 ===\n");
        sb.append("1. 부과일자(검사유효기간 종료일+146일) 기준 소유자명에 '상품용' 미포함\n");
        sb.append("2. 갑부 상세에서 변경업무구분코드 '11'(명의이전) 레코드가 검사유효기간 종료일+31일 이후에 존재\n");
        sb.append("3. 명의이전일자-1일 시점의 소유자명에 '상품용' 포함\n");
        sb.append("→ 명의이전 이전소유자 상품용 판정 (처리상태: 01_접수)\n");

        return sb.toString();
    }

    /**
     * 미수검명의이전 비고 상세 생성 - 미필
     *
     * @param vhclno 차량번호
     * @param inspVldPrdEnd 검사유효기간 종료일
     * @param levyCrtrYmd 부과기준일자 (검사유효기간+146일)
     * @param step1OwnerNm Step1 소유자명
     * @param targetChgYmd 갑부 명의이전 일자
     * @param step4OwnerNm Step4 소유자명 (명의이전 전 소유자)
     * @return 비고 상세 문자열
     */
    public static String buildOwnerChangeRemarkDetail(String vhclno, String inspVldPrdEnd,
                                                       String levyCrtrYmd, String step1OwnerNm,
                                                       String targetChgYmd, String step4OwnerNm) {
        StringBuilder sb = new StringBuilder();
        sb.append("[미수검명의이전 판정 - 미필]\n\n");

        sb.append("=== 기본 정보 ===\n");
        sb.append("차량번호: ").append(StringUtil.nvl(vhclno)).append("\n");
        sb.append("검사유효기간 종료일: ").append(DateUtil.formatDateString(inspVldPrdEnd)).append("\n");
        sb.append("부과기준일자 계산: 검사유효기간 종료일 + 146일 = ").append(DateUtil.formatDateString(levyCrtrYmd)).append("\n");
        sb.append("검사유효기간 종료일 + 31일 기준일: ").append(DateUtil.formatDateString(
            DateUtil.parseDate(inspVldPrdEnd).plusDays(31).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
        )).append("\n\n");

        sb.append("=== API 호출 및 비교 과정 ===\n");
        sb.append("Step1) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차량번호 + 부과일자(").append(DateUtil.formatDateString(levyCrtrYmd)).append(")\n");
        sb.append("  - 소유자명: ").append(StringUtil.nvl(step1OwnerNm)).append("\n");
        sb.append("  - 조건 확인: 소유자명에 '상품용' 포함 여부 → X\n\n");

        sb.append("Step2) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차대번호 + 오늘일자\n");
        sb.append("  - 목적: 차량번호, 성명, 주민번호, 법정동코드 조회\n\n");

        sb.append("Step3) 자동차등록원부(갑) 조회\n");
        sb.append("  - 조회 기준: 차량번호 + 성명 + 주민번호 + 법정동코드\n");
        sb.append("  - 검색 조건:\n");
        sb.append("    · 변경업무구분코드(CHG_TASK_SE_CD) = '11' (명의이전)\n");
        sb.append("    · 변경일자(CHG_YMD) > 검사유효기간 종료일+31일 (").append(DateUtil.formatDateString(
            DateUtil.parseDate(inspVldPrdEnd).plusDays(31).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
        )).append(")\n");
        sb.append("    · 조건 충족하는 레코드 중 가장 마지막 일자 선택\n");
        sb.append("  - 선택된 갑부 명의이전 일자: ").append(DateUtil.formatDateString(targetChgYmd)).append("\n\n");

        sb.append("Step4) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차대번호 + 명의이전일자-1일(").append(DateUtil.formatDateString(
            DateUtil.parseDate(targetChgYmd).minusDays(1).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
        )).append(")\n");
        sb.append("  - 명의이전 전 소유자명: ").append(StringUtil.nvl(step4OwnerNm)).append("\n");
        sb.append("  - 조건 확인: 부과일자 기준 소유자 = 명의이전 전 소유자 → 동일\n");
        sb.append("  - 명의이전 전 소유자명에 '상품용' 포함 → X\n\n");

        sb.append("=== 판정 근거 ===\n");
        sb.append("1. 부과일자(검사유효기간 종료일+146일) 기준 소유자명에 '상품용' 미포함\n");
        sb.append("2. 갑부 상세에서 변경업무구분코드 '11'(명의이전) 레코드가 검사유효기간 종료일+31일 이후에 존재\n");
        sb.append("3. 명의이전 전 소유자명과 부과일자 기준 소유자명이 동일 (미수검 상태에서 명의이전 발생)\n");
        sb.append("4. 명의이전 전 소유자명에 '상품용' 미포함\n");
        sb.append("→ 미수검명의이전 판정 (처리상태: 01_접수)\n");

        return sb.toString();
    }

    /**
     * 이첩 비고 상세 생성 - 미필
     *
     * @param vhclno 차량번호
     * @param inspVldPrdEnd 검사유효기간 종료일
     * @param levyCrtrYmd 부과기준일자 (검사유효기간+146일)
     * @param ownerNm 소유자명
     * @param usgsrhldStdgCd 사용본거지법정동코드
     * @param sggNm 시군구명
     * @param userOrgCd 사용자 조직코드
     * @return 비고 상세 문자열
     */
    public static String buildTransferRemarkDetail(String vhclno, String inspVldPrdEnd,
                                                    String levyCrtrYmd, String ownerNm,
                                                    String usgsrhldStdgCd, String sggNm, String userOrgCd) {
        StringBuilder sb = new StringBuilder();
        sb.append("[이첩 판정 - 미필]\n\n");

        sb.append("=== 기본 정보 ===\n");
        sb.append("차량번호: ").append(StringUtil.nvl(vhclno)).append("\n");
        sb.append("검사유효기간 종료일: ").append(DateUtil.formatDateString(inspVldPrdEnd)).append("\n");
        sb.append("부과기준일자 계산: 검사유효기간 종료일 + 146일 = ").append(DateUtil.formatDateString(levyCrtrYmd)).append("\n");
        sb.append("검사유효기간 종료일 - 90일: ").append(DateUtil.formatDateString(
            DateUtil.parseDate(inspVldPrdEnd).minusDays(90).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
        )).append("\n\n");

        sb.append("=== API 호출 및 비교 과정 ===\n");
        sb.append("Step1) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차량번호 + 부과일자(").append(DateUtil.formatDateString(levyCrtrYmd)).append(")\n");
        sb.append("  - 소유자명: ").append(StringUtil.nvl(ownerNm)).append("\n");
        sb.append("  - 사용본거지법정동코드: ").append(StringUtil.nvl(usgsrhldStdgCd)).append("\n");
        sb.append("  - 조건 확인: 소유자명에 '상품용' 포함 여부 → X\n\n");

        sb.append("Step2) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차대번호 + 검사유효기간 종료일-90일(").append(DateUtil.formatDateString(
            DateUtil.parseDate(inspVldPrdEnd).minusDays(90).format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
        )).append(")\n");
        sb.append("  - 조건 확인: Step1 대표소유자 회원번호 = Step2 대표소유자 회원번호 → 동일\n\n");

        sb.append("Step3) 자동차기본정보 조회\n");
        sb.append("  - 조회 기준: 차대번호 + 오늘일자\n");
        sb.append("  - 조건 확인: Step1 대표소유자 회원번호 = Step3 대표소유자 회원번호 → 동일\n\n");

        sb.append("=== 법정동코드 비교 ===\n");
        String legalDong4 = usgsrhldStdgCd != null && usgsrhldStdgCd.length() >= 4 ? usgsrhldStdgCd.substring(0, 4) : "";
        String userOrg4 = userOrgCd != null && userOrgCd.length() >= 4 ? userOrgCd.substring(0, 4) : "";
        sb.append("사용본거지법정동코드 앞 4자리: ").append(legalDong4).append("\n");
        sb.append("현재 사용자 조직코드 앞 4자리: ").append(userOrg4).append("\n");
        sb.append("코드 불일치 → 이첩 대상\n");
        sb.append("시군구코드: ").append(usgsrhldStdgCd != null && usgsrhldStdgCd.length() >= 5 ? usgsrhldStdgCd.substring(0, 5) : "").append("\n");
        sb.append("시군구명: ").append(StringUtil.nvl(sggNm)).append("\n\n");

        sb.append("=== 판정 근거 ===\n");
        sb.append("1. 부과일자(검사유효기간 종료일+146일) 기준 소유자명에 '상품용' 미포함\n");
        sb.append("2. 부과일자/검사유효기간 종료일-90일/오늘일자 세 시점의 대표소유자 회원번호 모두 동일 (소유자 변동 없음)\n");
        sb.append("3. 사용본거지법정동코드 앞 4자리와 현재 사용자 조직코드 앞 4자리가 불일치\n");
        sb.append("→ 이첩 판정 (처리상태: 03_이첩, 115일 도래지)\n");

        return sb.toString();
    }

    /**
     * 문자열 최대 길이 제한 (한글 3바이트 기준 약 1300자)
     *
     * @param str 원본 문자열
     * @return 제한된 문자열
     */
    private static String truncateToMaxLength(String str) {
        if (str == null) {
            return "";
        }
        // 4000바이트 / 3(한글) = 약 1333자, 여유있게 1300자로 제한
        if (str.length() > 1300) {
            return str.substring(0, 1297) + "...";
        }
        return str;
    }

    /**
     * 등록원부 갑부 레코드 상세 정보 생성
     *
     * @param record 갑부 레코드
     * @return 상세 정보 문자열
     */
    public static String buildLedgerRecordDetail(NewLedgerResponse.Record record) {
        if (record == null) {
            return "";
        }

        StringBuilder detail = new StringBuilder();

        StringUtil.appendIfNotEmpty(detail, "변경업무구분코드", record.getChgTaskSeCd());
        StringUtil.appendIfNotEmpty(detail, "변경업무구분명", record.getChgTaskSeNm());
        StringUtil.appendIfNotEmpty(detail, "변경일자", DateUtil.formatDateString(record.getChgYmd()));
        StringUtil.appendIfNotEmpty(detail, "주요번호", record.getMainNo());
        StringUtil.appendIfNotEmpty(detail, "일련번호", record.getSno());
        StringUtil.appendIfNotEmpty(detail, "특별사항", record.getSpcablMttr());
        StringUtil.appendIfNotEmpty(detail, "명의자명", record.getHshldrNm());
        StringUtil.appendIfNotEmpty(detail, "명의자식별번호", StringUtil.maskIdecno(record.getHshldrIdecno()));
        StringUtil.appendIfNotEmpty(detail, "신청접수번호", record.getAplyRcptNo());
        StringUtil.appendIfNotEmpty(detail, "차량관리번호", record.getVhmno());
        StringUtil.appendIfNotEmpty(detail, "원부그룹번호", record.getLedgerGroupNo());
        StringUtil.appendIfNotEmpty(detail, "원부개별번호", record.getLedgerIndivNo());
        StringUtil.appendIfNotEmpty(detail, "상세일련번호", record.getDtlSn());

        return detail.toString();
    }
}
