package com.yuchen.saas.park.service.service.repair.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuchen.saas.integration.feign.api.util.PageConverterUtils;
import com.yuchen.saas.manage.system.api.entity.NestOrgUser;
import com.yuchen.saas.manage.system.api.feign.ApplyManageFeignServer;
import com.yuchen.saas.manage.system.api.feign.IOrgUserClient;
import com.yuchen.saas.park.api.dto.repair.*;
import com.yuchen.saas.park.api.dto.work.SaasWorkOrderDto;
import com.yuchen.saas.park.api.dto.work.SaasWorkOrderMatterRepairDto;
import com.yuchen.saas.park.api.entity.repair.SaasMatterRepair;
import com.yuchen.saas.park.api.entity.repair.SaasMatterRepairHandleRecord;
import com.yuchen.saas.park.api.entity.work.SaasWorkOrder;
import com.yuchen.saas.park.api.enums.repair.EvaluateLevelEnum;
import com.yuchen.saas.park.api.enums.repair.RepairAreaEnum;
import com.yuchen.saas.park.api.enums.repair.RepairStatusEnum;
import com.yuchen.saas.park.api.enums.work.ConfirmResultEnum;
import com.yuchen.saas.park.api.enums.work.HandleResultEnum;
import com.yuchen.saas.park.api.enums.work.WorkOrderStatusEnum;
import com.yuchen.saas.park.api.vo.repair.*;
import com.yuchen.saas.park.api.vo.work.SaasWorkOrderVo;
import com.yuchen.saas.park.service.mapper.repair.SaasMatterRepairMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.repair.ISaasMatterRepairHandleRecordService;
import com.yuchen.saas.park.service.service.repair.ISaasMatterRepairService;
import com.yuchen.saas.park.service.service.repair.ISaasMatterRepairTypeService;
import com.yuchen.saas.park.service.service.work.ISaasWorkOrderService;
import org.nest.springwrap.core.log.exception.ServiceException;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.mp.support.NestPage;
import org.nest.springwrap.core.secure.utils.AuthUtil;
import org.nest.springwrap.core.tool.utils.BeanUtil;
import org.nest.springwrap.core.tool.utils.Func;
import org.nest.springwrap.core.tool.utils.WebUtil;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 报事报修表 服务实现类
 * </p>
 *
 * @author caiwq
 * @since 2024-04-24
 */
@Service
public class SaasMatterRepairServiceImpl extends BaseServiceImpl<SaasMatterRepairMapper, SaasMatterRepair> implements ISaasMatterRepairService {

    @Resource
    @Lazy
    private ISaasWorkOrderService workOrderService;
    @Resource
    private ISaasMatterRepairHandleRecordService matterRepairHandleRecordService;
    @Resource
    private ISaasMatterRepairTypeService repairTypeService;
    @Resource
    private PmgBatParkInfoService pmgBatParkInfoService;
    @Resource
    private IOrgUserClient iOrgUserClient;
    @Resource
    private ApplyManageFeignServer applyManageFeignServer;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(SaasMatterRepairDto matterRepairDto) {
        SaasMatterRepair matterRepair = BeanUtil.copyProperties(matterRepairDto, SaasMatterRepair.class);
        //客户ID
        Long customerId = AuthUtil.getUser().getCustomerManageId();
        matterRepair.setCustomerId(customerId);
        //录单人
        Long recordUserId = AuthUtil.getUser().getOrgUserId();
        String recordUserName = iOrgUserClient.detail(recordUserId).getData().getName();
        matterRepair.setRecordUserId(recordUserId);
        matterRepair.setRecordUserName(recordUserName);
        //录单时间
        matterRepair.setRecordTime(new Date());
        // 报修单号
        String repairNo = "BX" + new SimpleDateFormat("yyyyMMdd").format(new Date()) + (int) ((Math.random() * 9 + 1) * 1000);
        matterRepair.setRepairNo(repairNo);
        // 应用ID
        matterRepair.setAppId(Long.parseLong(WebUtil.getApplyId()));
        save(matterRepair);
        // 添加处理记录
        SaasMatterRepairHandleRecord handleRecord = new SaasMatterRepairHandleRecord();
        handleRecord.setRepairId(matterRepair.getId());
        handleRecord.setOperateTime(new Date());
        handleRecord.setOperateType("提交报修");
        handleRecord.setOperateUserId(AuthUtil.getUser().getOrgUserId());
        handleRecord.setImgUrl(matterRepair.getRepairImage());
        matterRepairHandleRecordService.save(handleRecord);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean accept(SaasMatterRepairAcceptDto acceptDto) {
        SaasMatterRepair matterRepair = getById(acceptDto.getId());
        if (Func.isEmpty(matterRepair)) {
            throw new ServiceException("报事报修不存在");
        }
        if (acceptDto.getOptType() == 1) {
            matterRepair.setRepairStatus(RepairStatusEnum.TO_DISPATCH.getValue());
        } else if (acceptDto.getOptType() == 2) {
            matterRepair.setRepairStatus(RepairStatusEnum.CANCELED.getValue());
        }
        updateById(matterRepair);
        // 添加处理记录
        SaasMatterRepairHandleRecord handleRecord = new SaasMatterRepairHandleRecord();
        handleRecord.setRepairId(matterRepair.getId());
        handleRecord.setOperateTime(new Date());
        handleRecord.setOperateType("受理");
        handleRecord.setOperateUserId(AuthUtil.getUser().getOrgUserId());
        handleRecord.setOperateContent(acceptDto.getHandleDesc());
        matterRepairHandleRecordService.save(handleRecord);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean dispatch(SaasMatterRepairDispatchDto dispatchDto) {
        SaasMatterRepair matterRepair = getById(dispatchDto.getId());
        if (Func.isEmpty(matterRepair)) {
            throw new ServiceException("报事报修不存在");
        }
        SaasWorkOrderDto workOrderDto = new SaasWorkOrderDto();
        workOrderDto.setWorkOrderCategory(1);
        SaasWorkOrderMatterRepairDto workOrderMatterRepairDto = BeanUtil.copyProperties(dispatchDto, SaasWorkOrderMatterRepairDto.class);
        workOrderMatterRepairDto.setLinkNo(matterRepair.getId());
        workOrderDto.setWorkOrderMatterRepairDto(workOrderMatterRepairDto);
        SaasWorkOrder workOrder = workOrderService.add(workOrderDto);
        matterRepair.setRepairStatus(RepairStatusEnum.TO_HANDLE.getValue());
        updateById(matterRepair);
        // 添加处理记录
        SaasMatterRepairHandleRecord handleRecord = new SaasMatterRepairHandleRecord();
        handleRecord.setRepairId(matterRepair.getId());
        handleRecord.setOperateTime(new Date());
        handleRecord.setOperateType("派工");
        handleRecord.setOperateUserId(AuthUtil.getUser().getOrgUserId());
        handleRecord.setOperateContent(dispatchDto.getDispatchRemark());
        matterRepairHandleRecordService.save(handleRecord);
        return Boolean.TRUE;
    }

    @Override
    public Boolean back(SaasMatterRepairBackDto backDto) {
        SaasMatterRepair matterRepair = getById(backDto.getId());
        if (Func.isEmpty(matterRepair)) {
            throw new ServiceException("报事报修不存在");
        }
        matterRepair.setBackResult(backDto.getBackResult());
        matterRepair.setBackUserId(AuthUtil.getUser().getOrgUserId());
        matterRepair.setBackTime(new Date());
        matterRepair.setRepairStatus(RepairStatusEnum.CLOSED.getValue());
        updateById(matterRepair);
        // 添加处理记录
        SaasMatterRepairHandleRecord handleRecord = new SaasMatterRepairHandleRecord();
        handleRecord.setRepairId(matterRepair.getId());
        handleRecord.setOperateTime(new Date());
        handleRecord.setOperateType("派工");
        handleRecord.setOperateUserId(AuthUtil.getUser().getOrgUserId());
        handleRecord.setOperateContent(backDto.getBackResult());
        matterRepairHandleRecordService.save(handleRecord);
        return Boolean.TRUE;
    }


    @Override
    public Boolean cancle(SaasMatterRepairCancleDto cancleDto) {
        SaasMatterRepair matterRepair = getById(cancleDto.getId());
        if (Func.isEmpty(matterRepair)) {
            throw new ServiceException("报事报修不存在");
        }
        if(cancleDto.getOptType() == 1) {
            matterRepair.setRepairStatus(RepairStatusEnum.CANCELED.getValue());
        }else if(cancleDto.getOptType() == 2) {
            matterRepair.setRepairStatus(RepairStatusEnum.CLOSED.getValue());
        }
        return updateById(matterRepair);
    }

    @Override
    public Boolean evaluate(SaasMatterRepairEvaluateDto evaluateDto) {
        SaasMatterRepair matterRepair = getById(evaluateDto.getId());
        if (Func.isEmpty(matterRepair)) {
            throw new ServiceException("报事报修不存在");
        }
        matterRepair.setEvaluateLevel(evaluateDto.getEvaluateLevel());
        matterRepair.setEvaluateTag(evaluateDto.getEvaluateTag());
        matterRepair.setEvaluateContent(evaluateDto.getEvaluateContent());
        return updateById(matterRepair);
    }

    @Override
    public Boolean remove(Long id) {
        return removeById(id);
    }

    @Override
    public SaasMatterRepairVo getDetail(Long id) {
        SaasMatterRepairVo matterRepairVo = BeanUtil.copyProperties(getById(id), SaasMatterRepairVo.class);
        // 报修类型名称
        matterRepairVo.setRepairTypeName(repairTypeService.getById(matterRepairVo.getRepairTypeId()).getName());
        NestOrgUser orgUser = iOrgUserClient.detail(matterRepairVo.getBackUserId()).getData();
        if (Func.isNotEmpty(orgUser)) {
            // 回访人员
            matterRepairVo.setBackUserName(orgUser.getName());
        }
        // 项目名称
        matterRepairVo.setProjectName(pmgBatParkInfoService.getById(matterRepairVo.getProjectId()).getParkName());
        // 应用名称
        matterRepairVo.setAppName(applyManageFeignServer.getDetail(matterRepairVo.getAppId()).getData().getName());
        // 派工详情
        SaasWorkOrderVo workOrderVo = workOrderService.getDetailByLinkNo(id);
        if (Func.isNotEmpty(workOrderVo)) {
            SaasMatterRepairVo.DispatchDetail dispatchDetail = BeanUtil.copyProperties(workOrderVo, SaasMatterRepairVo.DispatchDetail.class);
            matterRepairVo.setDispatchDetail(dispatchDetail);
        }
        // 处理记录
        List<SaasMatterRepairHandleRecord> list = matterRepairHandleRecordService.lambdaQuery().eq(SaasMatterRepairHandleRecord::getRepairId, id).orderByDesc(SaasMatterRepairHandleRecord::getOperateTime).list();
        List<SaasMatterRepairHandleRecordVo> handleRecordList = BeanUtil.copyProperties(list, SaasMatterRepairHandleRecordVo.class);
        handleRecordList.forEach(handleRecord -> {
            handleRecord.setOperateUserName(iOrgUserClient.detail(handleRecord.getOperateUserId()).getData().getName());
        });
        matterRepairVo.setHandleRecordList(handleRecordList);
        return matterRepairVo;
    }

    @Override
    public NestPage<SaasMatterRepairListVo> getMatterRepairList(SaasMatterRepairQueryDto queryDto) {
        // 分页获取数据
        Page<SaasMatterRepairListVo> page = new Page<>(queryDto.getCurrent(), queryDto.getSize());
        page = baseMapper.getMatterRepairList(page, queryDto);
        List<SaasMatterRepairListVo> list = page.getRecords();
        for (SaasMatterRepairListVo vo : list) {
            // 报修类型名称
            vo.setRepairTypeName(repairTypeService.getById(vo.getRepairTypeId()).getName());
            // 回访人员
            NestOrgUser orgUser = iOrgUserClient.detail(vo.getBackUserId()).getData();
            if (Func.isNotEmpty(orgUser)) {
                vo.setBackUserName(orgUser.getName());
            }
            // 项目名称
            vo.setProjectName(pmgBatParkInfoService.getById(vo.getProjectId()).getParkName());
            // 应用名称
            vo.setAppName(applyManageFeignServer.getDetail(vo.getAppId()).getData().getName());
        }
        return PageConverterUtils.convert(page);
    }

    @Override
    public void export(SaasMatterRepairQueryDto queryDto, HttpServletResponse response) {
        // 分页获取数据
        Page<SaasMatterRepairListVo> page = new Page<>(1, 100000);
        page = baseMapper.getMatterRepairList(page, queryDto);
        List<SaasMatterRepairListVo> list = page.getRecords();
        List<SaasMatterRepairExcelVo> excelVoList = BeanUtil.copyProperties(list, SaasMatterRepairExcelVo.class);
        for (SaasMatterRepairExcelVo vo : excelVoList) {
            vo.setRepairStatusName(RepairStatusEnum.getDescByCode(vo.getRepairStatus()));
            vo.setRepairTypeName(repairTypeService.getById(vo.getRepairTypeId()).getName());
            vo.setWorkOrderStatusName(WorkOrderStatusEnum.getDescByCode(vo.getWorkOrderStatus()));
            vo.setRepairUserName(iOrgUserClient.detail(vo.getRepairUserId()).getData().getName());
            vo.setRepairAreaName(RepairAreaEnum.getDescByCode(vo.getRepairArea()));
            vo.setProjectName(pmgBatParkInfoService.getById(vo.getProjectId()).getParkName());
            vo.setHandleResultName(HandleResultEnum.getDescByCode(vo.getHandleResult()));
            vo.setConfirmResultName(ConfirmResultEnum.getDescByCode(vo.getConfirmResult()));
            vo.setBackUserName(iOrgUserClient.detail(vo.getBackUserId()).getData().getName());
            vo.setEvaluateLevelName(EvaluateLevelEnum.getDescByCode(vo.getEvaluateLevel()));
            vo.setAppName(applyManageFeignServer.getDetail(vo.getAppId()).getData().getName());
        }
        try {
            String fileName = URLEncoder.encode("报事报修表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), SaasMatterRepairExcelVo.class)
                    .sheet("报事报修表表")
                    .doWrite(excelVoList); //最终处理好的数据结果集list
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public List<PmgBatRepairAddressRecordVO> addressRecords(PmgBatRepairAddressRecordQueryDTO dto) {
        LambdaQueryWrapper<SaasMatterRepair> query = Wrappers.lambdaQuery();
        query.eq(SaasMatterRepair::getRepairUserId, dto.getRepairUserId());
        query.eq(SaasMatterRepair::getProjectId, dto.getProjectId());
        query.eq(Func.isNotEmpty(dto.getCustomerId()),SaasMatterRepair::getCustomerId, dto.getCustomerId());
        List<SaasMatterRepair> list = list(query);
        return list.stream()
                .filter(repair -> Func.isNotEmpty(repair.getRepairAddrIds())  && Func.isNotEmpty(repair.getRepairAddrNames()))
                .flatMap(repair -> {
                    String[] addrIds = repair.getRepairAddrIds().split(",");
                    String[] addrNames = repair.getRepairAddrNames().split(",");
                    return IntStream.range(0, addrIds.length)
                            .mapToObj(i -> {
                                PmgBatRepairAddressRecordVO pmgBatRepairAddressRecordVO = new PmgBatRepairAddressRecordVO();
                                pmgBatRepairAddressRecordVO.setRepairAddrId(Long.parseLong(addrIds[i].trim()));
                                pmgBatRepairAddressRecordVO.setRepairAddrName(addrNames[i].trim());
                                return pmgBatRepairAddressRecordVO;
                            });
                })
                .distinct()
                .collect(Collectors.toList());
    }

}
