package com.ruoyi.web.modules.industryservice.support;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.ByteArrayInputStream;
import java.util.Arrays;
import java.util.Collections;
import org.apache.poi.ss.usermodel.BorderStyle;
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.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import com.ruoyi.web.modules.industryservice.domain.BizVaccinationData;

@DisplayName("VaccinationDataExcelExporter")
class VaccinationDataExcelExporterTest
{
    private final VaccinationDataExcelExporter exporter = new VaccinationDataExcelExporter();

    @Test
    @DisplayName("导出填表时间默认为系统当月，且标题统计月与填表月可不同")
    void exportFillerDateDefaultsToCurrentMonth() throws Exception
    {
        java.time.LocalDate today = java.time.LocalDate.now();
        String expectedFill = today.getYear() + "年" + today.getMonthValue() + "月";
        int exportMonth = today.getMonthValue() == 1 ? 12 : today.getMonthValue() - 1;
        int exportYear = today.getMonthValue() == 1 ? today.getYear() - 1 : today.getYear();

        BizVaccinationData row = sample("雅安镇", "雅安镇荣嘎村", 100, 90);

        byte[] bytes = exporter.export(exportYear, exportMonth, Collections.singletonList(row), "测试用户");
        try (Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(bytes)))
        {
            Sheet sheet = VaccinationDataExcelParser.resolveSheet(wb);
            Row fillerRow = sheet.getRow(1);
            assertNotNull(fillerRow);
            String fillerText = VaccinationDataExcelParser.cellString(fillerRow, 0);
            assertNotNull(fillerText);
            assertTrue(fillerText.contains("测试用户"), fillerText);
            assertTrue(fillerText.contains(expectedFill), "填表时间应为当月: " + fillerText);
            assertTrue(!fillerText.contains("X月"), fillerText);
            String title = VaccinationDataExcelParser.cellString(sheet.getRow(0), 0);
            assertTrue(title.contains(exportYear + "年"), title);
            assertTrue(title.contains("（" + exportMonth + "月）"), title);
        }
    }

    @Test
    @DisplayName("导出第5、6行（数据行）保留模板边框")
    void exportDataRowsKeepBorders() throws Exception
    {
        BizVaccinationData a = sample("雅安镇", "雅安镇荣嘎村", 12000, 11800);
        BizVaccinationData b = sample("雅安镇", "雅安镇公随村", 13000, 12695);
        byte[] bytes = exporter.export(2026, 7, Arrays.asList(a, b), "admin");
        try (Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(bytes)))
        {
            Sheet sheet = VaccinationDataExcelParser.resolveSheet(wb);
            int header = VaccinationDataExcelParser.detectHeaderRow(sheet);
            int dataStart = header + VaccinationDataExcelParser.HEADER_SPAN;
            // Excel 第 5、6 行（1-based）即 dataStart / dataStart+1
            assertEquals(4, dataStart);
            Row row5 = sheet.getRow(dataStart);
            Row row6 = sheet.getRow(dataStart + 1);
            assertNotNull(row5);
            assertNotNull(row6);
            assertHasBorder(row5, "第5行");
            assertHasBorder(row6, "第6行");
        }
    }

    private static void assertHasBorder(Row row, String label)
    {
        for (int col = 0; col <= VaccinationDataExcelParser.COL_RATE; col++)
        {
            assertNotNull(row.getCell(col), label + " 列" + col + " 单元格为空");
            BorderStyle bottom = row.getCell(col).getCellStyle().getBorderBottom();
            assertTrue(bottom != BorderStyle.NONE, label + " 列" + col + " 缺少下边框");
        }
    }

    private static BizVaccinationData sample(String town, String village, int should, int actual)
    {
        BizVaccinationData row = new BizVaccinationData();
        row.setTownName(town);
        row.setVillageDeptId((long) village.hashCode());
        row.setVillageName(village);
        row.setShouldVaccinateCount(should);
        row.setActualVaccinateCount(actual);
        return row;
    }
}
