package kr.itn.itnhub.seed;

import kr.itn.itnhub.provision.ChannelNaming;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 신유형 신청목록 시트를 대표기관 단위로 축약한다.
 *
 * 시트 배치 (1행 그룹제목, 2행 헤더, 3행부터 데이터):
 *   B=연번1  C=연번2  F=기관명  G=부서명  H=담당자명  I=직급/직함  J=유선전화  K=이메일
 *
 * 축약 규칙:
 *   - 연번2가 "00"인 행이 대표기관이며 담당자 정보를 갖는다
 *   - 나머지 하위기관 행은 대표기관에 흡수한다 (008 경찰청의 서울청·부산청 등)
 *   - 단 경찰청_치안정책연구소만 예외로 별도 기관으로 남긴다
 */
@Component
public class SeedParser {

    public static final String SHEET_NAME = "신유형 신청목록";

    private static final int DATA_START_ROW_INDEX = 2; // 3행
    private static final int COL_ORG_NO = 1;    // B
    private static final int COL_SUB_NO = 2;    // C
    private static final int COL_ORG_NAME = 5;  // F
    private static final int COL_DEPT = 6;      // G
    private static final int COL_MANAGER = 7;   // H
    private static final int COL_TITLE = 8;     // I
    private static final int COL_PHONE = 9;     // J
    private static final int COL_EMAIL = 10;    // K

    public List<SeedRow> parse(InputStream xlsx) {
        try (Workbook wb = WorkbookFactory.create(xlsx)) {
            Sheet sheet = wb.getSheet(SHEET_NAME);
            if (sheet == null) {
                throw new SeedParseException(
                        "통합문서에 '" + SHEET_NAME + "' 시트가 없습니다.");
            }
            return readRows(sheet);
        } catch (IOException e) {
            throw new SeedParseException("엑셀 파일을 읽지 못했습니다.", e);
        }
    }

    private List<SeedRow> readRows(Sheet sheet) {
        List<SeedRow> result = new ArrayList<>();

        for (int i = DATA_START_ROW_INDEX; i <= sheet.getLastRowNum(); i++) {
            Row row = sheet.getRow(i);
            if (row == null) {
                continue;
            }

            String orgNo = orgNo(row);
            String orgName = string(row, COL_ORG_NAME);
            if (orgNo.isBlank() || orgName.isBlank()) {
                continue;
            }

            boolean representative = "00".equals(subNo(row));
            boolean special = ChannelNaming.SPECIAL_ORG_NAME.equalsIgnoreCase(orgName);

            if (!representative && !special) {
                continue; // 하위기관은 대표기관에 흡수된다
            }

            result.add(new SeedRow(
                    orgNo,
                    orgName,
                    special ? orgNo + "-policy" : orgNo,
                    nullIfBlank(string(row, COL_DEPT)),
                    nullIfBlank(string(row, COL_MANAGER)),
                    nullIfBlank(string(row, COL_TITLE)),
                    nullIfBlank(string(row, COL_PHONE)),
                    nullIfBlank(string(row, COL_EMAIL))));
        }
        return result;
    }

    /** 연번은 항상 3자리 문자열이다. 숫자로 저장된 셀도 앞자리 0을 복원해 준다. */
    private String orgNo(Row row) {
        String raw = string(row, COL_ORG_NO);
        return raw.isBlank() ? "" : pad3(raw);
    }

    private String subNo(Row row) {
        String raw = string(row, COL_SUB_NO);
        return raw.isBlank() ? "" : (raw.length() == 1 ? "0" + raw : raw);
    }

    private String pad3(String value) {
        String v = value.trim();
        return v.length() >= 3 ? v : "0".repeat(3 - v.length()) + v;
    }

    private String string(Row row, int columnIndex) {
        Cell cell = row.getCell(columnIndex);
        if (cell == null) {
            return "";
        }
        return switch (cell.getCellType()) {
            case STRING -> cell.getStringCellValue().trim();
            case NUMERIC -> String.valueOf((long) cell.getNumericCellValue());
            case BOOLEAN -> String.valueOf(cell.getBooleanCellValue());
            default -> "";
        };
    }

    private String nullIfBlank(String value) {
        return (value == null || value.isBlank()) ? null : value;
    }
}
