package com.securitycontrol.system.base.service.impl;

import com.securitycontrol.common.core.constant.Constant;
import com.securitycontrol.common.core.utils.StringUtils;
import com.securitycontrol.common.core.utils.aes.DateTimeHelper;
import com.securitycontrol.common.core.utils.uuid.IdUtils;
import com.securitycontrol.common.core.web.domain.AjaxResult;
import com.securitycontrol.common.security.utils.ValidatorsUtils;
import com.securitycontrol.entity.system.base.dto.GxPlanDto;
import com.securitycontrol.entity.system.base.dto.ProScheduleDto;
import com.securitycontrol.entity.system.base.vo.GxPlanProgressVo;
import com.securitycontrol.entity.system.base.vo.GxPlanVo;
import com.securitycontrol.entity.system.base.vo.ProScheduleVo;
import com.securitycontrol.system.base.mapper.IProScheduleMapper;
import com.securitycontrol.system.base.service.IProScheduleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author：cwchen
 * @date：2024-03-13-19:08
 * @version：1.0
 * @description：工程进度-业务逻辑层
 */
@Slf4j
@Service(value = "IProScheduleService")
public class ProScheduleServiceImpl implements IProScheduleService {

    @Resource(name = "IProScheduleMapper")
    private IProScheduleMapper mapper;

    @Resource(name = "ValidatorsUtils")
    private ValidatorsUtils validatorsUtils;

    @Override
    public List<ProScheduleVo> getProScheduleLists(ProScheduleDto dto) {
        List<ProScheduleVo> list = new ArrayList<>();
        try {
            list = mapper.getProScheduleLists(dto);
        } catch (Exception e) {
            log.error("获取工程进度列表", e);
        }
        return list;
    }

    @Override
    public List<GxPlanVo> getGxPlanLists(GxPlanDto dto) {
        List<GxPlanVo> list = new ArrayList<>();
        try {
            list = mapper.getGxPlanLists(dto);
        } catch (Exception e) {
            log.error("获取工序计划列表", e);
        }
        return list;
    }

    @Override
    public AjaxResult getGxPlansIsDela(ProScheduleDto dto) {
        List<String> list = new ArrayList<>();
        try {
            list = mapper.getGxPlansIsDela(dto);
        } catch (Exception e) {
            log.error("工序计划延期提醒", e);
        }
        return AjaxResult.success(list);
    }

    @Override
    public List<GxPlanProgressVo> getGxPlanProgressLists(ProScheduleDto dto) {
        List<GxPlanProgressVo> list = new ArrayList<>();
        try {
            list = mapper.getGxPlanProgressLists(dto);
        } catch (Exception e) {
            log.error("获取工序计划进度列表", e);
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult fillingGxProgress(GxPlanProgressVo vo) {
        try {
            String validResult = validatorsUtils.valid(vo, GxPlanProgressVo.Query.class);
            if (StringUtils.isNotBlank(validResult)) {
                return AjaxResult.error(validResult);
            }
            // 验证工序计划进度数据
            AjaxResult ajaxResult = validateData(vo);
            if (ajaxResult != null) {
                return ajaxResult;
            }
            // 工序计划进度赋值
            vo = setGxPlanProgressData(vo);
            // 填报工序计划
            vo.setCreateTime(DateTimeHelper.getNowTime());
            String progressId = IdUtils.getUUId();
            vo.setProgressId(progressId);
            mapper.addGxPlanProgress(vo);
            // 查询该工序计划所有填报信息
            List<Map<String, Object>> progressList = mapper.getProgressData(vo);
            statisticsProgress(progressList,vo);
        } catch (Exception e) {
            log.error("填报工序计划进度列表", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
        return AjaxResult.success();
    }

    /**
     * 验证进度填报
     *
     * @return AjaxResult
     * @description
     * @author cwchen
     * @date 2024/3/29 18:06
     */
    public AjaxResult validateData(GxPlanProgressVo vo) {
        // 计划结束时间不能为空
        Long timestamp = DateTimeHelper.convertDateStringToTimestamp(vo.getPlanEndTime(), "yyyy-MM-dd");
        if (timestamp == null) {
            return AjaxResult.error("计划结束时间格式不正确");
        }
        // 如果当前时间超过计划结束时间 需要填写计划延期原因
        Long timestamp2 = DateTimeHelper.convertDateStringToTimestamp(DateTimeHelper.getNowDate(), "yyyy-MM-dd");
        if (timestamp2 > timestamp && StringUtils.isEmpty(vo.getDelaReason())) {
            return AjaxResult.error("计划延期原因不能为空");
        }
        // 获取当前工序的填报进度 线路->杆塔分为 基础、组塔、架线  变电直接到工序
        String nowGxPlanProgress = mapper.getGxPlanProgress(vo);
        if (StringUtils.isNotEmpty(nowGxPlanProgress)) {
            double aDouble = Double.parseDouble(nowGxPlanProgress);
            double bDouble = Double.parseDouble(vo.getGxProgress());
            if (bDouble < aDouble) {
                return AjaxResult.error("当前工序进度填报需大于上一次工序填报进度");
            }
        }
        return null;
    }

    /**
     * 进度填报赋值
     *
     * @param vo
     * @return GxPlanProgressVo
     * @description
     * @author cwchen
     * @date 2024/3/30 12:44
     */
    public GxPlanProgressVo setGxPlanProgressData(GxPlanProgressVo vo) {
        // 判断计划是否是第一次填报 并更新工序计划开始时间
        int result = mapper.isFirstFillingGxProgress(vo);
        if (result == 0) {
            vo.setStartTime(DateTimeHelper.getNowDate());
            vo.setType(1);
            mapper.updateGxPlanData(vo);
        }
        // 变电 - 工序进度达到 100 更新计划结束日期
        if (Objects.equals(vo.getProType(), Constant.BD) &&
                Objects.equals(Double.parseDouble(Constant.GX_PLAN_PROGRESS), vo.getGxProgress())) {
            vo.setEndTime(DateTimeHelper.getNowDate());
        }
        // 线路 - 工序进度为架线 并且进度到100 更新计划结束日期
        if (Objects.equals(vo.getProType(), Constant.XL) &&
                Objects.equals(Double.parseDouble(Constant.GX_PLAN_PROGRESS), vo.getGxProgress()) &&
                Objects.equals(vo.getNowGxId(), Constant.JX)) {
            vo.setEndTime(DateTimeHelper.getNowDate());
        }
        // 计划有延期或者进度填报达到100时更新到工序计划
        if (StringUtils.isNotEmpty(vo.getDelaReason()) || StringUtils.isNotEmpty(vo.getEndTime())) {
            vo.setType(2);
            mapper.updateGxPlanData(vo);
        }
        // 工程为线路时 更新杆塔当前工序
        if (Objects.equals(Constant.XL, vo.getProType())) {
            mapper.updateGtData(vo);
        }
        return vo;
    }

    /**
     * 统计并更新工序计划进度
     * @param progressList
     * @param vo
     * @description
     * @author cwchen
     * @date 2024/3/30 12:46
     */
    public void statisticsProgress(List<Map<String, Object>> progressList, GxPlanProgressVo vo) {
        if (CollectionUtils.isNotEmpty(progressList)) {
            BigDecimal value = new BigDecimal("0");
            BigDecimal gxNum = new BigDecimal("3");
            for (Map<String, Object> map : progressList) {
                BigDecimal dataValue = new BigDecimal(String.valueOf(map.get("gxProgress")));
                value = value.add(dataValue);
            }
            if(Objects.equals(vo.getProType(),Constant.XL)){
                value = value.divide(gxNum, 3, BigDecimal.ROUND_HALF_UP);
            }
            vo.setPlanProgress(value.doubleValue());
            mapper.updateGxPlan(vo);
        }
    }
}
