package com.bonus.material.largeScreen.service.impl;

import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.basic.domain.SysDeptVO;
import com.bonus.material.device.mapper.DevInfoMapper;
import com.bonus.material.equipment.domain.DeptConfigRateSummary;
import com.bonus.material.equipment.mapper.SysDeptMapper;
import com.bonus.material.equipment.service.ISysDeptService;
import com.bonus.material.largeScreen.entity.DevInfoReq;
import com.bonus.material.largeScreen.service.ProvinceScreenService;
import com.bonus.material.ma.mapper.MaTypeMapper;
import com.bonus.material.ma.vo.MaType;
import com.bonus.system.api.domain.SysDept;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;

import static com.bonus.common.biz.constant.MaterialConstants.ADMIN_ID;
import static com.bonus.common.biz.constant.MaterialConstants.PROVINCE_COMPANY_DEPT_ID;

/**
 * @author 马三炮
 * @date 2025/9/14
 */
@Service
@Slf4j
public class ProvinceScreenServiceImpl implements ProvinceScreenService {

    @Resource
    private DevInfoMapper devInfoMapper;

    @Resource
    private SysDeptMapper sysDeptMapper;

    @Resource
    private ISysDeptService sysDeptService;

    @Resource
    private MaTypeMapper maTypeMapper;

    /**
     * 计算当前日期与production_date的完整年数差（基于Java 8+ LocalDate）
     *
     * @param productionDateStr 生产日期字符串（格式：yyyy-MM-dd或yyyy-MM-dd HH:mm:ss）
     * @return 年数差（正数：当前日期在production_date之后；负数：当前日期在production_date之前；0：同年）
     * @throws DateTimeParseException 若日期字符串格式不符合要求，抛出解析异常
     */
    public static int calculateYearDifferenceWithJava8(String productionDateStr) throws DateTimeParseException {
        LocalDate productionDate;

        try {
            // 首先尝试解析包含时间的格式
            if (productionDateStr.length() > 10) {
                DateTimeFormatter fullFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                productionDate = LocalDateTime.parse(productionDateStr, fullFormatter).toLocalDate();
            } else {
                // 如果只有日期部分，使用简单的日期格式
                DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                productionDate = LocalDate.parse(productionDateStr, dateFormatter);
            }
        } catch (DateTimeParseException e) {
            // 如果解析失败，尝试提取日期部分
            if (productionDateStr.length() >= 10) {
                String datePart = productionDateStr.substring(0, 10);
                productionDate = LocalDate.parse(datePart, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            } else {
                throw e;
            }
        }

        LocalDate currentDate = LocalDate.now();
        return Period.between(productionDate, currentDate).getYears();
    }


    /**
     * 装备总量，总价值
     *
     * @return
     */
    @Override
    public Map<String, Object> getTotalEquipment() {
        Map<String, Object> res = new HashMap<>();
        DevInfoReq devInfoReq = new DevInfoReq();
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 管理员和省公司可查看所有数据
        if (userId != null && deptId != null
                && !userId.equals(ADMIN_ID)
                && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {
            devInfoReq.setOwnCo(deptId.intValue());
        }
        //装备总量
        Integer totalEquipmentQuantity = devInfoMapper.getTotalEquipment(devInfoReq);
        res.put("totalEquipmentQuantity", totalEquipmentQuantity);
        //总价值
        BigDecimal totalValue = devInfoMapper.getTotalValue(devInfoReq);
        res.put("totalValue", totalValue);
        return res;
    }

    /**
     * 线路装备，变电装备，电缆装备
     *
     * @return
     */
    @Override
    public Map<String, Object> getEquipmentClassification() {
        Map<String, Object> res = new HashMap<>();
        Map<String, Object> res1 = new HashMap<>();
        Map<String, Object> res2 = new HashMap<>();
        Map<String, Object> res3 = new HashMap<>();
        DevInfoReq devInfoReq = new DevInfoReq();
        //线路装备
        //装备数
        devInfoReq.setTypeId(1);
        int lineNum = devInfoMapper.getLineNum(devInfoReq);
        res1.put("num", lineNum);
        BigDecimal linePrice = devInfoMapper.getLinePrice(devInfoReq);
        res1.put("price", linePrice);
        List<String> lineProductionDateList = devInfoMapper.getLineProductionDateList(devInfoReq);
        count(res1, lineProductionDateList);
        //变电装备
        //装备数
        devInfoReq.setTypeId(2);
        int substationNum = devInfoMapper.getLineNum(devInfoReq);
        res2.put("num", substationNum);
        BigDecimal substationPrice = devInfoMapper.getLinePrice(devInfoReq);
        res2.put("price", substationPrice);
        List<String> substationProductionDateList = devInfoMapper.getLineProductionDateList(devInfoReq);
        count(res2, substationProductionDateList);
        //电缆装备
        //装备数
        devInfoReq.setTypeId(3);
        int cableNum = devInfoMapper.getLineNum(devInfoReq);
        res3.put("num", cableNum);
        BigDecimal cablePrice = devInfoMapper.getLinePrice(devInfoReq);
        res3.put("price", cablePrice);
        List<String> cableProductionDateList = devInfoMapper.getLineProductionDateList(devInfoReq);
        count(res3, cableProductionDateList);

        res.put("line", res1);
        res.put("substation", res2);
        res.put("cable", res3);
        return res;
    }

    /**
     * 单位装备配置
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getUnitEquipmentConfiguration() {
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 管理员和省公司可查看所有数据
        if (userId != null && deptId != null
                && !userId.equals(ADMIN_ID)
                && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {
            deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        } else {
            deptId = null;
        }
        List<Map<String, Object>> list = devInfoMapper.getUnitEquipmentConfiguration(deptId);
        return list;
    }

    /**
     * 装备状态
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getEquipmentStatus() {
        List<Map<String, Object>> res = new ArrayList<>();
        Map<String, Object> res1 = new HashMap<>();
        Map<String, Object> res2 = new HashMap<>();
        Map<String, Object> res3 = new HashMap<>();
        Map<String, Object> res4 = new HashMap<>();
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 管理员和省公司可查看所有数据
        if (userId != null && deptId != null
                && !userId.equals(ADMIN_ID)
                && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {
            deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        } else {
            deptId = null;
        }
        //在库--1
        int inStock = devInfoMapper.getEquipmentStatus("1", deptId);
        res1.put("name", "在库");
        res1.put("num", inStock);
        //自用--2
        int inUse = devInfoMapper.getEquipmentStatus("2", deptId);
        //共享--3
        int share = devInfoMapper.getEquipmentStatus("3", deptId);
        res2.put("name", "在用");
        res2.put("num", inUse + share);
        //维修--5
        int repair = devInfoMapper.getEquipmentStatus("5", deptId);
        res3.put("name", "在修");
        res3.put("num", repair);

        res4.put("name", "共享");
        res4.put("num", share);
        int count = inStock + inUse + share + repair;
        res1.put("proportion", count > 0 ? (inStock * 100) / count : 0 + "%");
        res2.put("proportion", count > 0 ? ((inUse + share) * 100) / count : 0 + "%");
        res3.put("proportion", count > 0 ? (repair * 100) / count : 0 + "%");
        res4.put("proportion", 0);
        res.add(res1);
        res.add(res2);
        res.add(res3);
        res.add(res4);
        return res;
    }

    /**
     * 项目装备
     *
     * @return
     */
    @Override
    public Map<String, Object> getProjectEquipment() {

        Map<String, Object> res = new HashMap<>();
        //年度总投资额 TODO 输入的
        res.put("annualTotal", "140.6");
        //在建工程数 TODO e基建2.0获取

        int projectNUm = devInfoMapper.getProjectNUm();
        res.put("projectNUm", projectNUm);
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 管理员和省公司可查看所有数据
        if (userId != null && deptId != null
                && !userId.equals(ADMIN_ID)
                && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {
            deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        } else {
            deptId = null;
        }
        //在用装备数
        //自用--2
        int inUse = devInfoMapper.getEquipmentStatus("2", deptId);
        //共享--3
        int share = devInfoMapper.getEquipmentStatus("3", deptId);
        res.put("num", inUse + share);
        //在用率
        DevInfoReq devInfoReq = new DevInfoReq();
        if (deptId != null) {
            devInfoReq.setOwnCo(deptId.intValue());
        }
        Integer totalEquipmentQuantity = devInfoMapper.getTotalEquipment(devInfoReq);
        res.put("proportion", totalEquipmentQuantity > 0 ? ((inUse + share) * 100) / totalEquipmentQuantity : 0 + "%");
        //周转率
        Integer devNum = devInfoMapper.getChangeNum(deptId);
        res.put("turnoverRate", totalEquipmentQuantity > 0 ? (devNum * 100) / totalEquipmentQuantity : 0 + "%");
        return res;
    }

    /**
     * 各单位装备在用率情况
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getDeptEquipment() {
        return maTypeMapper.getDeptEquipment();
    }

    /**
     * 工程在用装备情况
     *
     * @return
     */
    @Override
    public AjaxResult getEquipmentUse(String proCode, String proType) {
        String[] proCodeArray = new String[]{};
        List<String> proCodeList = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(proCode)) {
            proCodeArray = proCode.split(",");
            proCodeList = Arrays.asList(proCodeArray);
        }
        Map<String, Object> res = new HashMap<>();
        Integer proNum = maTypeMapper.getProNum(proType);
        Integer equipmentNum = maTypeMapper.getEquipmentNum(proType);
        res.put("proNum", proNum);
        res.put("equipmentNum", equipmentNum);
        res.put("equipmentUse", maTypeMapper.getEquipmentUse(proCodeList, proType));
        return AjaxResult.success(res);
    }

    /**
     * @return
     */
    @Override
    public List<Map<String, Object>> getEquipmentDetails(String proName) {
        return maTypeMapper.getEquipmentDetails(proName);
    }

    /**
     * 装备在用率统计
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getUsageStatistics(Integer type) {

   /*     List<Map<String, Object>> res = new ArrayList<>();
        List<MaType> maTypeList = new ArrayList<>();
        //获取装备在用率 查询全部
        if (StringUtils.isNull(type)) {
            maTypeList = maTypeMapper.selectMaTypeTreeBy5Level(null);
        } else {
            maTypeList = maTypeMapper.selectMaTypeTreeBy5Level2(type);
        }
        if (!maTypeList.isEmpty()) {
            for (MaType maType : maTypeList) {
                Map<String, Object> dev = new HashMap<>();
                DevInfoReq devInfoReq = new DevInfoReq();
                devInfoReq.setTypeId(Math.toIntExact(maType.getTypeId()));
                //装备总数
                Integer sum = devInfoMapper.getTotalEquipmentByLevel(devInfoReq);
                //自用2
                devInfoReq.setChangeStatus("2");
                Integer inUse = devInfoMapper.getTotalEquipmentByLevel(devInfoReq);
                devInfoReq.setChangeStatus("3");
                Integer share = devInfoMapper.getTotalEquipmentByLevel(devInfoReq);
                inUse = inUse + share;
                dev.put("name", maType.getTypeName());
                //在用率
                dev.put("proportion", sum > 0 ? (inUse * 100) / sum : (int) (Math.random() * 25) + "%");
                //周转率
                int turnoverRate = devInfoMapper.getTurnoverRateByLevel(devInfoReq);
                dev.put("turnoverRate", sum > 0 ? (turnoverRate * 100) / sum : (int) (Math.random() * 50) + "次/年");
                res.add(dev);
            }
        }
        // 【核心排序逻辑】按proportion数值降序排序（高在用率优先）
        res.sort((map1, map2) -> {
            // 1. 提取两个map中的proportion字符串
            String proportion1 = (String) map1.get("proportion");
            String proportion2 = (String) map2.get("proportion");
            // 2. 处理null值（默认视为0%）
            proportion1 = proportion1 == null ? "10%" : proportion1;
            proportion2 = proportion2 == null ? "11%" : proportion2;
            // 3. 去掉"%"符号，转为Integer数值（核心步骤）
            // 注意：若proportion含小数（如"83.5%"），需转为Double，此处按整数处理（适配原代码逻辑）
            int propValue1 = Integer.parseInt(proportion1.replace("%", ""));
            int propValue2 = Integer.parseInt(proportion2.replace("%", ""));
            // 4. 数值降序排序（高在用率在前）；升序用：propValue1 - propValue2
            return propValue2 - propValue1;
        });*/
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 管理员和省公司可查看所有数据
        if (userId != null && deptId != null
                && !userId.equals(ADMIN_ID)
                && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {
            deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        } else {
            deptId = null;
        }
        return maTypeMapper.getUsageStatistics(type, deptId);
    }

    /**
     * 在库装备数
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getEquipmentNumber() {
        //在库装备数
        List<Map<String, Object>> res = new ArrayList<>();
        SysDept sysDept = new SysDept();
        List<SysDeptVO> sysDeptList = sysDeptMapper.selectDeptVOList(sysDept);
        sysDeptList.removeIf(item -> item.getDeptType() == null || !Objects.equals(item.getDeptType(), "地市公司"));
        for (SysDeptVO sysDeptNew : sysDeptList) {
            Map<String, Object> dept = new HashMap<>();
            //入库1
            DevInfoReq devInfoReq = new DevInfoReq();
            devInfoReq.setOwnCo(Math.toIntExact(sysDeptNew.getDeptId()));
            devInfoReq.setChangeStatus("1");
            Integer inStock = devInfoMapper.getTotalEquipment(devInfoReq);
            dept.put("location", sysDeptNew.getLocation());
            dept.put("deptAbbreviation", sysDeptNew.getDeptAbbreviation() != null ? sysDeptNew.getDeptAbbreviation() : "未知部门");
            dept.put("name", sysDeptNew.getDeptName());
            dept.put("num", inStock);
            res.add(dept);
        }
        return res;
    }

    @Override
    public List<Map<String, Object>> getMechanizationRate() {
        return null;
    }

    /**
     * @return
     */
    @Override
    public List<Map<String, Object>> getUsageStatisticsDetails() {
        return maTypeMapper.getUsageStatisticsDetails();
    }

    /**
     * 统计数量
     */
    public void count(Map<String, Object> res, List<String> lineProductionDateList) {
        int five = 0;
        int fiveOrTen = 0;
        int ten = 0;
        if (!lineProductionDateList.isEmpty()) {
            for (String date : lineProductionDateList) {
                int yearDiff = calculateYearDifferenceWithJava8(date);
                if (yearDiff < 5) {
                    five++;
                } else if (yearDiff > 10) {
                    ten++;
                } else {
                    fiveOrTen++;
                }
            }
            five = !lineProductionDateList.isEmpty() ? (five * 100) / lineProductionDateList.size() : 0;
            fiveOrTen = !lineProductionDateList.isEmpty() ? (fiveOrTen * 100) / lineProductionDateList.size() : 0;
            ten = !lineProductionDateList.isEmpty() ? (ten * 100) / lineProductionDateList.size() : 0;
        }
        res.put("five", five);
        res.put("fiveOrTen", fiveOrTen);
        res.put("ten", ten);
    }


}
