package com.ruoyi.web.modules.industryservice.service.impl;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.industryservice.domain.BizYakHerdInventory;
import com.ruoyi.web.modules.industryservice.domain.vo.YakHerdInventoryImportResultVo;
import com.ruoyi.web.modules.industryservice.mapper.BizYakHerdInventoryMapper;
import com.ruoyi.web.modules.industryservice.service.IBizYakHerdInventoryService;
import com.ruoyi.web.modules.industryservice.support.TownDeptSupport;
import com.ruoyi.web.modules.industryservice.support.YakHerdInventoryExcelExporter;
import com.ruoyi.web.modules.industryservice.support.YakHerdInventoryExcelParser;
import com.ruoyi.web.modules.industryservice.support.YakHerdInventoryExcelParser.ParsedRow;
import com.ruoyi.web.modules.industryservice.support.YakHerdInventoryMonthSupport;
import com.ruoyi.web.modules.industryservice.support.YakHerdInventoryValidation;
import com.ruoyi.web.modules.industryservice.support.YakHerdInventoryYearSupport;

/**
 * 牦牛存栏数据填报服务实现
 */
@Service
public class BizYakHerdInventoryServiceImpl implements IBizYakHerdInventoryService
{
    @Autowired
    private BizYakHerdInventoryMapper bizYakHerdInventoryMapper;

    @Autowired
    private TownDeptSupport townDeptSupport;

    @Autowired
    private YakHerdInventoryExcelExporter yakHerdInventoryExcelExporter;

    @Override
    public BizYakHerdInventory selectBizYakHerdInventoryById(Long id)
    {
        return bizYakHerdInventoryMapper.selectBizYakHerdInventoryById(id);
    }

    @Override
    public List<BizYakHerdInventory> selectBizYakHerdInventoryList(BizYakHerdInventory query)
    {
        return bizYakHerdInventoryMapper.selectBizYakHerdInventoryList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertBizYakHerdInventory(BizYakHerdInventory row)
    {
        YakHerdInventoryValidation.validateRowForSave(row, townDeptSupport);
        assertUniqueYearMonthVillage(row.getStatYear(), row.getStatMonth(), row.getVillageDeptId(), null);
        return bizYakHerdInventoryMapper.insertBizYakHerdInventory(row);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateBizYakHerdInventory(BizYakHerdInventory row)
    {
        if (row.getId() == null)
        {
            throw new ServiceException("主键不能为空");
        }
        YakHerdInventoryValidation.validateRowForSave(row, townDeptSupport);
        requireExistingRow(row.getId());
        assertUniqueYearMonthVillage(row.getStatYear(), row.getStatMonth(), row.getVillageDeptId(), row.getId());
        return bizYakHerdInventoryMapper.updateBizYakHerdInventory(row);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteBizYakHerdInventoryByIds(Long[] ids, String updateBy)
    {
        if (ids == null || ids.length == 0)
        {
            return 0;
        }
        List<Long> cleaned = new ArrayList<>();
        for (Long id : ids)
        {
            if (id != null)
            {
                cleaned.add(id);
            }
        }
        if (cleaned.isEmpty())
        {
            return 0;
        }
        return bizYakHerdInventoryMapper.deleteBizYakHerdInventoryByIds(cleaned.toArray(new Long[0]));
    }

    /**
     * 导入：同一填报年月下全量覆盖——先删除该年月全部记录，再插入本次解析成功的乡镇行。
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public YakHerdInventoryImportResultVo importData(MultipartFile file, Integer statYear, Integer statMonth,
            String username)
    {
        if (file == null || file.isEmpty())
        {
            throw new ServiceException("请上传 Excel 文件");
        }
        String filename = file.getOriginalFilename();
        if (filename == null || !filename.toLowerCase().endsWith(".xlsx"))
        {
            throw new ServiceException("仅支持 .xlsx 格式");
        }
        YakHerdInventoryMonthSupport.validateStatPeriod(statYear, statMonth);
        YakHerdInventoryImportResultVo result = new YakHerdInventoryImportResultVo();
        List<ParsedRow> parsedRows;
        try
        {
            parsedRows = YakHerdInventoryExcelParser.parse(file.getInputStream());
        }
        catch (ServiceException ex)
        {
            throw ex;
        }
        catch (Exception ex)
        {
            throw new ServiceException("读取 Excel 失败：" + ex.getMessage());
        }

        List<BizYakHerdInventory> toInsert = new ArrayList<>();
        for (ParsedRow parsed : parsedRows)
        {
            try
            {
                SysDept town = townDeptSupport.resolveTownByName(parsed.getTownName());
                if (town == null)
                {
                    result.addFail("第" + parsed.getExcelRowNum() + "行[" + parsed.getTownName() + "]: 乡镇未识别");
                    continue;
                }
                if (StringUtils.isEmpty(parsed.getVillageName()))
                {
                    result.addFail("第" + parsed.getExcelRowNum() + "行[" + parsed.getTownName() + "]: 所属村不能为空");
                    continue;
                }
                SysDept village = townDeptSupport.resolveVillageByTownAndName(town.getDeptId(), parsed.getVillageName());
                if (village == null)
                {
                    result.addFail("第" + parsed.getExcelRowNum() + "行[" + parsed.getTownName() + "/"
                            + parsed.getVillageName() + "]: 村未识别");
                    continue;
                }
                BizYakHerdInventory row = YakHerdInventoryExcelParser.toInventory(parsed, statYear, statMonth,
                        town.getDeptId(), town.getDeptName(), village.getDeptId(), village.getDeptName());
                YakHerdInventoryValidation.validateRowForSave(row, townDeptSupport);
                for (String warn : YakHerdInventoryValidation.buildExcelTotalWarns(parsed, row))
                {
                    result.addWarn("第" + parsed.getExcelRowNum() + "行[" + parsed.getTownName() + "/"
                            + parsed.getVillageName() + "]: " + warn);
                }
                row.setCreateBy(username);
                toInsert.add(row);
            }
            catch (ServiceException ex)
            {
                result.addFail("第" + parsed.getExcelRowNum() + "行[" + parsed.getTownName() + "]: " + ex.getMessage());
            }
        }

        if (result.getFailCount() > 0)
        {
            throw new ServiceException("导入失败，未写入数据：" + String.join("；", result.getFailMessages()));
        }
        if (toInsert.isEmpty())
        {
            throw new ServiceException("未解析到有效数据行");
        }

        bizYakHerdInventoryMapper.deleteByYearMonth(statYear, statMonth);
        for (BizYakHerdInventory row : toInsert)
        {
            bizYakHerdInventoryMapper.insertBizYakHerdInventory(row);
            result.setInsertCount(result.getInsertCount() + 1);
        }
        return result;
    }

    @Override
    public List<Integer> listYearOptions()
    {
        return YakHerdInventoryYearSupport.resolveYearOptions();
    }

    @Override
    public List<Integer> listMonthOptions()
    {
        return YakHerdInventoryMonthSupport.resolveMonthOptions();
    }

    @Override
    public List<java.util.Map<String, Object>> listTownOptions()
    {
        return townDeptSupport.toOptionList();
    }

    @Override
    public List<com.ruoyi.common.core.domain.TreeSelect> listVillageTree()
    {
        return townDeptSupport.buildVillageTree();
    }

    @Override
    public byte[] exportByYearMonth(Integer statYear, Integer statMonth)
    {
        return exportByYearMonth(statYear, statMonth, null);
    }

    @Override
    public byte[] exportByYearMonth(Integer statYear, Integer statMonth, String fillerName)
    {
        YakHerdInventoryMonthSupport.validateStatPeriod(statYear, statMonth);
        BizYakHerdInventory query = new BizYakHerdInventory();
        query.setStatYear(statYear);
        query.setStatMonth(statMonth);
        List<BizYakHerdInventory> list = bizYakHerdInventoryMapper.selectBizYakHerdInventoryList(query);
        return yakHerdInventoryExcelExporter.export(statYear, statMonth, list, fillerName);
    }

    private void assertUniqueYearMonthVillage(Integer statYear, Integer statMonth, Long villageDeptId, Long excludeId)
    {
        if (bizYakHerdInventoryMapper.countByYearMonthAndVillageExcludeId(statYear, statMonth, villageDeptId,
                excludeId) > 0)
        {
            throw new ServiceException("该年该月该村已填报");
        }
    }

    private BizYakHerdInventory requireExistingRow(Long id)
    {
        BizYakHerdInventory row = bizYakHerdInventoryMapper.selectBizYakHerdInventoryById(id);
        if (row == null)
        {
            throw new ServiceException("记录不存在");
        }
        return row;
    }
}
