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

import cn.com.ty.lift.business.capital.dao.entity.CapitalRepair;
import cn.com.ty.lift.business.capital.dao.entity.CapitalRepairHistory;
import cn.com.ty.lift.business.capital.dao.entity.CapitalRepairImage;
import cn.com.ty.lift.business.capital.dao.entity.model.request.CapitalRepairRequest;
import cn.com.ty.lift.business.capital.dao.entity.model.response.CapitalRepairResponse;
import cn.com.ty.lift.business.capital.dao.mapper.CapitalRepairMapper;
import cn.com.ty.lift.business.framework.util.MessageUtils;
import cn.com.ty.lift.business.library.dao.entity.model.response.LiftResponse;
import cn.com.ty.lift.business.library.service.PlatformCompanyLiftRelevanceService;
import cn.com.ty.lift.business.maintenance.service.MaintenanceService;
import cn.com.ty.lift.business.project.dao.entity.ProjectUser;
import cn.com.ty.lift.business.project.dao.entity.model.response.ProjectUserResponse;
import cn.com.ty.lift.business.project.service.ProjectUserService;
import cn.com.ty.lift.common.utils.DateUtils;
import cn.com.xwy.boot.web.dto.RestResponse;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static cn.com.ty.lift.common.constants.CommonEnum.CapitalRepairStatus;

/**
 * @author bieao
 * @date 2020/2/3 11:38 上午
 * @description 大修项目业务层
 */
@Service
@Slf4j
public class CapitalRepairService extends ServiceImpl<CapitalRepairMapper, CapitalRepair> {

    @Resource
    private ProjectUserService projectUserService;

    @Resource
    private PlatformCompanyLiftRelevanceService platformCompanyService;

    @Resource
    private CapitalRepairLiftRelevanceService capitalRepairLiftRelevanceService;

    @Resource
    private CapitalRepairHistoryService capitalRepairHistoryService;

    @Resource
    private CapitalRepairImageService capitalRepairImageService;

    @Resource
    private MaintenanceService maintenanceService;

    /**
     * @param request 大修项目列表查询条件
     * @return RestResponse 结果集
     * @description 条件查询大修项目列表
     * @date 2020/2/3 11:38 上午
     */
    public IPage<CapitalRepairResponse> list(CapitalRepairRequest request) {
        request.addDesc("end_date");
        return baseMapper.findByCondition(request.getPage(), request);
    }

    /**
     * @param request 维保公司ID
     * @return List<Map<String,Object>> 项目ID和名称列表
     * @description 项目ID和名称列表
     * @date 2020/4/30 10:39 上午
     */
    public List<Map<String,Object>> projectIDList(CapitalRepairRequest request) {
        QueryWrapper<CapitalRepair> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(request.getMtCompanyId()), "mt_company_id", request.getMtCompanyId());
        queryWrapper.select("id projectId", "project_name projectName");
        return listMaps(queryWrapper);
    }

    /**
     * @param request 电梯列表查询条件
     * @return IPage<LiftResponse> 大修项目电梯列表
     * @description 查询大修项目电梯列表
     * @date 2020/4/29 3:50 下午
     */
    public IPage<LiftResponse> liftProjectList(CapitalRepairRequest request) {
        return baseMapper.findLiftListByProjectId(request.getPage(), request);
    }

    /**
     * @param request 选择电梯列表查询条件
     * @return IPage<LiftResponse> 选择电梯列表
     * @description 选择电梯
     * @date 2020/4/29 8:58 下午
     */
    public IPage<LiftResponse> choose(CapitalRepairRequest request) {
        return baseMapper.chooseLiftList(request.getPage(), request);
    }

    /**
     * @param mtCompanyId   公司id
     * @param projectStatus 项目状态
     * @return 项目数量、电梯数量、停保电梯数量
     * @description 查询大修项目数量、电梯数量、停保电梯数量
     * @date 2020/4/23 3:31 下午
     */
    public Map<String, Object> countAll(Long mtCompanyId, String projectStatus) {
        LambdaQueryWrapper<CapitalRepair> lambdaQueryWrapper = new QueryWrapper<CapitalRepair>().lambda();
        lambdaQueryWrapper.eq(CapitalRepair::getMtCompanyId, mtCompanyId);
        List<CapitalRepair> projects = list(lambdaQueryWrapper);
        Map<String, Long> collect = projects.stream().collect(Collectors.groupingBy(CapitalRepair::getProjectStatus, Collectors.counting()));
        Map<String, Long> totalMap = new HashMap<>();
        Long notStart = collect.get(CapitalRepairStatus.NO_START.getCode());
        Long inService = collect.get(CapitalRepairStatus.ABUILDING.getCode());
        Long complete = collect.get(CapitalRepairStatus.COMPLETE.getCode());
        Long checkPending = collect.get(CapitalRepairStatus.CHECK_PENDING.getCode());
        Long stopService = collect.get(CapitalRepairStatus.STOP_SERVICE.getCode());
        totalMap.put("notStart", notStart == null ? 0 : notStart);
        totalMap.put("inService", inService == null ? 0 : inService);
        totalMap.put("complete", complete == null ? 0 : complete);
        totalMap.put("checkPending", checkPending == null ? 0 : checkPending);
        totalMap.put("stopService", stopService == null ? 0 : stopService);
        int projectCount = count(mtCompanyId, projectStatus);
        int liftCount = capitalRepairLiftRelevanceService.count(mtCompanyId, projectStatus);
        int stopLiftCount = platformCompanyService.countCapital(mtCompanyId, projectStatus);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("totalCount", totalMap);
        resultMap.put("projectCount", projectCount);
        resultMap.put("liftCount", liftCount);
        resultMap.put("stopLiftCount", stopLiftCount);
        return resultMap;
    }

    /**
     * @param mtCompanyId   公司id
     * @param projectStatus 项目状态
     * @return 符合条件的项目数量
     * @description 根据项目状态和公司id查询项目数量
     * @date 2020/4/23 3:31 下午
     */
    public int count(Long mtCompanyId, String projectStatus) {
        LambdaQueryWrapper<CapitalRepair> lambdaQueryWrapper = new QueryWrapper<CapitalRepair>().lambda();
        lambdaQueryWrapper.eq(CapitalRepair::getMtCompanyId, mtCompanyId);
        lambdaQueryWrapper.eq(CapitalRepair::getProjectStatus, projectStatus);
        return count(lambdaQueryWrapper);
    }

    /**
     * @param id 大修项目id
     * @return CapitalRepair 大修项目详情
     * @description 查询大修项目详情
     * @date 2020/2/25 11:58 上午
     */
    public CapitalRepair getOne(Long id) {
        QueryWrapper<CapitalRepair> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<CapitalRepair> lambdaQueryWrapper = queryWrapper.lambda();
        lambdaQueryWrapper.eq(CapitalRepair::getId, id);
        return getOne(lambdaQueryWrapper);
    }

    /**
     * @param id 大修项目id
     * @return Map<String, Object> 大修项目详情和项目组列表
     * @description 查询大修项目详情和项目组列表
     * @date 2020/2/3 11:31 上午
     */
    public Map<String, Object> detail(Long id, Long mtCompanyId) {
        CapitalRepair capitalRepair = getOne(id);
        List<ProjectUserResponse> userList = projectUserService.getUserList(id, mtCompanyId);
        List<CapitalRepairImage> imageUrlList = capitalRepairImageService.imageUrlList(id, mtCompanyId);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("capitalRepair", capitalRepair);
        resultMap.put("userList", userList);
        resultMap.put("imageUrlList", imageUrlList);
        return resultMap;
    }

    /**
     * @param request 新增大修项目数据项
     * @return Integer 成功1或失败0
     * @description 新增大修项目
     * @date 2020/2/3 11:31 上午
     */
    @Transactional(rollbackFor = Exception.class)
    public RestResponse add(CapitalRepairRequest request) {
        CapitalRepair repair = request.getCapitalRepair();
        String projectCode = DateUtils.generateCode();
        repair.setProjectCode("XM" + projectCode);
        repair.setProjectStatus(CapitalRepairStatus.NO_START.getCode());
        boolean result = save(repair);
        if (!result) return RestResponse.fail(MessageUtils.get("msg.add.fail"));
        //批量新增项目成员信息
        List<ProjectUser> users = request.getUserList();
        users.forEach(user -> user.setProjectId(repair.getId()));
        boolean ret = projectUserService.saveBatch(users, users.size());
        if (!ret) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RestResponse.fail(MessageUtils.get("msg.add.fail"));
        }
        return RestResponse.success(null, MessageUtils.get("msg.add.success"));
    }

    /**
     * @param repair 修改大修项目数据项
     * @return 是否成功
     * @description 修改大修项目
     * @date 2020/2/3 11:36 上午
     */
    public RestResponse modify(CapitalRepair repair) {
        CapitalRepair oldCapital = getOne(repair.getId());
        if (ObjectUtil.isEmpty(oldCapital))
            return RestResponse.fail(MessageUtils.get("msg.capital.not.exist"));
        boolean result = updateById(repair);
        if (!result)
            return RestResponse.fail(MessageUtils.get("msg.modify.fail"));
        //生成大修项目操作记录
        CapitalRepairHistory history = capitalRepairHistoryService.saveOperaHistory(oldCapital, repair, repair.getMtCompanyId());
        if (Objects.nonNull(history)) {
            //保存大修项目操作记录
            boolean projectResult = capitalRepairHistoryService.save(history);
            if (!projectResult) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return RestResponse.fail(MessageUtils.get("msg.modify.fail"));
            }
        }
        return RestResponse.success(null, MessageUtils.get("msg.modify.success"));
    }

    /**
     * @param request 是否通过
     * @return Integer 成功1或失败0
     * @description 大修审核
     * @date 2020/2/4 12:46 下午
     */
    public boolean audit(CapitalRepairRequest request) {
        CapitalRepair capitalRepair = getOne(request.getId());
        //逾期审核
        if (Objects.equals(0, request.getType())) {
            if (Objects.equals(0, request.getPass())) {
                capitalRepair.setOverdueFlag(0);
            } else {
                capitalRepair.setOverdueFlag(1);
            }
        }
        //竣工审核
        capitalRepair.setProjectStatus(Objects.equals(0, request.getPass()) ?
                CapitalRepairStatus.ABUILDING.getCode() : CapitalRepairStatus.COMPLETE.getCode());
        return updateById(capitalRepair);
    }

    /**
     * @param request 项目id，公司id
     * @return Integer 成功1或失败0
     * @description 大修项目开始
     * @date 2020/4/21 3:13 下午
     */
    public boolean begin(CapitalRepairRequest request) {
        CapitalRepair capitalRepair = getOne(request.getProjectId());
        if (ObjectUtil.isEmpty(capitalRepair)) return false;
        capitalRepair.setProjectStatus(CapitalRepairStatus.ABUILDING.getCode());
        return updateById(capitalRepair);
    }

    /**
     * @param request 项目id，公司id
     * @return Integer 成功1或失败0
     * @description 大修竣工
     * @date 2020/4/26 1:47 下午
     */
    @Transactional(rollbackFor = Exception.class)
    public RestResponse completed(CapitalRepairRequest request) {
        CapitalRepair capitalRepair = getOne(request.getProjectId());
        if (ObjectUtil.isEmpty(capitalRepair))
            return RestResponse.fail(MessageUtils.get("msg.capital.not.exist"));
        capitalRepair.setProjectStatus(CapitalRepairStatus.CHECK_PENDING.getCode());
        boolean result = updateById(capitalRepair);
        if (!result) return RestResponse.fail(MessageUtils.get("msg.modify.fail"));
        List<CapitalRepairImage> imageList = new ArrayList<>();
        //组装竣工单数据
        request.getImageUrlList().forEach(entry -> {
            CapitalRepairImage image = new CapitalRepairImage();
            image.setImageUrl(entry);
            image.setMtCompanyId(request.getMtCompanyId());
            image.setProjectId(request.getProjectId());
            imageList.add(image);
        });
        //保存竣工单地址
        boolean ret = capitalRepairImageService.saveBatch(imageList);
        if (!ret) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RestResponse.fail(MessageUtils.get("msg.modify.fail"));
        }
        return RestResponse.success(MessageUtils.get("msg.modify.success"));
    }

    /**
     * @param request liftIdList 电梯id列表
     * @return 1.成功, 0.失败, 消息描述
     * @description 服务操作
     * @date 2020/4/29 10:16 上午
     */
    @Transactional(rollbackFor = Exception.class)
    public RestResponse serviceOperate(CapitalRepairRequest request) {
        Integer operate = request.getOperate();
        Long projectId = request.getProjectId();
        Long mtCompanyId = request.getMtCompanyId();
        CapitalRepair oldRepair = getOne(projectId);
        if (Objects.isNull(oldRepair))
            return RestResponse.success(null, MessageUtils.get("msg.capital.not.exist"));
        CapitalRepair repair = new CapitalRepair();
        repair.setId(projectId);
        switch (operate) {
            //恢复服务
            case 1:
                //判断当前公司台量是否大于企业设置的台量
                boolean judgeResult = maintenanceService.judge(mtCompanyId);
                if (!judgeResult) {
                    return RestResponse.fail(MessageUtils.get("msg.limit.num"));
                }
                repair.setStartDate(request.getStartDate());
                repair.setEndDate(request.getEndDate());
                repair.setProjectStatus(CapitalRepairStatus.ABUILDING.getCode());
                boolean result = updateById(repair);
                if (!result)
                    return RestResponse.fail(MessageUtils.get("msg.modify.fail"));
                break;
            //停止服务
            case 2:
                //修改项目状态为停止
                repair.setProjectStatus(CapitalRepairStatus.STOP_SERVICE.getCode());
                //设置停止时间及描述
                repair.setEndRemarks(request.getEndRemarks());
                repair.setStopTime(request.getStopTime());
                boolean repairResult = updateById(repair);
                if (!repairResult)
                    return RestResponse.fail(MessageUtils.get("msg.modify.fail"));
                break;
            default:
                break;
        }
        return RestResponse.success(null, MessageUtils.get("msg.project.operate.success"));
    }

    /**
     * @param request 逾期原因，逾期时间
     * @return Integer 成功1或失败0
     * @description 逾期申请
     * @date 2020/4/15 11:34 上午
     */
    public boolean overdueApply(CapitalRepairRequest request) {
        CapitalRepair capitalRepair = getOne(request.getProjectId());
        if (ObjectUtil.isEmpty(capitalRepair)) return false;
        capitalRepair.setOverdueDate(request.getOverdueDate());
        capitalRepair.setOverdueReason(request.getOverdueReason());
        capitalRepair.setOverdueFlag(1);
        return updateById(capitalRepair);
    }

}
