package com.ga.api.service.statement;

import com.ga.common.exception.BizException;
import com.ga.common.exception.ErrorCode;
import com.ga.core.vo.org.AgentResp;
import com.ga.core.vo.settle.PaymentVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.stereotype.Component;

import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.List;

@Slf4j
@Component
public class ExcelStatementGenerator {

    private static final DecimalFormat AMOUNT_FMT = new DecimalFormat("#,##0");

    public byte[] generate(AgentResp agent, StatementSummary summary, List<PaymentVO> payments) {
        try (SXSSFWorkbook wb = new SXSSFWorkbook(100)) {
            wb.setCompressTempFiles(true);
            Sheet sheet = wb.createSheet("수수료명세서");

            int rowNum = 0;

            // 상단 헤더 정보
            rowNum = writeHeaderSection(sheet, wb, agent, summary, rowNum);

            // 공백 행
            sheet.createRow(rowNum++);

            // 지급 테이블 헤더
            Row tableHeader = sheet.createRow(rowNum++);
            CellStyle boldStyle = boldStyle(wb);
            String[] cols = {"지급ID", "지급금액", "원천세", "지방소득세", "부가세", "공제금액", "실수령액"};
            for (int i = 0; i < cols.length; i++) {
                Cell c = tableHeader.createCell(i);
                c.setCellValue(cols[i]);
                c.setCellStyle(boldStyle);
                sheet.setColumnWidth(i, 18 * 256);
            }

            // 지급 데이터 행
            for (PaymentVO p : payments) {
                Row row = sheet.createRow(rowNum++);
                row.createCell(0).setCellValue(p.getPaymentId() != null ? p.getPaymentId() : 0L);
                row.createCell(1).setCellValue(fmt(p.getPayAmount()));
                row.createCell(2).setCellValue(fmt(p.getIncomeTaxAmount()));
                row.createCell(3).setCellValue(fmt(p.getLocalTaxAmount()));
                row.createCell(4).setCellValue(fmt(p.getVatAmount()));
                row.createCell(5).setCellValue(fmt(p.getDeductionAmount()));
                row.createCell(6).setCellValue(fmt(p.getNetAmount()));
            }

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            wb.write(out);
            wb.dispose();
            return out.toByteArray();
        } catch (Exception e) {
            log.error("ExcelStatementGenerator error", e);
            throw new BizException(ErrorCode.INTERNAL_ERROR, "명세서 엑셀 생성 실패");
        }
    }

    private int writeHeaderSection(Sheet sheet, SXSSFWorkbook wb, AgentResp agent,
                                   StatementSummary summary, int rowNum) {
        CellStyle bold = boldStyle(wb);
        writeKv(sheet, rowNum++, bold, "설계사명", agent.getAgentName());
        writeKv(sheet, rowNum++, bold, "사업자번호", agent.getBusinessNo());
        writeKv(sheet, rowNum++, bold, "소득세유형", agent.getTaxType());
        writeKv(sheet, rowNum++, bold, "부가세유형", agent.getVatType());
        sheet.createRow(rowNum++);
        writeKv(sheet, rowNum++, bold, "총 지급액",    fmt(summary.grossAmount()));
        writeKv(sheet, rowNum++, bold, "원천세",       fmt(summary.incomeTaxAmount()));
        writeKv(sheet, rowNum++, bold, "지방소득세",   fmt(summary.localTaxAmount()));
        writeKv(sheet, rowNum++, bold, "부가세",       fmt(summary.vatAmount()));
        writeKv(sheet, rowNum++, bold, "공제금액",     fmt(summary.deductionAmount()));
        writeKv(sheet, rowNum++, bold, "실수령액",     fmt(summary.netAmount()));
        return rowNum;
    }

    private void writeKv(Sheet sheet, int rowNum, CellStyle keyStyle, String key, String value) {
        Row row = sheet.createRow(rowNum);
        Cell k = row.createCell(0);
        k.setCellValue(key);
        k.setCellStyle(keyStyle);
        row.createCell(1).setCellValue(value != null ? value : "");
    }

    private CellStyle boldStyle(SXSSFWorkbook wb) {
        CellStyle style = wb.createCellStyle();
        Font font = wb.createFont();
        font.setBold(true);
        style.setFont(font);
        return style;
    }

    private String fmt(BigDecimal val) {
        if (val == null) return "0";
        return AMOUNT_FMT.format(val);
    }
}
