package com.zhyc.module.produce.breed.service.impl;

import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

import com.zhyc.module.produce.breed.domain.ScBreedPlan;
import com.zhyc.module.produce.breed.domain.ScBreedPlanGenerate;
import com.zhyc.module.produce.breed.mapper.ScBreedPlanGenerateMapper;
import com.zhyc.module.produce.breed.mapper.ScBreedPlanMapper;
import com.zhyc.module.produce.breed.service.IScBreedPlanGenerateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.zhyc.common.utils.SecurityUtils;
import org.springframework.util.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * 配种计划生成Service业务层处理
 *
 * @author ruoyi
 * @date 2025-07-16
 */
@Service
public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateService
{
    @Autowired
    private ScBreedPlanGenerateMapper scBreedPlanGenerateMapper;

    @Autowired
    private ScBreedPlanMapper scBreedPlanMapper;

    /**
     * 查询配种计划生成
     *
     * @param id 配种计划生成主键
     * @return 配种计划生成
     */
    @Override
    public ScBreedPlanGenerate selectScBreedPlanGenerateById(Long id)
    {
        return scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
    }

    /**
     * 查询配种计划生成列表
     *
     * @param scBreedPlanGenerate 配种计划生成
     * @return 配种计划生成
     */
    @Override
    public List<ScBreedPlanGenerate> selectScBreedPlanGenerateList(ScBreedPlanGenerate scBreedPlanGenerate)
    {
        return scBreedPlanGenerateMapper.selectScBreedPlanGenerateList(scBreedPlanGenerate);
    }

    /**
     * 筛选符合条件的母羊
     *
     * @return 符合条件的母羊列表
     */
    @Override
    public List<Map<String, Object>> selectEligibleEwe(@RequestParam(value = "manageTags", required = false) String manageTags)
    {
        return scBreedPlanGenerateMapper.selectEligibleEwe();
    }

    /**
     * 筛选符合条件的公羊
     *
     * @return 符合条件的公羊列表
     */
    @Override
    public List<Map<String, Object>> selectEligibleRam(@RequestParam(value = "manageTags", required = false) String manageTags)
    {
        return scBreedPlanGenerateMapper.selectEligibleRam();
    }

    /**
     * 自动生成配种计划
     *
     * @param planType 计划类型
     * @param planName 计划名称
     * @param eweIds 母羊ID列表
     * @param ramIds 公羊ID列表
     * @return 生成的配种计划
     */
    @Override
    @Transactional
    public ScBreedPlanGenerate autoGenerateBreedPlan(Integer planType, String planName, List<Long> eweIds, List<Long> ramIds)
    {
        // 创建配种计划生成记录
        ScBreedPlanGenerate planGenerate = new ScBreedPlanGenerate();

        // 自动生成计划名称：日期+计划类型
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = sdf.format(new Date());
        String planTypeName = "";

        switch (planType) {
            case 1: planTypeName = "供体母羊配种计划"; break;
            case 2: planTypeName = "同期发情人工授精计划"; break;
            case 3: planTypeName = "本交配种计划"; break;
            case 4: planTypeName = "自然发情人工授精计划"; break;
            default: planTypeName = "未知配种计划"; break;
        }

        planName = dateStr + planTypeName;

        planGenerate.setPlanName(planName);
        planGenerate.setPlanType(planType);
        planGenerate.setPlanDate(new Date());
        planGenerate.setTotalEweCount(eweIds.size());
        planGenerate.setTotalRamCount(ramIds.size());

        // 计算配种比例
        double ratio = (double) eweIds.size() / ramIds.size();
        planGenerate.setBreedRatio(String.format("%.1f:1", ratio));
        planGenerate.setStatus(0); // 待审批
        planGenerate.setCreateBy(SecurityUtils.getUsername());
        planGenerate.setCreateTime(new Date());

        // 保存配种计划生成记录
        scBreedPlanGenerateMapper.insertScBreedPlanGenerate(planGenerate);

        // 生成具体的配种计划
        generateBreedPlanDetails(planGenerate.getId(), eweIds, ramIds, planType);

        return planGenerate;
    }

    /**
     * 生成具体的配种计划详情
     */
    private void generateBreedPlanDetails(Long planGenerateId, List<Long> eweIds, List<Long> ramIds, Integer planType)
    {
        int ramIndex = 0;
        int ewesPerRam = (int) Math.ceil((double) eweIds.size() / ramIds.size());

        for (int i = 0; i < eweIds.size(); i++) {
            ScBreedPlan breedPlan = new ScBreedPlan();
            breedPlan.setRamId(ramIds.get(ramIndex).toString());
            breedPlan.setEweId(eweIds.get(i).toString());

            // 2. 修改：直接使用 planType 作为 breedType (假设一一对应)
            // 1=供体母羊配种, 2=同期发情人工授精, 3=本交, 4=自然发情人工授精
            breedPlan.setBreedType(Long.valueOf(planType));

            scBreedPlanGenerateMapper.insertTempBreedPlan(planGenerateId, breedPlan);

            if ((i + 1) % ewesPerRam == 0 && ramIndex < ramIds.size() - 1) {
                ramIndex++;
            }
        }
    }

    /**
     * 新增配种计划生成
     *
     * @param scBreedPlanGenerate 配种计划生成
     * @return 结果
     */
    @Override
    public int insertScBreedPlanGenerate(ScBreedPlanGenerate scBreedPlanGenerate)
    {
        scBreedPlanGenerate.setCreateTime(new Date());
        return scBreedPlanGenerateMapper.insertScBreedPlanGenerate(scBreedPlanGenerate);
    }

    /**
     * 修改配种计划生成
     *
     * @param scBreedPlanGenerate 配种计划生成
     * @return 结果
     */
    @Override
    public int updateScBreedPlanGenerate(ScBreedPlanGenerate scBreedPlanGenerate)
    {
        scBreedPlanGenerate.setUpdateTime(new Date());
        return scBreedPlanGenerateMapper.updateScBreedPlanGenerate(scBreedPlanGenerate);
    }

    /**
     * 获取审批配种计划详情
     *
     * @param id 配种计划ID
     * @return 审批配种计划详情
     */
    @Override
    public Map<String, Object> getApproveBreedPlanDetails(Long id)
    {
        Map<String, Object> result = new HashMap<>();

        // 获取配种计划基本信息
        ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
        result.put("planInfo", planGenerate);

        // 获取详细的配种计划信息
        List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectApproveBreedPlanDetails(id);
        result.put("planDetails", planDetails);

        // 获取可选择的公羊列表
        List<Map<String, Object>> availableRams = scBreedPlanGenerateMapper.selectEligibleRam();
        result.put("availableRams", availableRams);

        return result;
    }

    /**
     * 确认审批配种计划
     *
     * @param planId 配种计划ID
     * @param planDetails 配种计划详情
     * @param status 审批状态
     * @param approveRemark 审批意见
     * @return 结果
     */
    @Override
    @Transactional
    public int confirmApproveBreedPlan(Long planId, List<Map<String, Object>> planDetails, Integer status, String approveRemark)
    {
        // 更新审批状态
        ScBreedPlanGenerate planGenerate = new ScBreedPlanGenerate();
        planGenerate.setId(planId);
        planGenerate.setStatus(status);
        planGenerate.setApprover(SecurityUtils.getUsername());
        planGenerate.setApproveTime(new Date());
        planGenerate.setApproveRemark(approveRemark);
        planGenerate.setUpdateTime(new Date());

        int result = scBreedPlanGenerateMapper.updateScBreedPlanGenerate(planGenerate);

        // 如果审批通过，更新临时配种计划并转为正式计划
        if (result > 0 && status == 1) {
            // 更新临时配种计划中的公羊分配
            if (planDetails != null && !planDetails.isEmpty()) {
                for (Map<String, Object> detail : planDetails) {
                    Long tempId = Long.valueOf(detail.get("id").toString());
                    Long ramId = Long.valueOf(detail.get("ram_id").toString());
                    Long breedType = Long.valueOf(detail.get("breed_type").toString());

                    // 更新临时配种计划
                    Map<String, Object> updateParams = new HashMap<>();
                    updateParams.put("id", tempId);
                    updateParams.put("ramId", ramId);
                    updateParams.put("breedType", breedType);
                    scBreedPlanGenerateMapper.updateTempBreedPlan(updateParams);
                }
            }

            // 将临时配种计划转为正式配种计划
            scBreedPlanGenerateMapper.transferTempToFormal(planId);
        }

        return result;
    }

    /**
     * 获取配种计划详情
     *
     * @param id 配种计划ID
     * @return 配种计划详情
     */
    @Override
    public Map<String, Object> getBreedPlanDetails(Long id)
    {
        Map<String, Object> result = new HashMap<>();

        // 获取配种计划基本信息
        ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
        result.put("planInfo", planGenerate);

        // 获取配种计划详情列表
        List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectBreedPlanDetails(id);
        result.put("planDetails", planDetails);

        return result;
    }

    /**
     * 导出配种计划详情
     *
     * @param response HTTP响应
     * @param id 配种计划ID
     */
    @Override
    public void exportBreedPlanDetails(HttpServletResponse response, Long id)
    {
        try {
            // 获取配种计划基本信息
            ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
            if (planGenerate == null) {
                throw new RuntimeException("配种计划不存在");
            }

            // 检查是否已审批
            if (planGenerate.getStatus() != 1) {
                throw new RuntimeException("只有已审批的配种计划才能导出");
            }

            // 获取配种计划详情
            List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectBreedPlanDetails(id);

            // 创建工作簿
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("配种计划详情");

            // 创建样式
            CellStyle titleStyle = workbook.createCellStyle();
            Font titleFont = workbook.createFont();
            titleFont.setBold(true);
            titleFont.setFontHeightInPoints((short) 16);
            titleStyle.setFont(titleFont);
            titleStyle.setAlignment(HorizontalAlignment.CENTER);

            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);
            headerStyle.setAlignment(HorizontalAlignment.CENTER);
            headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

            CellStyle dataStyle = workbook.createCellStyle();
            dataStyle.setAlignment(HorizontalAlignment.CENTER);

            CellStyle eweHeaderStyle = workbook.createCellStyle();
            Font eweHeaderFont = workbook.createFont();
            eweHeaderFont.setBold(true);
            eweHeaderStyle.setFont(eweHeaderFont);
            eweHeaderStyle.setAlignment(HorizontalAlignment.CENTER);
            eweHeaderStyle.setFillForegroundColor(IndexedColors.ROSE.getIndex());
            eweHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

            CellStyle ramHeaderStyle = workbook.createCellStyle();
            Font ramHeaderFont = workbook.createFont();
            ramHeaderFont.setBold(true);
            ramHeaderStyle.setFont(ramHeaderFont);
            ramHeaderStyle.setAlignment(HorizontalAlignment.CENTER);
            ramHeaderStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
            ramHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

            int rowNum = 0;

            // 标题
            Row titleRow = sheet.createRow(rowNum++);
            Cell titleCell = titleRow.createCell(0);
            titleCell.setCellValue(planGenerate.getPlanName() + " - 配种计划详情");
            titleCell.setCellStyle(titleStyle);
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 19));

            // 空行
            rowNum++;

            String typeName = "";
            switch (planGenerate.getPlanType()) {
                case 1: typeName = "供体母羊配种计划"; break;
                case 2: typeName = "同期发情人工授精计划"; break;
                case 3: typeName = "本交配种计划"; break;
                case 4: typeName = "自然发情人工授精计划"; break;
                default: typeName = "未知"; break;
            }

            // 基本信息
            Row infoRow1 = sheet.createRow(rowNum++);
            infoRow1.createCell(0).setCellValue("计划类型：");
            String planTypeNameStr;
            Integer type = planGenerate.getPlanType();
            if (type != null) {
                switch (type) {
                    case 1: planTypeNameStr = "供体母羊配种计划"; break;
                    case 2: planTypeNameStr = "同期发情人工授精计划"; break;
                    case 3: planTypeNameStr = "本交配种计划"; break;
                    case 4: planTypeNameStr = "自然发情人工授精计划"; break;
                    default: planTypeNameStr = "未知类型";
                }
            } else {
                planTypeNameStr = "";
            }
            infoRow1.createCell(1).setCellValue(planTypeNameStr);
            infoRow1.createCell(3).setCellValue("计划日期：");
            infoRow1.createCell(4).setCellValue(new SimpleDateFormat("yyyy-MM-dd").format(planGenerate.getPlanDate()));

            Row infoRow2 = sheet.createRow(rowNum++);
            infoRow2.createCell(0).setCellValue("母羊数量：");
            infoRow2.createCell(1).setCellValue(planGenerate.getTotalEweCount());
            infoRow2.createCell(3).setCellValue("公羊数量：");
            infoRow2.createCell(4).setCellValue(planGenerate.getTotalRamCount());

            Row infoRow3 = sheet.createRow(rowNum++);
            infoRow3.createCell(0).setCellValue("配种比例：");
            infoRow3.createCell(1).setCellValue(planGenerate.getBreedRatio());
            infoRow3.createCell(3).setCellValue("创建人：");
            infoRow3.createCell(4).setCellValue(planGenerate.getCreateBy());

            // 空行
            rowNum++;

            // 分组表头
            Row groupHeaderRow = sheet.createRow(rowNum++);
            Cell groupHeaderCell1 = groupHeaderRow.createCell(1);
            groupHeaderCell1.setCellValue("母羊信息");
            groupHeaderCell1.setCellStyle(eweHeaderStyle);
            sheet.addMergedRegion(new CellRangeAddress(rowNum-1, rowNum-1, 1, 12));

            Cell groupHeaderCell2 = groupHeaderRow.createCell(13);
            groupHeaderCell2.setCellValue("公羊信息");
            groupHeaderCell2.setCellStyle(ramHeaderStyle);
            sheet.addMergedRegion(new CellRangeAddress(rowNum-1, rowNum-1, 13, 19));

            // 详细表头
            Row headerRow = sheet.createRow(rowNum++);
            String[] headers = {
                    "序号",
                    // 母羊信息
                    "母羊耳号", "母羊品种", "母羊家系", "母羊类别", "繁育状态", "胎次", "月龄", "体重", "核心羊群", "是否种用", "羊舍", "备注",
                    // 公羊信息
                    "公羊耳号", "公羊品种", "公羊家系", "公羊类别", "生日", "月龄", "体重",
                    // 配种信息
                    "配种类型"
            };

            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                if (i == 0 || i == headers.length - 1) {
                    cell.setCellStyle(headerStyle);
                } else if (i <= 12) {
                    cell.setCellStyle(eweHeaderStyle);
                } else {
                    cell.setCellStyle(ramHeaderStyle);
                }
            }

            // 数据行
            for (int i = 0; i < planDetails.size(); i++) {
                Map<String, Object> detail = planDetails.get(i);
                Row dataRow = sheet.createRow(rowNum++);
                int colNum = 0;

                // 序号
                dataRow.createCell(colNum++).setCellValue(i + 1);

                // 母羊信息
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_manage_tags"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_variety"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_family"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_sheep_type"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_breed_status"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_parity"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_month_age"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_current_weight"));
                dataRow.createCell(colNum++).setCellValue(getBooleanValue(detail, "ewe_is_core") ? "是" : "否");
                dataRow.createCell(colNum++).setCellValue(getBooleanValue(detail, "ewe_is_breeding") ? "是" : "否");
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_sheepfold_name"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_comment"));

                // 公羊信息
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_manage_tags"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_variety"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_family"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_sheep_type"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_birthday"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_month_age"));
                dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_current_weight"));

                // 配种类型
                Object breedTypeObj = detail.get("breed_type");
                String breedTypeName = "未知类型";
                if (breedTypeObj != null) {
                    try {
                        int typeValue = Integer.parseInt(breedTypeObj.toString());
                        switch (typeValue) {
                            case 1: breedTypeName = "供体母羊配种"; break;
                            case 2: breedTypeName = "同期发情人工授精"; break;
                            case 3: breedTypeName = "本交"; break;
                            case 4: breedTypeName = "自然发情人工授精"; break;
                            default: breedTypeName = "未知类型";
                        }
                    } catch (NumberFormatException e) {
                        // ignore
                    }
                }
               dataRow.createCell(colNum++).setCellValue(breedTypeName);
                // 应用数据样式
                for (int j = 0; j < headers.length; j++) {
                    if (dataRow.getCell(j) != null) {
                        dataRow.getCell(j).setCellStyle(dataStyle);
                    }
                }
            }

            // 自动调整列宽
            for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
                // 设置最小宽度
                if (sheet.getColumnWidth(i) < 2000) {
                    sheet.setColumnWidth(i, 2000);
                }
            }

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = java.net.URLEncoder.encode(planGenerate.getPlanName() + "_配种计划详情", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            // 输出到响应流
            workbook.write(response.getOutputStream());
            workbook.close();

        } catch (IOException e) {
            throw new RuntimeException("导出Excel失败", e);
        }
    }

    /**
     * 安全获取字符串值
     */
    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value != null ? value.toString() : "";
    }

    /**
     * 安全获取布尔值
     */
    private boolean getBooleanValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return false;
        if (value instanceof Boolean) return (Boolean) value;
        if (value instanceof Number) return ((Number) value).intValue() == 1;
        return "1".equals(value.toString()) || "true".equalsIgnoreCase(value.toString());
    }

    /**
     * 批量删除配种计划生成
     *
     * @param ids 需要删除的配种计划生成主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteScBreedPlanGenerateByIds(Long[] ids)
    {
        // 删除相关的临时配种计划
        for (Long id : ids) {
            scBreedPlanGenerateMapper.deleteTempBreedPlanByPlanId(id);
        }
        return scBreedPlanGenerateMapper.deleteScBreedPlanGenerateByIds(ids);
    }

    /**
     * 删除配种计划生成信息
     *
     * @param id 配种计划生成主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteScBreedPlanGenerateById(Long id)
    {
        // 先删除相关的临时配种计划
        scBreedPlanGenerateMapper.deleteTempBreedPlanByPlanId(id);
        return scBreedPlanGenerateMapper.deleteScBreedPlanGenerateById(id);
    }
    @Override
    public List<String> searchEarNumbers(String query) {
        return scBreedPlanGenerateMapper.searchEarNumbers(query);
    }
}