package com.ozs.plan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ozs.common.core.domain.AjaxResult;
import com.ozs.common.core.domain.entity.SysDept;
import com.ozs.common.core.domain.entity.SysDictData;
import com.ozs.common.core.domain.model.LoginUser;
import com.ozs.common.enums.ProjectStatus;
import com.ozs.common.enums.ProjectTypes;
import com.ozs.common.enums.SysFileRefEnum;
import com.ozs.common.exception.ServiceException;
import com.ozs.common.utils.StringUtils;
import com.ozs.common.utils.bean.BeanUtils;
import com.ozs.plan.doman.PlanQuarter;
import com.ozs.plan.doman.PlanYears;
import com.ozs.plan.doman.ProvisionalPlan;
import com.ozs.plan.doman.vo.requestVo.PlanQuarterStandardVo;
import com.ozs.plan.doman.vo.requestVo.ProvisionalPlanVo;
import com.ozs.plan.mapper.PlanYearsMapper;
import com.ozs.plan.mapper.ProvisionalPlanMapper;
import com.ozs.plan.service.ProvisionalPlanService;
import com.ozs.system.domain.SysFileRef;
import com.ozs.system.domain.vo.responseVo.SysDeptResponseVo;
import com.ozs.system.mapper.SysDeptMapper;
import com.ozs.system.mapper.SysFileRefMapper;
import com.ozs.system.service.ISysDeptService;
import com.ozs.system.service.ISysDictTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;

@Service
public class ProvisionalPlanServiceImpl extends ServiceImpl<ProvisionalPlanMapper, ProvisionalPlan> implements ProvisionalPlanService {

    @Autowired
    private ProvisionalPlanMapper provisionalPlanMapper;
    @Autowired
    private ISysDictTypeService dictTypeService;
    @Autowired
    private SysDeptMapper deptMapper;
    @Autowired
    private ISysDeptService deptService;
    @Autowired
    private PlanYearsMapper planYearsMapper;
    @Autowired
    private SysFileRefMapper sysFileRefMapper;

    @Override
    public int deleteProvisionalPlanById(Integer planYearId) {
        return provisionalPlanMapper.deleteProvisionalPlanById(planYearId);
    }

    @Override
    public int updateProvisionalPlanById(ProvisionalPlan provisionalPlan) {
        return provisionalPlanMapper.updateProvisionalPlanById(provisionalPlan);
    }

    @Override
    public String importProvisionalPlan(List<ProvisionalPlan> provisionalPlans, boolean updateSupport, LoginUser loginUser) {
        // 字典项
        HashMap<String, HashMap<String, String>> planEnums = dictTypeService.getAboutEnums();
        HashMap<String, String> projectTypesMap = planEnums.get("projectTypes");
        HashMap<String, String> planPurchaseModesMap = planEnums.get("planPurchaseModes");
        HashMap<String, String> projectAttributes = planEnums.get("projectAttributes");
        HashMap<String, String> purchaseServices = planEnums.get("purchaseServices");

        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (ProvisionalPlan ofProvisionalPlan : provisionalPlans) {
            try {
                //验证项目名称是否重复导入
                List<ProvisionalPlan> plan = provisionalPlanMapper.selectProjectName(ofProvisionalPlan.getProjectName());
                //将录入信息中的值更改为要保存的数据
                if (plan.size() == 0) {
                    //采购单位
                    SysDept info = deptMapper.checkDeptNameOnlyOne(ofProvisionalPlan.getPurchaseDeptName());
                    if (StringUtils.isNotNull(info)) {
                        ofProvisionalPlan.setPurchaseDeptId(info.getDeptId());
                    }
                    ofProvisionalPlan.setProjectType(projectTypesMap.get(ofProvisionalPlan.getProjectType()));
                    ofProvisionalPlan.setProjectStatus(ProjectStatus.PLANWAITCOMMIT.getCode());
                    ofProvisionalPlan.setPurchaseMode(planPurchaseModesMap.get(ofProvisionalPlan.getPurchaseMode()));
                    //项目属性是多选字段
                    StringBuilder builder = new StringBuilder();
                    if (ofProvisionalPlan.getProjectAttr().contains(",")) {
                        String[] split = ofProvisionalPlan.getProjectAttr().split(",");
                        for (String s : split) {
                            builder.append(projectAttributes.get(s) + ",");
                        }
                    } else {
                        builder.append(projectAttributes.get(ofProvisionalPlan.getProjectAttr()));
                    }
                    ofProvisionalPlan.setProjectAttr(builder.toString());
                    ofProvisionalPlan.setPurchaseServices(purchaseServices.get(ofProvisionalPlan.getPurchaseServices()));
                    ofProvisionalPlan.setIsExcess(isExcessOrNo(ofProvisionalPlan.getProjectType(), ofProvisionalPlan.getEvaluation()));
                    ofProvisionalPlan.setCreated(String.valueOf(loginUser.getUserId()));
                    ofProvisionalPlan.setCreateTime(new Date());
                    ofProvisionalPlan.setPlanType("1");
                    provisionalPlanMapper.insert(ofProvisionalPlan);
                    successNum++;
                    successMsg.append("*" + successNum + "、项目 " + ofProvisionalPlan.getProjectName() + " 导入成功!");
                } else {
                    failureNum++;
                    failureMsg.append("*" + successNum + "、项目 " + ofProvisionalPlan.getProjectName() + " 已存在");
                }
            } catch (Exception exc) {
                failureNum++;
                String msg = "*" + successNum + "、项目 " + ofProvisionalPlan.getProjectName() + " 导入失败";
                failureMsg.append(msg + exc.getMessage());
                log.error(msg, exc);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "导入失败！共 " + failureNum + " 条数据格式不正确：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "导入成功！共 " + successNum + " 条。");
        }
        return successMsg.toString();
    }

    @Override
    public List<ProvisionalPlan> selectProvisionalPlanExport(ProvisionalPlanVo vo) {
        List<ProvisionalPlan> list = new ArrayList<>();
        List<ProvisionalPlan> provisionalPlanList = new ArrayList<>();
        try {
            int num = 1;
            int size = 200;
            while (size == 200) {
                LambdaQueryWrapper<ProvisionalPlan> lw = new LambdaQueryWrapper<ProvisionalPlan>();
                if (!ObjectUtils.isEmpty(vo.getProjectName())) {
                    lw.like(ProvisionalPlan::getProjectName, vo.getProjectName());
                }
                if (!ObjectUtils.isEmpty(vo.getPurchaseServices())) {
                    lw.eq(ProvisionalPlan::getPurchaseServices, vo.getPurchaseServices());
                }
                if (!ObjectUtils.isEmpty(vo.getIsExcess())) {
                    lw.eq(ProvisionalPlan::getIsExcess, vo.getIsExcess());
                }
                if (!ObjectUtils.isEmpty(vo.getProjectStatus())) {
                    lw.eq(ProvisionalPlan::getProjectStatus, vo.getProjectStatus());
                }
                if (!ObjectUtils.isEmpty(vo.getStartTime())) {
                    lw.ge(ProvisionalPlan::getPlanDemandSubTime, vo.getStartTime());
                }
                if (!ObjectUtils.isEmpty(vo.getEndTime())) {
                    lw.le(ProvisionalPlan::getPlanDemandSubTime, vo.getEndTime());
                }
                Page<ProvisionalPlan> page = provisionalPlanMapper.selectPage(new Page<ProvisionalPlan>(num, size, false), lw);
                list.addAll(page.getRecords());
                size = page.getRecords().size();
                num++;
            }
            provisionalPlanList = changeTo(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return provisionalPlanList;
    }

    @Override
    public int commitProvisionalPlan(ProvisionalPlanVo provisionalPlanVo) {
        return provisionalPlanMapper.commitProvisionalPlan(provisionalPlanVo.getPlanPracticalId());
    }

    @Override
    public ProvisionalPlan seletById(Integer planPracticalId) {
        ProvisionalPlan provisionalPlan = changeToProvisionalPlan(provisionalPlanMapper.seletById(planPracticalId));
        return provisionalPlan;
    }

    @Override
    public PageInfo<ProvisionalPlan> selectProvisionalPlan(ProvisionalPlanVo provisionalPlanVo) {
        List<ProvisionalPlan> provisionalPlanList = provisionalPlanMapper.selectProvisionalPlan(provisionalPlanVo);
        provisionalPlanList = changeTo(provisionalPlanList);
        PageHelper.startPage(provisionalPlanVo.getPageNum().intValue(), provisionalPlanVo.getPageSize().intValue());
        PageInfo<ProvisionalPlan> pageInfo = new PageInfo<>(provisionalPlanList);
        return pageInfo;
    }

    @Override
    public PageInfo<ProvisionalPlan> selectProvisionalPlanAudit(ProvisionalPlanVo provisionalPlanVo) {
        List<ProvisionalPlan> provisionalPlanList = provisionalPlanMapper.selectProvisionalPlanAudit(provisionalPlanVo);
        provisionalPlanList = changeTo(provisionalPlanList);
        PageHelper.startPage(provisionalPlanVo.getPageNum().intValue(), provisionalPlanVo.getPageSize().intValue());
        PageInfo<ProvisionalPlan> pageInfo = new PageInfo<>(provisionalPlanList);
        return pageInfo;
    }

    @Override
    public AjaxResult auditPass(ProvisionalPlanVo provisionalPlanVo) {
        ProvisionalPlan byId = provisionalPlanMapper.seletById(provisionalPlanVo.getPlanPracticalId());
        if (ObjectUtils.isEmpty(byId.getPlanYearId())) {
            PlanYears ofYears = new PlanYears();
            BeanUtils.copyProperties(provisionalPlanVo, ofYears);
            planYearsMapper.insertPlanYears(ofYears);
            Long planYearId = ofYears.getPlanYearId();
            byId.setPlanYearId(ofYears.getPlanYearId().intValue());
        }
        byId.setProjectStatus(ProjectStatus.PLANTOEXAMINE.getCode());
        return review(provisionalPlanVo, byId);
    }

    @Override
    public AjaxResult auditNoPass(ProvisionalPlanVo provisionalPlanVo) {
        ProvisionalPlan provisionalPlan = new ProvisionalPlan();
        BeanUtils.copyProperties(provisionalPlanVo, provisionalPlan);
        provisionalPlan.setProjectStatus(ProjectStatus.PLANTOBACK.getCode());
        return review(provisionalPlanVo, provisionalPlan);
    }

    private AjaxResult review(ProvisionalPlanVo vo, ProvisionalPlan provisionalPlan) {
        List<SysFileRef> sysFileRefs = vo.getSysFileRefs();
        if (!ObjectUtils.isEmpty(sysFileRefs)) {
            for (SysFileRef ref : sysFileRefs) {
                ref.setRedId(vo.getPlanPracticalId().longValue());
                ref.setType(SysFileRefEnum.PLAN_TEMPORARY.getType());
                ref.setCreated(vo.getUpdated());
                ref.setCreateTime(new Date());
                ref.setUpdated(vo.getUpdated());
                ref.setUpdateTime(new Date());
                sysFileRefMapper.insert(ref);
            }
        }
        int review = provisionalPlanMapper.review(provisionalPlan);
        if (review != 1) {
            return AjaxResult.error("项目状态数据异常");
        }
        return AjaxResult.success();
    }

    //判断是否为超额计划
    public String isExcessOrNo(String projectType, BigDecimal evaluation) {
        BigDecimal threshold = new BigDecimal(0);
        //获取各个项目类型设定的概算金额阈值
        List<SysDictData> data = dictTypeService.selectDictDataByType("sys_over_limit_threshold");
        HashMap<String, String> thresholdMap = new LinkedHashMap<>();
        //各个类型的概算金额阈值
        for (SysDictData dictData : data) {
            //    类型----阈值
            thresholdMap.put(dictData.getDictLabel(), dictData.getDictValue());
        }
        //项目类型
        for (ProjectTypes value : ProjectTypes.values()) {
            if (projectType.equals(value.getCode())) {
                threshold = BigDecimal.valueOf(Long.parseLong(thresholdMap.get(value.getInfo())));
            }
            break;
        }
        if (evaluation.compareTo(threshold) == 1) {
            //是超额计划
            return ("1");
        } else {
            return ("0");
        }
    }

    // 字典项负值
    public ProvisionalPlan changeToProvisionalPlan(ProvisionalPlan provisionalPlan) {
        HashMap<String, HashMap<String, String>> planEnums = dictTypeService.getAboutEnums();
        HashMap<String, String> projectTypesMap = planEnums.get("projectTypes");
        HashMap<String, String> planPurchaseModesMap = planEnums.get("planPurchaseModes");
        HashMap<String, String> projectAttributes = planEnums.get("projectAttributes");
        HashMap<String, String> purchaseServices = planEnums.get("purchaseServices");
        if (provisionalPlan.getPurchaseDeptId() != null) {
            SysDeptResponseVo sysDeptResponseVo = (SysDeptResponseVo) deptService.selectDeptById(provisionalPlan.getPurchaseDeptId()).get("sysDept");
            provisionalPlan.setPurchaseDeptName(sysDeptResponseVo.getDeptName());
        }
        for (Map.Entry<String, String> entry : projectTypesMap.entrySet()) {
            if (provisionalPlan.getProjectType() != null && provisionalPlan.getProjectType().equals(entry.getValue())) {
                provisionalPlan.setProjectTypeStr(entry.getKey());
                break;
            }
        }
        for (Map.Entry<String, String> entry : planPurchaseModesMap.entrySet()) {
            if (provisionalPlan.getPurchaseMode() != null && provisionalPlan.getPurchaseMode().equals(entry.getValue())) {
                provisionalPlan.setPurchaseModeStr(entry.getKey());
                break;
            }
        }
        //项目属性是拼接的
        if (provisionalPlan.getProjectAttr().length() > 1) {
            StringBuilder builder = new StringBuilder();
            String[] split = provisionalPlan.getProjectAttr().split(",");
            for (String s : split) {
                for (Map.Entry<String, String> entry : projectAttributes.entrySet()) {
                    if (s.equals(entry.getValue())) {
                        builder.append(entry.getKey() + ",");
                        break;
                    }
                }
            }
            provisionalPlan.setProjectAttrStr(builder.toString());
        } else {
            for (Map.Entry<String, String> entry : projectAttributes.entrySet()) {
                if (provisionalPlan.getProjectAttr() != null && provisionalPlan.getProjectAttr().equals(entry.getValue())) {
                    provisionalPlan.setProjectAttrStr(entry.getKey());
                    break;
                }
            }
        }
        for (Map.Entry<String, String> entry : purchaseServices.entrySet()) {
            if (provisionalPlan.getPurchaseServices() != null && provisionalPlan.getPurchaseServices().equals(entry.getValue())) {
                provisionalPlan.setPurchaseServicesStr(entry.getKey());
                break;
            }
        }
        return provisionalPlan;
    }

    //字段赋值对应的名称
    public List<ProvisionalPlan> changeTo(List<ProvisionalPlan> provisionalPlans) {
        HashMap<String, HashMap<String, String>> planEnums = dictTypeService.getAboutEnums();
        HashMap<String, String> projectTypesMap = planEnums.get("projectTypes");
        HashMap<String, String> planPurchaseModesMap = planEnums.get("planPurchaseModes");
        HashMap<String, String> projectAttributes = planEnums.get("projectAttributes");
        HashMap<String, String> purchaseServices = planEnums.get("purchaseServices");
        List<ProvisionalPlan> list = new ArrayList<ProvisionalPlan>();
        for (ProvisionalPlan provisionalPlan : provisionalPlans) {
            if (provisionalPlan.getPurchaseDeptId() != null) {
                SysDeptResponseVo sysDeptResponseVo = (SysDeptResponseVo) deptService.selectDeptById(provisionalPlan.getPurchaseDeptId()).get("sysDept");
                provisionalPlan.setPurchaseDeptName(sysDeptResponseVo.getDeptName());
            }
            for (Map.Entry<String, String> entry : projectTypesMap.entrySet()) {
                if (provisionalPlan.getProjectType() != null && provisionalPlan.getProjectType().equals(entry.getValue())) {
                    provisionalPlan.setProjectTypeStr(entry.getKey());
                    break;
                }
            }
            for (Map.Entry<String, String> entry : planPurchaseModesMap.entrySet()) {
                if (provisionalPlan.getPurchaseMode() != null && provisionalPlan.getPurchaseMode().equals(entry.getValue())) {
                    provisionalPlan.setPurchaseModeStr(entry.getKey());
                    break;
                }
            }
            //项目属性是拼接的
            if (provisionalPlan.getProjectAttr().length() > 1) {
                StringBuilder builder = new StringBuilder();
                String[] split = provisionalPlan.getProjectAttr().split(",");
                for (String s : split) {
                    for (Map.Entry<String, String> entry : projectAttributes.entrySet()) {
                        if (s.equals(entry.getValue())) {
                            builder.append(entry.getKey() + ",");
                            break;
                        }
                    }
                }
                provisionalPlan.setProjectAttrStr(builder.toString());
            } else {
                for (Map.Entry<String, String> entry : projectAttributes.entrySet()) {
                    if (provisionalPlan.getProjectAttr() != null && provisionalPlan.getProjectAttr().equals(entry.getValue())) {
                        provisionalPlan.setProjectAttrStr(entry.getKey());
                        break;
                    }
                }
            }
            for (Map.Entry<String, String> entry : purchaseServices.entrySet()) {
                if (provisionalPlan.getPurchaseServices() != null && provisionalPlan.getPurchaseServices().equals(entry.getValue())) {
                    provisionalPlan.setPurchaseServicesStr(entry.getKey());
                    break;
                }
            }

            list.add(provisionalPlan);
        }
        return list;
    }
}
