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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
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.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gci.boot.annotation.Query.handle.QueryGenerator;
import com.gci.boot.common.util.ValidateUtil;
import com.gci.boot.common.validated.SaveValidated;
import com.gci.boot.exception.GciBootException;
import com.gci.boot.modules.basedata.entity.TbInspectionTemplate;
import com.gci.boot.modules.basedata.entity.TbInspectionTemplateProject;
import com.gci.boot.modules.basedata.entity.TbVehicle;
import com.gci.boot.modules.basedata.service.ITbInspectionTemplateProjectService;
import com.gci.boot.modules.basedata.service.ITbInspectionTemplateService;
import com.gci.boot.modules.basedata.service.ITbVehicleService;
import com.gci.boot.modules.customer.dto.VehicleDto;
import com.gci.boot.modules.customer.entity.TbInspectionTask;
import com.gci.boot.modules.customer.entity.TbInspectionTaskPart;
import com.gci.boot.modules.customer.entity.TbInspectionTaskProject;
import com.gci.boot.modules.customer.entity.TbInspectionTaskVehicle;
import com.gci.boot.modules.customer.mapper.TbInspectionTaskMapper;
import com.gci.boot.modules.customer.service.ITbInspectionTaskPartService;
import com.gci.boot.modules.customer.service.ITbInspectionTaskProjectService;
import com.gci.boot.modules.customer.service.ITbInspectionTaskService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gci.boot.modules.customer.service.ITbInspectionTaskVehicleService;
import com.gci.boot.modules.projects.entity.Projects;
import com.gci.boot.modules.projects.service.IProjectsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 巡检任务 服务实现类
 * </p>
 *
 * @author 2464
 * @since 2023-10-16
 */
@Service
public class TbInspectionTaskServiceImpl extends ServiceImpl<TbInspectionTaskMapper, TbInspectionTask> implements ITbInspectionTaskService {

    @Autowired
    private IProjectsService projectsService;
    @Autowired
    private ITbVehicleService vehicleService;
    @Autowired
    private ITbInspectionTemplateService inspectionTemplateService;
    @Autowired
    private ITbInspectionTemplateProjectService inspectionTemplateProjectService;
    @Autowired
    private ITbInspectionTaskProjectService inspectionTaskProjectService;
    @Autowired
    private ITbInspectionTaskVehicleService inspectionTaskVehicleService;
    @Autowired
    private ITbInspectionTaskPartService inspectionTaskPartService;
    @Autowired
    private TbInspectionTaskMapper inspectionTaskMapper;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void saveItem(TbInspectionTask tbInspectionTask) {
        List<String> projectList = checkProject(tbInspectionTask.getProjectIds());
        //1-线上巡检
        if ("1".equals(tbInspectionTask.getInspectionType())) {
            //非空的时候需要校验车辆
            if (ObjectUtil.isNotEmpty(tbInspectionTask.getVehicleList())) {
                checkVehicle(tbInspectionTask.getVehicleList(), projectList);
            }
        }
        checkTemplate(tbInspectionTask);
        if ("0".equals(tbInspectionTask.getInspectionResult())) {
            checkHandle(tbInspectionTask);
        }
        save(tbInspectionTask);
        //保存关联项目
        ArrayList<TbInspectionTaskProject> tbInspectionTaskProjects = new ArrayList<>();
        List<String> split = StrUtil.split(tbInspectionTask.getProjectIds(), StrUtil.COMMA);
        for (String s : split) {
            TbInspectionTaskProject tbInspectionTaskProject = new TbInspectionTaskProject();
            tbInspectionTaskProject.setProjectId(s);
            tbInspectionTaskProject.setInspectionTaskId(tbInspectionTask.getId());
            tbInspectionTaskProjects.add(tbInspectionTaskProject);
        }
        inspectionTaskProjectService.saveBatch(tbInspectionTaskProjects);
        //保存关联车辆
        if ("1".equals(tbInspectionTask.getInspectionType())) {
            if (ObjectUtil.isNotEmpty(tbInspectionTask.getVehicleList())) {
                ArrayList<TbInspectionTaskVehicle> tbInspectionTaskVehicles = new ArrayList<>();
                List<VehicleDto> vehicleList = tbInspectionTask.getVehicleList();
                for (VehicleDto vehicleDto : vehicleList) {
                    TbInspectionTaskVehicle vehicle = new TbInspectionTaskVehicle();
                    vehicle.setVehicleId(vehicleDto.getId());
                    vehicle.setInspectionTaskId(tbInspectionTask.getId());
                    vehicle.setIsNormal(vehicleDto.getIsNormal());
                    vehicle.setAbnormalMsg(vehicleDto.getAbnormalMsg());
                    tbInspectionTaskVehicles.add(vehicle);
                }
                inspectionTaskVehicleService.saveBatch(tbInspectionTaskVehicles);
            }
        }
        //保存巡检信息
        List<TbInspectionTaskPart> partList = tbInspectionTask.getPartList();
        partList.forEach(i -> i.setTaskId(tbInspectionTask.getId()));
        inspectionTaskPartService.saveBatch(partList);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateItem(TbInspectionTask tbInspectionTask) {
        TbInspectionTask byId = getById(tbInspectionTask.getId());
//        if (StrUtil.isNotBlank(byId.getInspectionResult())) {
//            if ("1".equals(byId.getInspectionResult())) {
//                throw new GciBootException("巡检结果为 合格 时不可删除！");
//            }
//        }
//        if (StrUtil.isNotBlank(byId.getHandleType())) {
//            if ("2".equals(byId.getHandleType())) {
//                throw new GciBootException("处理结果为 已完成 时不可删除！");
//            }
//        }
        tbInspectionTask.setInspectionType(byId.getInspectionType());
        tbInspectionTask.setInspectionTemplateId(byId.getInspectionTemplateId());
        List<String> projectList = checkProject(tbInspectionTask.getProjectIds());
        //1-线上巡检
        if ("1".equals(tbInspectionTask.getInspectionType())) {
            //非空的时候需要校验车辆
            if (ObjectUtil.isNotEmpty(tbInspectionTask.getVehicleList())) {
                checkVehicle(tbInspectionTask.getVehicleList(), projectList);
            }
        }
        checkTemplate(tbInspectionTask);
        if ("0".equals(tbInspectionTask.getInspectionResult())) {
            checkHandle(tbInspectionTask);
        }
        updateById(tbInspectionTask);
        //保存关联项目
        ArrayList<TbInspectionTaskProject> tbInspectionTaskProjects = new ArrayList<>();
        List<String> split = StrUtil.split(tbInspectionTask.getProjectIds(), StrUtil.COMMA);
        inspectionTaskProjectService.remove(new LambdaQueryWrapper<TbInspectionTaskProject>().eq(TbInspectionTaskProject::getInspectionTaskId, tbInspectionTask.getId()));
        for (String s : split) {
            TbInspectionTaskProject tbInspectionTaskProject = new TbInspectionTaskProject();
            tbInspectionTaskProject.setProjectId(s);
            tbInspectionTaskProject.setInspectionTaskId(tbInspectionTask.getId());
            tbInspectionTaskProjects.add(tbInspectionTaskProject);
        }
        inspectionTaskProjectService.saveBatch(tbInspectionTaskProjects);
        //保存关联车辆
        inspectionTaskVehicleService.remove(new LambdaQueryWrapper<TbInspectionTaskVehicle>().eq(TbInspectionTaskVehicle::getInspectionTaskId, tbInspectionTask.getId()));

        if (ObjectUtil.isNotEmpty(tbInspectionTask.getVehicleList())) {
            ArrayList<TbInspectionTaskVehicle> tbInspectionTaskVehicles = new ArrayList<>();
            List<VehicleDto> vehicleList = tbInspectionTask.getVehicleList();
            for (VehicleDto vehicleDto : vehicleList) {
                TbInspectionTaskVehicle vehicle = new TbInspectionTaskVehicle();
                vehicle.setVehicleId(vehicleDto.getId());
                vehicle.setInspectionTaskId(tbInspectionTask.getId());
                vehicle.setIsNormal(vehicleDto.getIsNormal());
                vehicle.setAbnormalMsg(vehicleDto.getAbnormalMsg());
                tbInspectionTaskVehicles.add(vehicle);
            }
            inspectionTaskVehicleService.saveBatch(tbInspectionTaskVehicles);
        }

        //保存巡检信息
        List<TbInspectionTaskPart> partList = tbInspectionTask.getPartList();
        partList.forEach(i -> i.setTaskId(tbInspectionTask.getId()));
        inspectionTaskPartService.updateBatchById(partList);
    }

    @Override
    public void saveItemFromFollow(TbInspectionTask tbInspectionTask) {
        String valid = ValidateUtil.valid(TbInspectionTask.class, SaveValidated.class);
        if (StrUtil.isNotBlank(valid)) {
            throw new GciBootException(valid);
        }
        if (StrUtil.isBlank(tbInspectionTask.getFollowId())) {
            throw new GciBootException("对应回访Id不能为空！");
        }
        checkProject(tbInspectionTask.getProjectIds());
        checkTemplate(tbInspectionTask);
        if ("0".equals(tbInspectionTask.getInspectionResult())) {
            checkHandle(tbInspectionTask);
        }
        save(tbInspectionTask);
        //保存关联项目
        ArrayList<TbInspectionTaskProject> tbInspectionTaskProjects = new ArrayList<>();
        List<String> split = StrUtil.split(tbInspectionTask.getProjectIds(), StrUtil.COMMA);
        for (String s : split) {
            TbInspectionTaskProject tbInspectionTaskProject = new TbInspectionTaskProject();
            tbInspectionTaskProject.setProjectId(s);
            tbInspectionTaskProject.setInspectionTaskId(tbInspectionTask.getId());
            tbInspectionTaskProjects.add(tbInspectionTaskProject);
        }
        inspectionTaskProjectService.saveBatch(tbInspectionTaskProjects);
        //保存关联车辆
        inspectionTaskVehicleService.remove(new LambdaQueryWrapper<TbInspectionTaskVehicle>().eq(TbInspectionTaskVehicle::getInspectionTaskId, tbInspectionTask.getId()));
        //保存关联车辆
        if (ObjectUtil.isNotEmpty(tbInspectionTask.getVehicleList())) {
            ArrayList<TbInspectionTaskVehicle> tbInspectionTaskVehicles = new ArrayList<>();
            List<VehicleDto> vehicleList = tbInspectionTask.getVehicleList();
            for (VehicleDto vehicleDto : vehicleList) {
                TbInspectionTaskVehicle vehicle = new TbInspectionTaskVehicle();
                vehicle.setVehicleId(vehicleDto.getId());
                vehicle.setInspectionTaskId(tbInspectionTask.getId());
                vehicle.setIsNormal(vehicleDto.getIsNormal());
                vehicle.setAbnormalMsg(vehicleDto.getAbnormalMsg());
                tbInspectionTaskVehicles.add(vehicle);
            }
            inspectionTaskVehicleService.saveBatch(tbInspectionTaskVehicles);
        }
        //保存巡检信息
        List<TbInspectionTaskPart> partList = tbInspectionTask.getPartList();
        partList.forEach(i -> i.setTaskId(tbInspectionTask.getId()));
        inspectionTaskPartService.saveBatch(partList);
    }

    @Override
    public IPage<TbInspectionTask> pageBuild(Page<TbInspectionTask> page, TbInspectionTask inspectionTask) {
        LambdaQueryWrapper<TbInspectionTask> lambdaQueryWrapper = QueryGenerator.initQueryWrapper(TbInspectionTask.class, inspectionTask);
        IPage<TbInspectionTask> taskPage = inspectionTaskMapper.pageBuild(page, lambdaQueryWrapper);
        for (TbInspectionTask record : taskPage.getRecords()) {
            fillInspectionTask(record);
        }
        return taskPage;
    }

    @Override
    public void removeItem(String id) {
        TbInspectionTask byId = getById(id);
//        if (StrUtil.isNotBlank(byId.getInspectionResult())) {
//            if ("1".equals(byId.getInspectionResult())) {
//                throw new GciBootException("巡检结果为 合格 时不可删除！");
//            }
//        }
//        if (StrUtil.isNotBlank(byId.getHandleType())) {
//            if ("2".equals(byId.getHandleType())) {
//                throw new GciBootException("处理结果为 已完成 时不可删除！");
//            }
//        }
        removeById(id);
        inspectionTaskProjectService.remove(new LambdaQueryWrapper<TbInspectionTaskProject>().eq(TbInspectionTaskProject::getInspectionTaskId, id));
        inspectionTaskVehicleService.remove(new LambdaQueryWrapper<TbInspectionTaskVehicle>().eq(TbInspectionTaskVehicle::getInspectionTaskId, id));
        inspectionTaskPartService.remove(new LambdaQueryWrapper<TbInspectionTaskPart>().eq(TbInspectionTaskPart::getTaskId, id));
    }

    @Override
    public TbInspectionTask getItemById(String id) {
        TbInspectionTask inspectionTask = inspectionTaskMapper.getItemById(id);
        if (BeanUtil.isEmpty(inspectionTask)) {
            throw new GciBootException("删除失败，id错误！");
        }
        fillInspectionTask(inspectionTask);
        return inspectionTask;
    }

    /**
     * 补充数据
     *
     * @param record
     */
    private void fillInspectionTask(TbInspectionTask record) {
        if (StrUtil.isNotBlank(record.getVehicleIds())) {
            List<TbVehicle> vehicleList = vehicleService.list(new LambdaQueryWrapper<TbVehicle>().in(TbVehicle::getId, StrUtil.split(record.getVehicleIds(), StrUtil.COMMA)).orderByDesc(TbVehicle::getCreateTime));
            ArrayList<VehicleDto> vehicleDtos = buildVehicleDtos(record, vehicleList);
            record.setVehicleList(vehicleDtos);
        }
        List<TbInspectionTaskPart> partList = inspectionTaskPartService.list(new LambdaQueryWrapper<TbInspectionTaskPart>().eq(TbInspectionTaskPart::getTaskId, record.getId()).orderByAsc(TbInspectionTaskPart::getSort));
        record.setPartList(partList);
    }

    /**
     * 构建实体类
     *
     * @param record
     * @param vehicleList
     * @return
     */
    private ArrayList<VehicleDto> buildVehicleDtos(TbInspectionTask record, List<TbVehicle> vehicleList) {
        ArrayList<VehicleDto> vehicleDtos = new ArrayList<>();
        List<TbInspectionTaskVehicle> list = inspectionTaskVehicleService.list(new LambdaQueryWrapper<TbInspectionTaskVehicle>().eq(TbInspectionTaskVehicle::getInspectionTaskId, record.getId()));
        for (TbInspectionTaskVehicle taskVehicle : list) {
            TbVehicle tbVehicle = vehicleList.stream().filter(i -> i.getId().equals(taskVehicle.getVehicleId())).findFirst().orElse(null);
            if (tbVehicle != null) {
                VehicleDto vehicleDto = new VehicleDto();
                vehicleDto.setId(tbVehicle.getId());
                vehicleDto.setVehicleBrand(tbVehicle.getVehicleBrand());
                vehicleDto.setVehicleModel(tbVehicle.getVehicleModel());
                vehicleDto.setVehicleType(tbVehicle.getVehicleType());
                vehicleDto.setFrameNumber(tbVehicle.getFrameNumber());
                vehicleDto.setPlateNumber(tbVehicle.getPlateNumber());
                vehicleDto.setIsNormal(taskVehicle.getIsNormal());
                vehicleDto.setAbnormalMsg(taskVehicle.getAbnormalMsg());
                vehicleDtos.add(vehicleDto);
            }
        }
        return vehicleDtos;
    }

    /**
     * 不合格时校验处理信息
     *
     * @param tbInspectionTask
     */
    private void checkHandle(TbInspectionTask tbInspectionTask) {
        if (StrUtil.isBlank(tbInspectionTask.getHandlePlan())) {
            throw new GciBootException("处理方案不能为空！");
        } else if (tbInspectionTask.getHandlePlan().length() > 500) {
            throw new GciBootException("处理方案不能超过500字符！");
        }
        if (StrUtil.isBlank(tbInspectionTask.getHandleType())) {
            throw new GciBootException("处理结果不能为空！");
        }
        if (ObjectUtil.isNull(tbInspectionTask.getHandleTime())) {
            throw new GciBootException("处理时间不能为空！");
        }
    }

    /**
     * 校验模板
     *
     * @param tbInspectionTask
     */
    private void checkTemplate(TbInspectionTask tbInspectionTask) {
        TbInspectionTemplate byId = inspectionTemplateService.getById(tbInspectionTask.getInspectionTemplateId());
        if (BeanUtil.isEmpty(byId)) {
            throw new GciBootException("巡检模板id错误！");
        }
        List<TbInspectionTemplateProject> list = inspectionTemplateProjectService.list(new LambdaQueryWrapper<TbInspectionTemplateProject>().eq(TbInspectionTemplateProject::getTemplateId, byId.getId()));
        List<TbInspectionTaskPart> partList = tbInspectionTask.getPartList();
        if (list.size() == partList.size()) {
            List<String> collect = list.stream().map(i -> i.getContent() + "-" + i.getName()).collect(Collectors.toList());
            List<String> collect1 = partList.stream().map(i -> i.getContent() + "-" + i.getName()).collect(Collectors.toList());
            if (CollUtil.intersection(collect, collect1).size() != collect.size()) {
                throw new GciBootException("模板信息不匹配！");
            }
        } else {
            throw new GciBootException("缺少对应巡检信息！");
        }
    }

    /**
     * 校验车辆
     *
     * @param vehicleDtoList
     * @param projectList
     */
    private void checkVehicle(List<VehicleDto> vehicleDtoList, List<String> projectList) {
        List<String> split = vehicleDtoList.stream().map(VehicleDto::getId).distinct().collect(Collectors.toList());
        if (split.size() < vehicleDtoList.size()) {
            throw new GciBootException("车辆不能重复！");
        }
        List<TbVehicle> list = vehicleService.list(new LambdaQueryWrapper<TbVehicle>().in(TbVehicle::getId, split));
        if (split.size() != list.size()) {
            throw new GciBootException("错误车辆Id！");
        }
        for (TbVehicle tbVehicle : list) {
            if (!projectList.contains(tbVehicle.getProjectId())) {
                throw new GciBootException("车辆与项目Id不对应！");
            }
        }
    }

    /**
     * 校验项目
     *
     * @param projectIds
     */
    private List<String> checkProject(String projectIds) {
        List<String> split = StrUtil.split(projectIds, StrUtil.COMMA);
        if (split.size() > 1) {
            throw new GciBootException("只能选择一个项目！");
        }
        List<Projects> list = projectsService.list(new LambdaQueryWrapper<Projects>().in(Projects::getId, split));
        if (list.size() != split.size()) {
            throw new GciBootException("错误项目Id！");
        }
        return split;
    }
}
