package cn.com.ty.lift.business.annualinspection.service;

import cn.com.ty.lift.business.annualinspection.dto.InspectionCount;
import cn.com.ty.lift.business.annualinspection.dto.InspectionRequest;
import cn.com.ty.lift.business.annualinspection.dto.InspectionResponse;
import cn.com.ty.lift.business.annualinspection.entity.AnnualInspection;
import cn.com.ty.lift.business.annualinspection.mapper.AnnualInspectionMapper;
import cn.com.ty.lift.business.common.CommonRequest;
import cn.com.ty.lift.business.emergency.entity.EmergencyRepair;
import cn.com.ty.lift.business.emergency.service.EmergencyRepairService;
import cn.com.ty.lift.business.library.dao.entity.Lift;
import cn.com.ty.lift.business.library.dao.entity.LiftHistory;
import cn.com.ty.lift.business.library.dao.entity.PlatformCompanyLiftRelevance;
import cn.com.ty.lift.business.library.service.LiftHistoryService;
import cn.com.ty.lift.business.library.service.LiftService;
import cn.com.ty.lift.business.library.service.PlatformCompanyLiftRelevanceService;
import cn.com.ty.lift.business.maintenance.service.MaintenancePlanService;
import cn.com.ty.lift.common.constants.CommonEnum;
import cn.com.ty.lift.common.utils.ValuePool;
import cn.com.xwy.boot.web.dto.RestResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 年检记录 服务实现类
 * </p>
 *
 * @author wcz
 * @since 2019-12-10
 */
@Service
@AllArgsConstructor
public class AnnualInspectionService extends ServiceImpl<AnnualInspectionMapper, AnnualInspection> {

    private MaintenancePlanService              maintenancePlanService;
    private LiftService                         liftService;
    private LiftHistoryService                  liftHistoryService;
    private PlatformCompanyLiftRelevanceService platformCompanyLiftRelevanceService;
    private EmergencyRepairService              emergencyRepairService;

    /**
     * 年检列表中根据条件分页查询记录
     * @param request InspectionRequest
     * @return IPage<InspectionResponse>
     */
    public IPage<InspectionResponse> pageByCondition(InspectionRequest request) {
        //总经理查询所有年检任务
        if (CommonEnum.DefaultRole.HIGH_DIRECTOR.getCode().equals(request.getCurrentRoleCode())) {
            request.setWorkerId(null);
        }
        return baseMapper.pageByCondition(request.getPage(), request);
    }

    public InspectionCount count(InspectionRequest request) {
        InspectionCount inspectionCount = baseMapper.countInspectionByUserId(request);
        if (Objects.isNull(inspectionCount))
            inspectionCount = new InspectionCount();
        int toConfirm = baseMapper.countInspectionConfirmByUserId(request);
        inspectionCount.setToConfirm(toConfirm);
        return inspectionCount;
    }

    /**
     * 年检列表中根据条件计算记录总条数
     * @param request InspectionRequest
     * @return long
     */
    public long countByCondition(InspectionRequest request) {
        return baseMapper.countByCondition(request);
    }

    /**
     * 根据id查询单个年检记录的详情，带全部关联信息
     * @param request InspectionRequest
     * @return InspectionResponse
     */
    public InspectionResponse infoById(InspectionRequest request) {
        return baseMapper.infoById(request);
    }

    /**
     * 根据用户id查询关联的年检
     * @param request InspectionRequest
     * @return IPage<InspectionResponse>
     */
    public IPage<InspectionResponse> pageByUser(InspectionRequest request) {
        if(Objects.equals(request.getCurrentRoleCode(), CommonEnum.DefaultRole.HIGH_DIRECTOR.getCode())){
            request.setUserId(0L);
        }
        return baseMapper.pageByUser(request.getPage(), request);
    }

    public List<InspectionResponse> listByIdList(InspectionRequest request) {
        return baseMapper.listByIdList(request);
    }


    public IPage<InspectionResponse> pageByLift(InspectionRequest request) {
        return baseMapper.pageByLift(request.getPage(), request);
    }

    /**
     * 根据电梯，维保公司和计划年检日期查询年检记录
     * @param liftId 电梯
     * @param mtCompanyId 维保公司
     * @param planDate 计划年检日期
     * @return long
     */
    public AnnualInspection sameConfirm(Long liftId, Long mtCompanyId, LocalDate planDate) {
        LambdaQueryWrapper<AnnualInspection> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(AnnualInspection::getLiftId, liftId);
        lambdaQueryWrapper.eq(AnnualInspection::getMtCompanyId, mtCompanyId);
        lambdaQueryWrapper.eq(AnnualInspection::getPlanDate, planDate);
        lambdaQueryWrapper.last("LIMIT 1");
        return getOne(lambdaQueryWrapper);
    }

    /**
     * 根据电梯和维保公司查询最近的一次年检记录
     * @param liftId 电梯
     * @param mtCompanyId 维保公司
     * @return AnnualInspection
     */
    public AnnualInspection previousConfirm(Long liftId, Long mtCompanyId){
        LambdaQueryWrapper<AnnualInspection> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(AnnualInspection::getLiftId, liftId);
        lambdaQueryWrapper.eq(AnnualInspection::getMtCompanyId, mtCompanyId);
        lambdaQueryWrapper.orderByDesc(AnnualInspection::getPlanDate);
        lambdaQueryWrapper.last("LIMIT 1");
        return getOne(lambdaQueryWrapper);
    }

    private void rollback(){
        //强制手动事务回滚
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }
    /**
     * 3 -> 4	维保工上传检验结果
     * 5	企业文员确认检验结果-合格 --> 不能算年检超期
     * 6	企业文员确认检验结果-整改 --> 回到第二阶段
     *      (3  企业文员确认现场检验时间 录入人员信息，政府质检，企业质检，联系电话)
     * 7	企业文员确认检验结果-不合格 --> 可以算年检超期
     */
    @Transactional(rollbackFor = Exception.class)
    public RestResponse stepThree(AnnualInspection entity, Long projectId, Integer isCheckGoverner, Integer loadInspectionSetting) {
        //更新年检
        boolean up = updateById(entity);
        //更新失败，直接返回false
        if (!up) {
            return RestResponse.fail("更新年检失败，请稍后重试");
        }
        Long mtCompanyId = entity.getMtCompanyId();
        Long liftId = entity.getLiftId();
        PlatformCompanyLiftRelevance relevance = platformCompanyLiftRelevanceService.findByMtCompanyAndLift(mtCompanyId, liftId);
        if (Objects.isNull(relevance)) {
            return RestResponse.fail("平台公司电梯关联信息不存在，请核查");
        }
        //如果电梯在急修中，关掉急修，开始年检
        if (relevance.getLiftCompanyStatus().equals(CommonEnum.LiftStatus.EMERGENCY_REPAIR.getCode())) {
            EmergencyRepair repair = emergencyRepairService.findRepairing(mtCompanyId, liftId, projectId);
            if (Objects.nonNull(repair)) {
                repair.setCloseReason("开启年检，关闭急修");
                //新状态（-1 暂停中，0 待修理；1 修理中；2 已完成 3 已关闭）
                entity.setStatus(ValuePool.EMERGENCY_STATE_CLOSE);
                boolean cl = emergencyRepairService.updateById(repair);
                if (!cl) {
                    rollback();
                    return RestResponse.fail("关闭急修失败，请稍后重试");
                }
            }
        }
        relevance.setLiftCompanyStatus(CommonEnum.LiftStatus.ANNUAL_INSPECTION.getCode());
        boolean re = platformCompanyLiftRelevanceService.updateById(relevance);
        if(!re){
            //强制手动事务回滚
            rollback();
            return RestResponse.fail("修改电梯业务状态失败，请稍后重试");
        }
        //todo: 更新电梯中下一次年检信息
        //电梯不存在，说明数据有误，直接返回false
        Lift lift = liftService.getById(liftId);
        if (Objects.isNull(lift)) {
            rollback();
            return RestResponse.fail("关联电梯不存在，请核查");
        }
        //更新电梯之前获取旧的年检时间
        LocalDate oldInspectionDate = lift.getAnnualInspectionDate();
        LocalDate nextInspectionTime = entity.getNextInspectionTime();

        lift.setAnnualInspectionDate(nextInspectionTime);
        lift.setIsCheckGoverner(isCheckGoverner);
        lift.setLoadInspectionSetting(loadInspectionSetting);

        boolean li = liftService.updateById(lift);
        //更新电梯失败，返回false
        if (!li) {
            rollback();
            return RestResponse.fail("更新电梯下一次年检信息失败，请稍后重试");
        }
        //更新电梯成功，插入电梯操作记录
        LiftHistory liftHistory = new LiftHistory();
        liftHistory.setId(IdWorker.getId());
        liftHistory.setMtCompanyId(mtCompanyId);
        liftHistory.setLiftId(liftId);
        liftHistory.setCode(lift.getLiftCode());
        liftHistory.setDescription("修改电梯年检日期");
        liftHistory.setBeforeContent(String.format("%tF", oldInspectionDate));
        liftHistory.setAfterContent(String.format("%tF", nextInspectionTime));

        //fixme:获取当前登录用户
        liftHistory.setOperatorId(entity.getUpdateId());
        liftHistory.setOperateDate(LocalDateTime.now());
        boolean lh = liftHistoryService.save(liftHistory);
        //插入电梯记录成功，直接返回true,否则手动事务回滚，返回false
        if (lh) {
            return RestResponse.success(true);
        } else {
            rollback();
            return RestResponse.fail("添加电梯操作日志失败，请稍后重试");
        }
    }
    /**
     * 8	维保工上传年检报告和合格证
     * 9	企业文员确认年检报告和合格证-合格
     * 10	企业文员确认年检报告和合格证-不合格 -->停用电梯
     */
    @Transactional(rollbackFor = Exception.class)
    public RestResponse stepFour(AnnualInspection entity){
        //更新年检
        boolean up = updateById(entity);
        //更新失败，直接返回false
        if (!up) {
            return RestResponse.fail("更新年检失败，请稍后重试");
        }
        Integer stepStatus = entity.getStepStatus();
        Long mtCompanyId = entity.getMtCompanyId();
        Long liftId = entity.getLiftId();

        PlatformCompanyLiftRelevance relevance = platformCompanyLiftRelevanceService.findByMtCompanyAndLift(mtCompanyId, liftId);
        if (Objects.isNull(relevance)) {
            return RestResponse.fail("平台公司电梯关联信息不存在，请核查");
        }
        //todo 不合格：流程结束，电梯扭转到不合格状态列表，电梯停保，清理维保计划记录
        if (stepStatus == ValuePool.INSPECTION_STAGE_CERT_REPORT_UNQUALIFIED) {
            //如果不合格，修改电梯的业务状态为停保
            relevance.setLiftCompanyStatus(CommonEnum.LiftStatus.STOP_INSURANCE.getCode());
            boolean re = platformCompanyLiftRelevanceService.updateById(relevance);
            if(!re){
                rollback();
                return RestResponse.fail("修改电梯业务状态失败，请稍后重试");
            }

            boolean mp = maintenancePlanService.cleanPlan(mtCompanyId, liftId);
            if (mp) {
                return RestResponse.success(true);
            } else {
                //强制手动事务回滚
                rollback();
                return RestResponse.fail("清除电梯维保计划失败，请稍后重试");
            }
        }
        //todo:合格：修改电梯的业务状态为正常
        if (stepStatus == ValuePool.INSPECTION_STAGE_CERT_REPORT_QUALIFIED) {
            //如果合格，修改电梯的业务状态为正常
            relevance.setLiftCompanyStatus(CommonEnum.LiftStatus.NORMAL.getCode());
            boolean re = platformCompanyLiftRelevanceService.updateById(relevance);
            if(re){
                return RestResponse.success(true);
            }else{
                rollback();
                return RestResponse.fail("修改电梯业务状态失败，请稍后重试");
            }
        }
        return RestResponse.success(true);
    }

    /**
     * 根据id和mtCompanyId查找唯一
     * @param id 主键id
     * @param mtCompanyId 维保公司id
     * @return AnnualInspection
     */
    public AnnualInspection findByMtCompanyId(Long id, Long mtCompanyId) {
        LambdaQueryWrapper<AnnualInspection> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(AnnualInspection::getId, id);
        lambdaQueryWrapper.eq(AnnualInspection::getMtCompanyId, mtCompanyId);
        return getOne(lambdaQueryWrapper);
    }

    public long countDoingByUser(CommonRequest request){
        return baseMapper.countDoingByUser(request);
    }
}
