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

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

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

@DisplayName("LivestockOwnershipHouseholdExcelExporter")
class LivestockOwnershipHouseholdExcelExporterTest
{
    private final LivestockOwnershipHouseholdExcelExporter exporter = new LivestockOwnershipHouseholdExcelExporter();

    @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();

        BizLivestockOwnershipHousehold row = new BizLivestockOwnershipHousehold();
        row.setTownName("雅安镇");
        row.setVillageDeptId(201L);
        row.setVillageName("雅安镇荣嘎村");
        row.setWithLivestockHouseholdCount(36);
        row.setWithoutLivestockHouseholdCount(12);

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

    @Test
    @DisplayName("导出合计行应保留边框")
    void exportTotalRowKeepsBorders() throws Exception
    {
        BizLivestockOwnershipHousehold row = new BizLivestockOwnershipHousehold();
        row.setTownName("雅安镇");
        row.setVillageDeptId(201L);
        row.setVillageName("雅安镇荣嘎村");
        row.setWithLivestockHouseholdCount(36);
        row.setWithoutLivestockHouseholdCount(12);

        byte[] bytes = exporter.export(2026, 6, Collections.singletonList(row), "测试用户");
        try (Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(bytes)))
        {
            Sheet sheet = LivestockOwnershipHouseholdExcelParser.resolveSheet(wb);
            int headerRowIndex = LivestockOwnershipHouseholdExcelParser.detectHeaderRow(sheet);
            int totalRowIndex = headerRowIndex + 3;
            Row totalRow = sheet.getRow(totalRowIndex);
            assertNotNull(totalRow);
            assertTrue("合计".equals(LivestockOwnershipHouseholdExcelParser.cellString(totalRow, 0)));
            for (int col = 0; col <= LivestockOwnershipHouseholdExcelParser.COL_LAST; col++)
            {
                Cell cell = totalRow.getCell(col);
                assertNotNull(cell, "合计行列 " + col + " 应存在");
                assertNotEquals(BorderStyle.NONE, cell.getCellStyle().getBorderBottom(),
                        "合计行列 " + col + " 应有下边框");
            }
        }
    }

    @Test
    @DisplayName("数据行不应继承模板合计行的合并单元格")
    void exportDataRowsHaveNoMergedTownVillage() throws Exception
    {
        List<BizLivestockOwnershipHousehold> list = new ArrayList<>();
        for (int i = 0; i < 4; i++)
        {
            BizLivestockOwnershipHousehold row = new BizLivestockOwnershipHousehold();
            row.setTownName("雅安镇");
            row.setVillageDeptId(200L + i);
            row.setVillageName("测试村" + i);
            row.setWithLivestockHouseholdCount(10 + i);
            row.setWithoutLivestockHouseholdCount(1);
            list.add(row);
        }
        byte[] bytes = exporter.export(2026, 5, list, "admin");
        try (Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(bytes)))
        {
            Sheet sheet = LivestockOwnershipHouseholdExcelParser.resolveSheet(wb);
            int header = LivestockOwnershipHouseholdExcelParser.detectHeaderRow(sheet);
            int dataStart = header + 2;
            int totalIdx = dataStart + list.size();
            for (int r = dataStart; r < totalIdx; r++)
            {
                Row row = sheet.getRow(r);
                assertNotNull(row);
                assertEquals("雅安镇",
                        LivestockOwnershipHouseholdExcelParser.cellString(row, LivestockOwnershipHouseholdExcelParser.COL_TOWN));
                assertTrue(LivestockOwnershipHouseholdExcelParser
                        .cellString(row, LivestockOwnershipHouseholdExcelParser.COL_VILLAGE).startsWith("测试村"));
                for (int i = 0; i < sheet.getNumMergedRegions(); i++)
                {
                    CellRangeAddress region = sheet.getMergedRegion(i);
                    assertFalse(region.getFirstRow() <= r && region.getLastRow() >= r
                                    && region.getFirstColumn() <= LivestockOwnershipHouseholdExcelParser.COL_TOWN
                                    && region.getLastColumn() >= LivestockOwnershipHouseholdExcelParser.COL_TOWN,
                            "数据行 " + r + " 不应合并乡镇/村列");
                }
            }
            boolean totalMerged = false;
            for (int i = 0; i < sheet.getNumMergedRegions(); i++)
            {
                CellRangeAddress region = sheet.getMergedRegion(i);
                if (region.getFirstRow() == totalIdx && region.getLastRow() == totalIdx
                        && region.getFirstColumn() == 0
                        && region.getLastColumn() == LivestockOwnershipHouseholdExcelParser.COL_VILLAGE)
                {
                    totalMerged = true;
                }
            }
            assertTrue(totalMerged, "仅合计行应合并序号~村三列");
        }
    }
}
