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.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
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.BizCooperativeDevelopment;

@DisplayName("CooperativeDevelopmentExcelExporter")
class CooperativeDevelopmentExcelExporterTest
{
    private final CooperativeDevelopmentExcelExporter exporter = new CooperativeDevelopmentExcelExporter();

    @Test
    @DisplayName("导出仅数据行、不含合计")
    void exportWithoutTotalRow() throws Exception
    {
        BizCooperativeDevelopment a = sample("雅安镇", "雅安镇荣嘎村", "合作社A", 10, 20);
        BizCooperativeDevelopment b = sample("雅安镇", "雅安镇公随村", "合作社B", 5, 15);
        byte[] bytes = exporter.export(2026, 7, Arrays.asList(a, b), "admin");
        assertNotNull(bytes);
        assertTrue(bytes.length > 1000);

        try (Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(bytes)))
        {
            Sheet sheet = CooperativeDevelopmentExcelParser.resolveSheet(wb);
            int header = CooperativeDevelopmentExcelParser.detectHeaderRow(sheet);
            int dataStart = header + CooperativeDevelopmentExcelParser.HEADER_SPAN;
            assertEquals(dataStart + 1, sheet.getLastRowNum());
            Row last = sheet.getRow(sheet.getLastRowNum());
            assertNotNull(last);
            assertEquals("合作社B", CooperativeDevelopmentExcelParser.cellString(last,
                    CooperativeDevelopmentExcelParser.COL_COOP_NAME));
            for (int r = dataStart; r <= sheet.getLastRowNum(); r++)
            {
                String seq = CooperativeDevelopmentExcelParser.cellString(sheet.getRow(r), 0);
                assertTrue(seq == null || !seq.contains("合计"), "不应出现合计行");
            }
        }
    }

    @Test
    @DisplayName("第3行及以后复用模板数据行边框样式")
    void exportThirdRowKeepsBorderStyle() throws Exception
    {
        BizCooperativeDevelopment a = sample("雅安镇", "雅安镇荣嘎村", "合作社A", 10, 20);
        BizCooperativeDevelopment b = sample("雅安镇", "雅安镇公随村", "合作社B", 5, 15);
        BizCooperativeDevelopment c = sample("雅安镇", "雅安镇荣嘎村", "合作社C", 8, 12);
        byte[] bytes = exporter.export(2026, 7, Arrays.asList(a, b, c), "admin");
        try (Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(bytes)))
        {
            Sheet sheet = CooperativeDevelopmentExcelParser.resolveSheet(wb);
            int header = CooperativeDevelopmentExcelParser.detectHeaderRow(sheet);
            int dataStart = header + CooperativeDevelopmentExcelParser.HEADER_SPAN;
            Row first = sheet.getRow(dataStart);
            Row third = sheet.getRow(dataStart + 2);
            assertNotNull(first);
            assertNotNull(third);
            assertEquals("合作社C", CooperativeDevelopmentExcelParser.cellString(third,
                    CooperativeDevelopmentExcelParser.COL_COOP_NAME));
            org.apache.poi.ss.usermodel.BorderStyle expected = first.getCell(0).getCellStyle().getBorderBottom();
            assertTrue(expected != org.apache.poi.ss.usermodel.BorderStyle.NONE);
            assertEquals(expected, third.getCell(0).getCellStyle().getBorderBottom());
            assertEquals(expected, third.getCell(CooperativeDevelopmentExcelParser.COL_LAST).getCellStyle()
                    .getBorderBottom());
        }
    }

    @Test
    @DisplayName("无数据时不写合计行")
    void exportEmptyNoTotal() throws Exception
    {
        byte[] bytes = exporter.export(2026, 7, Collections.emptyList(), "admin");
        try (Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(bytes)))
        {
            Sheet sheet = CooperativeDevelopmentExcelParser.resolveSheet(wb);
            int header = CooperativeDevelopmentExcelParser.detectHeaderRow(sheet);
            int dataStart = header + CooperativeDevelopmentExcelParser.HEADER_SPAN;
            assertTrue(sheet.getLastRowNum() < dataStart);
            for (int r = 0; r <= sheet.getLastRowNum(); r++)
            {
                Row row = sheet.getRow(r);
                if (row == null)
                {
                    continue;
                }
                String seq = CooperativeDevelopmentExcelParser.cellString(row, 0);
                assertTrue(seq == null || !seq.contains("合计"));
            }
        }
    }

    @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();
        byte[] bytes = exporter.export(exportYear, exportMonth,
                Collections.singletonList(sample("雅安镇", "雅安镇荣嘎村", "合作社A", 10, 20)), "测试用户");
        try (Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(bytes)))
        {
            Sheet sheet = CooperativeDevelopmentExcelParser.resolveSheet(wb);
            Row fillerRow = sheet.getRow(1);
            assertNotNull(fillerRow);
            String fillerText = CooperativeDevelopmentExcelParser.cellString(fillerRow, 0);
            assertNotNull(fillerText);
            assertTrue(fillerText.contains("测试用户"), fillerText);
            assertTrue(fillerText.contains(expectedFill), "填表时间应为当月: " + fillerText);
            assertTrue(!fillerText.contains("X月"), fillerText);
            String title = CooperativeDevelopmentExcelParser.cellString(sheet.getRow(0), 0);
            assertTrue(title.contains(exportYear + "年"), title);
            assertTrue(title.contains("（" + exportMonth + "月）"), title);
        }
    }

    private static BizCooperativeDevelopment sample(String town, String village, String coop, int hh, int pop)
    {
        BizCooperativeDevelopment row = new BizCooperativeDevelopment();
        row.setTownName(town);
        row.setVillageDeptId((long) village.hashCode());
        row.setVillageName(village);
        row.setCooperativeName(coop);
        row.setMemberHouseholdCount(hh);
        row.setMemberPopulationCount(pop);
        row.setRegisteredCapital(new BigDecimal("100"));
        row.setYearEndTotalAssets(new BigDecimal("200"));
        row.setTotalIncome(new BigDecimal("50"));
        return row;
    }
}
