package com.nanri.aiimage.modules.productrisk.service;

import com.nanri.aiimage.common.exception.BusinessException;
import com.nanri.aiimage.modules.productrisk.model.dto.ProductRiskRowDto;
import com.nanri.aiimage.modules.productrisk.model.enums.ProductRiskCountryCode;
import lombok.extern.slf4j.Slf4j;
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.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ProductRiskExcelAssemblyService {

    private static final List<String> SHEET_ORDER = java.util.Arrays.stream(ProductRiskCountryCode.values())
            .map(ProductRiskCountryCode::getSheetName)
            .toList();

    private static final String[] HEADER = {
            "店铺名",
            "商品ASIN/SKU",
            "状态",
            "完成",
            "移除ASIN",
            "移除状态"
    };

    public void writeWorkbook(File outputXlsx, String shopDisplayName, Map<String, List<ProductRiskRowDto>> countries) {
        Map<String, List<ProductRiskRowDto>> safe = countries == null ? Map.of() : countries;
        try (XSSFWorkbook wb = new XSSFWorkbook(); FileOutputStream fos = new FileOutputStream(outputXlsx)) {
            for (String sheetName : SHEET_ORDER) {
                Sheet sheet = wb.createSheet(sheetName);
                Row headerRow = sheet.createRow(0);
                for (int c = 0; c < HEADER.length; c++) {
                    headerRow.createCell(c).setCellValue(HEADER[c]);
                }
                List<ProductRiskRowDto> rows = safe.getOrDefault(sheetName, List.of());
                int rowIdx = 1;
                for (ProductRiskRowDto dto : rows) {
                    Row row = sheet.createRow(rowIdx++);
                    createTextCell(row, 0, firstNonBlank(dto == null ? null : dto.getShopName(), shopDisplayName));
                    createTextCell(row, 1, dto == null ? null : dto.getProductAsinSku());
                    createTextCell(row, 2, dto == null ? null : dto.getStatus());
                    createTextCell(row, 3, dto == null ? null : dto.getDone());
                    createTextCell(row, 4, dto == null ? null : dto.getRemoveAsin());
                    createTextCell(row, 5, dto == null ? null : dto.getRemoveStatus());
                }
                for (int i = 0; i < HEADER.length; i++) {
                    sheet.autoSizeColumn(i);
                }
            }
            wb.write(fos);
        } catch (BusinessException ex) {
            throw ex;
        } catch (Exception ex) {
            log.warn("[product-risk] write workbook failed: {}", ex.getMessage());
            throw new BusinessException("生成 Excel 失败: " + ex.getMessage());
        }
    }

    public int countRows(Map<String, List<ProductRiskRowDto>> countries) {
        if (countries == null || countries.isEmpty()) {
            return 0;
        }
        int n = 0;
        for (List<ProductRiskRowDto> list : countries.values()) {
            if (list != null) {
                n += list.size();
            }
        }
        return n;
    }

    /**
     * 将接口中的 {@link ProductRiskCountryCode} 键转为 Excel 中文工作表名 → 行列表。
     */
    public Map<String, List<ProductRiskRowDto>> normalizeCountriesMap(Map<ProductRiskCountryCode, List<ProductRiskRowDto>> raw) {
        if (raw == null || raw.isEmpty()) {
            return new LinkedHashMap<>();
        }
        Map<String, List<ProductRiskRowDto>> out = new LinkedHashMap<>();
        for (ProductRiskCountryCode code : ProductRiskCountryCode.values()) {
            List<ProductRiskRowDto> rows = raw.get(code);
            if (rows != null) {
                out.put(code.getSheetName(), rows);
            }
        }
        return out;
    }

    private static void createTextCell(Row row, int index, String value) {
        Cell cell = row.createCell(index);
        cell.setCellValue(value == null ? "" : value);
    }

    private static String firstNonBlank(String primary, String fallback) {
        if (primary != null && !primary.isBlank()) {
            return primary;
        }
        return fallback == null ? "" : fallback;
    }
}
