package com.gci.boot.modules.vehicles.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
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.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gci.boot.common.util.ValidateUtil;
import com.gci.boot.common.validated.SaveValidated;
import com.gci.boot.constant.CommonConstant;
import com.gci.boot.exception.GciBootException;
import com.gci.boot.modules.basedata.entity.TbVehicle;
import com.gci.boot.modules.basedata.service.ITbVehicleService;
import com.gci.boot.modules.msg.enums.SenderTypeEnum;
import com.gci.boot.modules.msg.enums.WorkOrderType;
import com.gci.boot.modules.msg.service.MsgPushService;
import com.gci.boot.modules.msg.vo.MsgRedisVO;
import com.gci.boot.modules.projects.entity.Projects;
import com.gci.boot.modules.projects.service.IProjectsService;
import com.gci.boot.modules.vehicles.entity.TbAccidentInfo;
import com.gci.boot.modules.vehicles.entity.TbAccidentInsuranceInfo;
import com.gci.boot.modules.vehicles.entity.TbAccidentProgress;
import com.gci.boot.modules.vehicles.entity.TbInsuranceRecord;
import com.gci.boot.modules.vehicles.mapper.TbAccidentInfoMapper;
import com.gci.boot.modules.vehicles.query.AccidentInfoQuery;
import com.gci.boot.modules.vehicles.service.ITbAccidentInfoService;
import com.gci.boot.modules.vehicles.service.ITbAccidentInsuranceInfoService;
import com.gci.boot.modules.vehicles.service.ITbAccidentProgressService;
import com.gci.boot.modules.vehicles.service.ITbInsuranceRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 事故信息基础表 服务实现类
 * </p>
 *
 * @author 2464
 * @since 2023-09-13
 */
@Service
public class TbAccidentInfoServiceImpl extends ServiceImpl<TbAccidentInfoMapper, TbAccidentInfo> implements ITbAccidentInfoService {

    @Autowired
    private TbAccidentInfoMapper accidentInfoMapper;
    @Autowired
    private ITbAccidentInsuranceInfoService accidentInsuranceInfoService;
    @Autowired
    private ITbAccidentProgressService accidentProgressService;
    @Autowired
    private ITbInsuranceRecordService insuranceRecordService;
    @Autowired
    private ITbVehicleService vehicleService;
    @Autowired
    private MsgPushService msgPushService;
    @Autowired
    private IProjectsService projectsService;

    @Override
    public IPage<TbAccidentInfo> pageBuild(Page<TbAccidentInfo> page, AccidentInfoQuery query) {
        List<Date> accidentTime = query.getAccidentTime();
        List<Date> closingTime = query.getClosingTime();
        if (ObjectUtil.isNotEmpty(accidentTime)) {
            if (accidentTime.size() != 2) {
                throw new GciBootException("事故发生时间必须包含起止时间！");
            }
        }
        if (ObjectUtil.isNotEmpty(closingTime)) {
            if (closingTime.size() != 2) {
                throw new GciBootException("结案时间必须包含起止时间！");
            }
        }
        QueryWrapper<TbAccidentInfo> accidentInfoQueryWrapper = new QueryWrapper<>();
        accidentInfoQueryWrapper.eq(StrUtil.isNotBlank(query.getProjectId()), "tai.project_id", query.getProjectId())
                .in(StrUtil.isNotBlank(query.getPlateNumber()), "tai.plate_number", StrUtil.split(query.getPlateNumber(),StrUtil.COMMA))
                .eq(StrUtil.isNotBlank(query.getLiabilityConfirm()), "taii.liability_confirm", query.getLiabilityConfirm())
                .eq(StrUtil.isNotBlank(query.getNatureConfirm()), "taii.nature_confirm", query.getNatureConfirm());
        if (ObjectUtil.isNotEmpty(accidentTime)) {
            accidentInfoQueryWrapper.between(ObjectUtil.isNotEmpty(accidentTime), "tai.accident_time", accidentTime.get(0), accidentTime.get(1));
        }
        if (ObjectUtil.isNotEmpty(closingTime)) {
            accidentInfoQueryWrapper.between(ObjectUtil.isNotEmpty(closingTime), "tap.closing_time", closingTime.get(0), closingTime.get(1));
        }
        if (ObjectUtil.isNotEmpty(query.getCaseClosed())) {
            if ("1".equals(query.getCaseClosed())) {
                accidentInfoQueryWrapper.eq("tap.case_closed",query.getCaseClosed());
            } else {
                accidentInfoQueryWrapper.and(i->i.eq("tap.case_closed",query.getCaseClosed())
                        .or().isNull("tap.case_closed"));
            }
        }
        if (ObjectUtil.isNotEmpty(query.getIsRecord())) {
            accidentInfoQueryWrapper.eq("taii.is_record",query.getIsRecord());
        }
        IPage<TbAccidentInfo> pagebuild = accidentInfoMapper.pageBuild(page, accidentInfoQueryWrapper);
        if (ObjectUtil.isNotEmpty(pagebuild.getRecords())) {
            for (TbAccidentInfo record : pagebuild.getRecords()) {
                if (StrUtil.isNotBlank(record.getAccidentLossType())) {
                    List<String> split = StrUtil.split(record.getAccidentLossType(), StrUtil.COMMA);
                    record.setAccidentLossTypeList(split);
                }
            }
        }
        return pagebuild;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void saveItem(TbAccidentInfo tbAccidentInfo) {
        if (ObjectUtil.isEmpty(tbAccidentInfo.getAccidentLossTypeList())) {
            tbAccidentInfo.setAccidentLossType("");
        } else {
            tbAccidentInfo.setAccidentLossType(StrUtil.join(StrUtil.COMMA,tbAccidentInfo.getAccidentLossTypeList()));
        }
        save(tbAccidentInfo);
        TbAccidentInsuranceInfo accidentInsuranceInfo = tbAccidentInfo.getAccidentInsuranceInfo();
        TbAccidentProgress accidentProgress = tbAccidentInfo.getAccidentProgress();
        if (BeanUtil.isNotEmpty(accidentInsuranceInfo)) {
            accidentInsuranceInfo.setInfoId(tbAccidentInfo.getId());
            if (accidentInsuranceInfo.getIsRecord().equals(CommonConstant.YES)) {
                extracted(tbAccidentInfo, accidentInsuranceInfo, accidentProgress);
            }
            accidentInsuranceInfoService.save(accidentInsuranceInfo);
        }
        if (BeanUtil.isNotEmpty(accidentProgress)) {
            accidentProgress.setInfoId(tbAccidentInfo.getId());
            accidentProgressService.save(accidentProgress);
        }
        //微信消息推送 -- 案件进度为空或者没结案
        if(!(BeanUtil.isNotEmpty(accidentProgress) && CommonConstant.YES.equals(accidentProgress.getCaseClosed()))){
            //推送微信消息
            ThreadUtil.execAsync(()->{
                Projects projects = projectsService.getById(tbAccidentInfo.getProjectId());
                msgPushService.pushMsgToRedis(new MsgRedisVO(
                        SenderTypeEnum.YYWB.getSendType() +","+SenderTypeEnum.CUSTOMER.getSendType(),tbAccidentInfo.getId(),
                        tbAccidentInfo.getProjectId(), WorkOrderType.ACCIDENT.getType(),"未结案",
                        DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss"),projects.getProjectName() + "新增事故，请及时查看"));
            });
        }
    }

    private void extracted(TbAccidentInfo tbAccidentInfo, TbAccidentInsuranceInfo accidentInsuranceInfo, TbAccidentProgress accidentProgress) {
        TbInsuranceRecord tbInsuranceRecord = new TbInsuranceRecord();
        BeanUtil.copyProperties(accidentInsuranceInfo,tbInsuranceRecord);
        TbInsuranceRecord r = insuranceRecordService.getOne(new LambdaQueryWrapper<TbInsuranceRecord>().eq(TbInsuranceRecord::getInfoId, tbAccidentInfo.getId()).or().eq(TbInsuranceRecord::getInsuranceNo,tbAccidentInfo.getReportNumber()));
        if (BeanUtil.isNotEmpty(r)) {
            tbInsuranceRecord.setId(r.getId());
        } else {
            tbInsuranceRecord.setId(null);
        }

        TbVehicle one = vehicleService.getOne(new LambdaQueryWrapper<TbVehicle>().eq(TbVehicle::getPlateNumber, tbAccidentInfo.getPlateNumber()));
        if (BeanUtil.isEmpty(one)) {
            throw new GciBootException("车牌号错误！");
        } else {
            tbInsuranceRecord.setVehicleId(one.getId());
            tbInsuranceRecord.setVehicleType(one.getVehicleType());
            tbInsuranceRecord.setProjectId(one.getProjectId());
        }
        tbInsuranceRecord.setHandleUser(tbAccidentInfo.getProcessedPerson());
        tbInsuranceRecord.setHandleStatus(CommonConstant.YES);
        tbInsuranceRecord.setInsuranceNo(tbAccidentInfo.getReportNumber());
        tbInsuranceRecord.setInsurancePrice(accidentInsuranceInfo.getTotalAmountActuallyIncurred());

        if (StrUtil.isNotBlank(accidentInsuranceInfo.getDocumentImage())) {
            tbInsuranceRecord.setCompensateUrl(accidentInsuranceInfo.getDocumentImage());
        }
        if (BeanUtil.isNotEmpty(accidentProgress)) {
            if (StrUtil.isNotBlank(accidentProgress.getAccidentCertificatePhoto())) {
                tbInsuranceRecord.setAccidentUrl(accidentProgress.getAccidentCertificatePhoto());
            }
            if (StrUtil.isNotBlank(accidentProgress.getCompensationAgreementPhoto())) {
                tbInsuranceRecord.setCompensateAgreementUrl(accidentProgress.getAccidentCertificatePhoto());
            }
            if (StrUtil.isNotBlank(accidentProgress.getLossAssessmentPhoto())) {
                tbInsuranceRecord.setLossAssessmentUrl(accidentProgress.getLossAssessmentPhoto());
            }
            if (StrUtil.isNotBlank(accidentProgress.getOtherPhoto())) {
                tbInsuranceRecord.setOtherUrl(accidentProgress.getOtherPhoto());
            }
        }
        String valid = ValidateUtil.valid(tbInsuranceRecord, SaveValidated.class);
        if (StrUtil.isNotBlank(valid)) {
            throw new GciBootException(valid);
        }
        if (StrUtil.isBlank(tbInsuranceRecord.getId())) {
            insuranceRecordService.save(tbInsuranceRecord);
        } else {
            insuranceRecordService.updateById(tbInsuranceRecord);
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateItem(TbAccidentInfo tbAccidentInfo) {
        if (ObjectUtil.isEmpty(tbAccidentInfo.getAccidentLossTypeList())) {
            tbAccidentInfo.setAccidentLossType("");
        } else {
            tbAccidentInfo.setAccidentLossType(StrUtil.join(StrUtil.COMMA,tbAccidentInfo.getAccidentLossTypeList()));
        }
        updateById(tbAccidentInfo);
        TbAccidentInsuranceInfo accidentInsuranceInfo = tbAccidentInfo.getAccidentInsuranceInfo();
        TbAccidentProgress accidentProgress = tbAccidentInfo.getAccidentProgress();
        if (BeanUtil.isNotEmpty(accidentInsuranceInfo)) {
            accidentInsuranceInfo.setInfoId(tbAccidentInfo.getId());
            if (StrUtil.isNotBlank(accidentInsuranceInfo.getId())) {
                TbAccidentInsuranceInfo byId = accidentInsuranceInfoService.getById(accidentInsuranceInfo.getId());
                if (accidentInsuranceInfo.getIsRecord().equals(CommonConstant.YES) || byId.getIsRecord().equals(CommonConstant.YES)) {
                    accidentInsuranceInfo.setIsRecord(CommonConstant.YES);
                    extracted(tbAccidentInfo, accidentInsuranceInfo, accidentProgress);
                }
                accidentInsuranceInfoService.updateById(accidentInsuranceInfo);
            } else {
                if (accidentInsuranceInfo.getIsRecord().equals(CommonConstant.YES)) {
                    extracted(tbAccidentInfo, accidentInsuranceInfo, accidentProgress);
                }
                accidentInsuranceInfoService.save(accidentInsuranceInfo);
            }
        }
        if (BeanUtil.isNotEmpty(accidentProgress)) {
            accidentProgress.setInfoId(tbAccidentInfo.getId());
            if (StrUtil.isNotBlank(accidentProgress.getId())) {
                accidentProgressService.updateById(accidentProgress);
            } else {
                accidentProgressService.save(accidentProgress);
            }
        }
    }

    @Override
    public void removeItem(String id) {
        removeById(id);
        accidentInsuranceInfoService.remove(new LambdaQueryWrapper<TbAccidentInsuranceInfo>().eq(TbAccidentInsuranceInfo::getInfoId,id));
        accidentProgressService.remove(new LambdaQueryWrapper<TbAccidentProgress>().eq(TbAccidentProgress::getInfoId,id));
    }

    @Override
    public TbAccidentInfo getItemById(String id) {
        return accidentInfoMapper.getItemById(id);
    }
}
