package com.bonus.material.devchange.service;

import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.devchange.domain.*;
import com.bonus.material.devchange.mapper.MaDevInfoMapper;
import com.bonus.material.device.domain.vo.DevInfoPropertyVo;
import com.bonus.material.device.domain.vo.DevMergeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

import static com.bonus.common.biz.constant.MaterialConstants.ADMIN_ID;
import static com.bonus.common.biz.constant.MaterialConstants.PROVINCE_COMPANY_DEPT_ID;
import static org.apache.commons.math3.exception.util.LocalizedFormats.SCALE;

@Service
public class MaDevInfoServiceImpl implements MaDevInfoService {

    @Autowired
    private MaDevInfoMapper mapper;


    @Override
    public List<MaDevInfo> list(MaDevInfo o) {
        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)) {
//            o.setCompanyId(deptId);
//        }
        if(ADMIN_ID.equals(userId)){
            o.setCompanyId(1L);
        }else{
            o.setCompanyId(deptId);
        }
        List<MaDevInfo> list = mapper.list(o);

        // 折旧常量定义（年折旧10% → 剩余90%，保留2位小数）
        BigDecimal DEPRECIATION_RATE = new BigDecimal("0.9");
        int SCALE = 2;

        list.forEach(item -> {
            List<DevInfoPropertyVo> propertiiesList = mapper.getProperties(item);
            if (propertiiesList != null && !propertiiesList.isEmpty()) {
                item.setPropertyVoList(propertiiesList);
            }
            item.setAppearanceImages(mapper.getFileList(item.getMaId(), 1));
            item.setCertificates(mapper.getFileList(item.getMaId(), 2));
            item.setInspectionReports(mapper.getFileList(item.getMaId(), 3));
            item.setPurchaseInvoices(mapper.getFileList(item.getMaId(), 4));

            // 计算资产净值
            // 空值校验：出厂日期/原值为空 → 净值设为null
            Date productionDate = item.getProductionDate();
            BigDecimal originalValue = item.getOriginalValue();
            if (productionDate == null || originalValue == null) {
                item.setValue(null); // 净值字段设为null
                return; // 跳过当前装备的净值计算
            }

            //  Date转LocalDate（解决日期计算兼容问题）
            LocalDate prodLocalDate = productionDate.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate();
            LocalDate currentDate = LocalDate.now();

            //  出厂日期晚于当前日期 → 净值=原值
            if (prodLocalDate.isAfter(currentDate)) {
                item.setValue(originalValue.setScale(SCALE, RoundingMode.HALF_UP));
                return;
            }

            // 计算使用年限（整年数，不足1年按0算）
            Period period = Period.between(prodLocalDate, currentDate);
            int useYears = period.getYears();
            // 校验：若「出厂日期+使用年限」仍晚于当前日期，说明不足1年，年份减1
            if (prodLocalDate.plusYears(useYears).isAfter(currentDate)) {
                useYears--;
            }
            useYears = Math.max(useYears, 0); // 最低为0年

            //计算净值：原值 × (0.9)^使用年限，保留2位小数
            BigDecimal depreciation = DEPRECIATION_RATE.pow(useYears);
            BigDecimal netValue = originalValue.multiply(depreciation)
                    .setScale(SCALE, RoundingMode.HALF_UP); // 四舍五入
            // 兜底：净值最低为0（避免折旧后为负）
            netValue = netValue.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : netValue;

            if(item.getValue() == null ||!item.getValue().equals(netValue) ){
                mapper.updatePrice(item.getMaId(),netValue);
            }

            // 填充净值到实体字段
            item.setValue(netValue);


        });



        return list;
    }

    @Override
    public Integer updateDeviceStatus(DevMergeVo o) {
        String[] split = o.getDevIds().split(",");
        if (split.length > 0) {
            List<MapBean> list = new ArrayList<>();
            for (String s : split) {
                list.add(new MapBean(s, o.getStatus()));
            }
            return mapper.updateDeviceStatus(list);
        } else {
            return 0;
        }
    }

    @Override
    public Integer delDevice(String[] ids) {
        return mapper.delDevice(ids);
    }

    @Override
    public DeviceTreeBean deviceTree(String id) {
        List<DeviceTreeBean> list = mapper.deviceTree(id);
        return buildTree(list);
    }

    @Override
    public DeviceCountBean deviceCount(MaDevInfo o) {
        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)) {
            o.setCompanyId(deptId);
        }
        return mapper.deviceCount(o);
    }

    @Override
    public List<MapBean> deviceLocationSel(String id) {
        return mapper.deviceLocationSel(id);
    }

    @Override
    public List<MapBean> companySel(String id) {
        return mapper.companySel(id);
    }

    /**
     * @param o
     * @return
     */
    @Override
    public Integer updateDeviceApi(MaDevInfo o) {
        mapper.delProperties(o);
        mapper.insertDevInfoProperties(o.getPropertyVoList(), o.getMaId());
        return mapper.updateDeviceApi(o);
    }

    /**
     * @param maId
     * @return
     */
    @Override
    public MaDevInfo getDevice(Integer maId) {
        MaDevInfo item = mapper.getDevice(maId);
        List<DevInfoPropertyVo> propertiiesList = mapper.getProperties(item);
        if (propertiiesList != null && !propertiiesList.isEmpty()) {
            item.setPropertyVoList(propertiiesList);
        }
        item.setAppearanceImages(mapper.getFileList(item.getMaId(), 1));
        item.setCertificates(mapper.getFileList(item.getMaId(), 2));
        item.setInspectionReports(mapper.getFileList(item.getMaId(), 3));
        item.setPurchaseInvoices(mapper.getFileList(item.getMaId(), 4));
        return item;
    }

    /**
     * @param maIds
     * @return
     */
    @Override
    public AjaxResult getDeviceByMaIds(String maIds) {
        String[] maIdArray = maIds.split(",");
        return AjaxResult.success(mapper.getDeviceByMaIds(maIdArray));
    }

    /**
     * @param o
     * @return
     */
    @Override
    public List<MaDevInfoXlsx> export(MaDevInfo o) {
        // 1. 一次性查询所有主表数据（1次查询）
        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)) {
            o.setCompanyId(deptId);
        }
        List<MaDevInfoXlsx> mainList = mapper.listXlsx(o);
        if (mainList.isEmpty()) {
            return Collections.emptyList(); // 空数据直接返回，避免后续无效操作
        }

        // 2. 收集所有主表ID（用于批量查关联属性）
        List<Integer> mainIds = mainList.stream()
                .map(MaDevInfoXlsx::getMaId) // 假设主表主键是id（Long类型，根据实际字段调整）
                .filter(Objects::nonNull) // 过滤空ID，防止查询异常
                .collect(Collectors.toList());

        // 3. 一次性批量查询所有关联属性（1次查询，替代原N次循环查询）
        List<DevInfoPropertyVo> allProperties = mapper.batchGetProperties(mainIds);

        // 4. 用Map分组关联属性：key=主表ID，value=该主表对应的所有属性（内存关联核心）
        Map<Integer, List<DevInfoPropertyVo>> propertyMap = allProperties.stream()
                .collect(Collectors.groupingBy(DevInfoPropertyVo::getMaId)); // 按关联字段（dev_id）分组

        // 5. 批量给主表对象设置属性列表（无循环查库，纯内存操作）
        mainList.forEach(main -> {
            // 若主表ID无对应属性，返回空集合（避免null）
            List<DevInfoPropertyVo> properties = propertyMap.getOrDefault(main.getMaId(), Collections.emptyList());
            main.setPropertyVoList(properties);
            // 自动填充 propertyName1~9 和 propertyValue1~9（适配Excel导出）
            main.fillPropertyFields();
        });

        return mainList;
    }


    /**
     * 将扁平列表构建成树，并添加一个总的根节点，根节点名称包含设备总数
     */
    public DeviceTreeBean buildTree(List<DeviceTreeBean> list) {
        // 统计设备总数（列表的size即为总数量）
        //int totalCount = list == null ? 0 : list.size();
        Long companyId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 管理员和省公司可查看所有数据
//        if (userId != null && companyId != null
//                && !userId.equals(ADMIN_ID)
//                && !companyId.equals(PROVINCE_COMPANY_DEPT_ID)) {
//            companyId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
//        } else {
//            companyId = null;
//        }
        if(ADMIN_ID.equals(userId)){
            companyId = 1L;
        }
        Integer totalCount = mapper.selectTotalDeviceCount(companyId);

        if (list == null || list.isEmpty()) {
            // 空列表时显示总数为0
            return new DeviceTreeBean("0", "-1", "装备目录（总数：0）");
        }

        // 1. 创建 id -> node 映射
        Map<String, DeviceTreeBean> nodeMap = new HashMap<>();
        for (DeviceTreeBean node : list) {
            node.setChildren(new ArrayList<>());
            nodeMap.put(node.getId(), node);
        }

        // 2. 创建虚拟根节点（level=1 的父节点）
        DeviceTreeBean virtualRoot = new DeviceTreeBean("-1", null, "虚拟根");
        nodeMap.put("-1", virtualRoot);

        // 3. 按 level 排序，从小到大构建（确保父节点先存在）
        List<DeviceTreeBean> sortedList = list.stream()
                .sorted(Comparator.comparing(DeviceTreeBean::getLevel))
                .collect(Collectors.toList());

        // 4. 遍历节点，挂载到父节点
        for (DeviceTreeBean node : sortedList) {
            String pId = node.getPId();
            DeviceTreeBean parentNode = nodeMap.get(pId);
            if (parentNode == null) {
                // 如果父节点不存在，挂到虚拟根
                parentNode = virtualRoot;
            }
            if (parentNode.getChildren() == null) {
                parentNode.setChildren(new ArrayList<>());
            }
            parentNode.getChildren().add(node);
        }

        // 5. 创建最终的总根节点，名称包含设备总数
        DeviceTreeBean root = new DeviceTreeBean("0", "-1", String.format("装备目录（总数：%d）", totalCount));
        if (virtualRoot.getChildren() != null && !virtualRoot.getChildren().isEmpty()) {
            if (root.getChildren() == null) {
                root.setChildren(new ArrayList<>());
            }
            root.getChildren().addAll(virtualRoot.getChildren());
        }

        return root;
    }


}
