package com.sckw.fleet.service;

import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.exception.SystemException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.utils.BeanUtils;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.web.constant.HttpStatus;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.core.web.response.HttpResult;
import com.sckw.fleet.dao.*;
import com.sckw.fleet.model.*;
import com.sckw.fleet.model.dto.*;
import com.sckw.fleet.model.vo.KwfTableTopCount;
import com.sckw.fleet.model.vo.KwfTruckVo;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.EntCacheResDto;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import com.sckw.system.api.model.dto.res.UserCacheResDto;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zk
 * @desc 车辆
 * @date 2023/7/6 0006
 */
@Service
public class KwfTruckService {

    @Autowired
    KwfTruckMapper truckDao;
    @Autowired
    KwfTruckEntMapper truckEntDao;
    @Autowired
    KwfTruckLicenseMapper truckLicenseDao;
    @Autowired
    KwfTransportLicenseMapper transportLicenseDao;
    @Autowired
    KwfFleetTruckMapper fleetTruckDao;
    @DubboReference(version = "2.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;

    /**
     * @param key 主键id
     * @desc 根据主键查询
     * @author zk
     * @date 2023/7/6
     **/
    public KwfTruck selectByKey(Long key) {
        return truckDao.selectById(key);
    }

    /**
     * @param params 参数
     * @desc 统计
     * @author zk
     * @date 2023/7/11
     **/
    public Map statistics(Map<String, Object> params) {
        /**统计数据**/
        List<KwfTableTopCount> counts = truckDao.statistics(params);
        long tatol = 0;
        for (KwfTableTopCount topCount:counts) {
            tatol += topCount.getTotal();
        }

        /**全部数据-处理**/
        List<KwfTableTopCount> countList = new ArrayList();
        KwfTableTopCount allCount = new KwfTableTopCount();
        allCount.setValue(String.valueOf(Global.NUMERICAL_ZERO));
        allCount.setTotal(tatol);
        allCount.setName("全部");
        countList.add(allCount);

        /**数据处理**/
        Map<String, Integer> statusMap = new HashMap(){{put("正常", 1); put("临时", 2); put("异常", 3);}};
        for(Map.Entry<String, Integer> entry:statusMap.entrySet()){
            System.out.println(entry.getKey()+"--->"+entry.getValue());
            KwfTableTopCount count = new KwfTableTopCount();
            for (KwfTableTopCount topCount:counts) {
                if (Integer.parseInt(topCount.getValue()) == entry.getValue()) {
                    BeanUtils.copyProperties(topCount, count);
                }
            }
            count.setName(entry.getKey());
            count.setValue(String.valueOf(entry.getValue()));
            countList.add(count);
        }

        /**数据组装**/
        Map tableCount = new HashMap();
        tableCount.put("tableTop", countList);
        tableCount.put("tableBottom", tatol);
        return tableCount;
    }

    /**
     * @param params 分页参数
     * @desc 分页查询
     * @author zk
     * @date 2023/7/6
     **/
    public List<KwfTruckVo> findPage(Map<String, Object> params) {
        /**查询分页数据**/
        List<KwfTruckVo> trucks = truckDao.findPage(params);
        if (CollectionUtils.isEmpty(trucks)) {
            return trucks;
        }

        /**获取查询数据**/
        String pound = Global.POUND;
        List<Long> createBys = new ArrayList<>();
        List<Long> entIds = new ArrayList<>();
        List<String> dictKey = new ArrayList<>();

        for (KwfTruckVo truck:trucks) {
            createBys.add(Long.parseLong(truck.getCreateBy()));
            entIds.add(Long.parseLong(truck.getEntId()));
            dictKey.add(DictTypeEnum.COLOR_TYPE.getType() + pound + truck.getColor());
            dictKey.add(DictTypeEnum.TRUCK_TYPE.getType() + pound + truck.getType());
            dictKey.add(DictTypeEnum.USE_TYPE.getType() + pound + truck.getUseType());
            dictKey.add(DictTypeEnum.ENERGY_TYPE.getType() + pound + truck.getEnergyType());
        }
        //用户数据集
        createBys = createBys.stream().distinct().collect(Collectors.toList());
        Map<Long, UserCacheResDto> users = remoteSystemService.queryUserCacheMapByIds(createBys);
        //企业数据集
        entIds = entIds.stream().distinct().collect(Collectors.toList());
        Map<Long, EntCacheResDto> ents = remoteSystemService.queryEntCacheMapByIds(entIds);
        //数据字典
        dictKey = dictKey.stream().distinct().collect(Collectors.toList());
        Map<String, SysDictResDto> dicts = remoteSystemService.queryDictMapByTypeValues(String.join(",", dictKey));

        /**数据组装**/
        for (KwfTruckVo truck:trucks) {
            UserCacheResDto user = users == null ? null : users.get(Long.parseLong(truck.getCreateBy()));
            EntCacheResDto ent = ents == null ? null : ents.get(Long.parseLong(truck.getEntId()));
            SysDictResDto color = dicts == null ? null : dicts.get(DictTypeEnum.COLOR_TYPE.getType() + pound + truck.getColor());
            SysDictResDto type = dicts == null ? null : dicts.get(DictTypeEnum.TRUCK_TYPE.getType() + pound + truck.getType());
            SysDictResDto useType = dicts == null ? null : dicts.get(DictTypeEnum.USE_TYPE.getType() + pound + truck.getUseType());
            SysDictResDto energyType = dicts == null ? null : dicts.get(DictTypeEnum.ENERGY_TYPE.getType() + pound + truck.getEnergyType());
            truck.setCreateByName(user != null ? user.getName() : null);
            truck.setFirmName(ent != null ? ent.getFirmName() : null);
            truck.setColorName(color != null ? color.getLabel() : null);
            truck.setTruckTypeName(type != null ? type.getLabel() : null);
            truck.setUseTypeName(useType != null ? useType.getLabel() : null);
            truck.setEnergyTypeName(energyType != null ? energyType.getLabel() : null);
        }
        return trucks;
    }

    /**
     * @param params 查询参数
     * @desc 查询
     * @author zk
     * @date 2023/7/6
     **/
    public List<Map<String, Object>> findList(Map<String, Object> params) {
        return truckDao.findList(params);
    }

    /**
     * @param {}
     * @description 导出
     * @author zk
     * @date 2023/07/11
     **/
    public HttpResult importExcel(MultipartFile file) {
        return null;
    }

    /**
     * @param params 参数
     * @desc 新增车辆
     * @author zk
     * @date 2023/7/6
     **/
    public HttpResult add(KwfTruckDto params) {
        /**车辆信息**/
        KwfTruck truck = new KwfTruck();
        BeanUtils.copyProperties(params, truck);
        //证件都有数据则为已认证(前端校验认证数据必填)
        boolean bool = checkLicense(params);
        if (bool) {
            truck.setStatus(Global.NUMERICAL_ONE);
        } else {
            truck.setStatus(Global.NUMERICAL_TWO);
        }
        HttpResult result = truckEdit(truck);
        if (result.getCode() != HttpStatus.SUCCESS_CODE) {
            return result;
        }

        /**车辆行驶证信息**/
        KwfTruckLicenseDto truckLicenseDto = params.getTruckLicense();
        if (truckLicenseDto != null) {
            truckLicenseDto.setTruckId(truck.getId());
            truckLicenseEdit(truckLicenseDto);
        }

        /**车辆行驶证信息**/
        KwfTransportLicenseDto transportLicenseDto = params.getTransportLicense();
        if (transportLicenseDto != null) {
            transportLicenseDto.setTruckId(truck.getId());
            transportLicenseEdit(transportLicenseDto);
        }

        /**车辆信息与企业关联信息**/
        truckEntEdit(truck);

        /**车队班组绑定**/
        truckFleetEdit(truck.getId(), params.getFleetId());

        return HttpResult.ok("车辆信息新增成功！", truck);
    }

    /**
     * @param params 参数
     * @desc 修改车辆
     * @author zk
     * @date 2023/7/6
     **/
    public HttpResult update(KwfTruckDto params) {
        /**数据校验**/
        if (StringUtils.isBlank(params.getId())) {
            return HttpResult.error(HttpStatus.PARAMETERS_PATTERN_ERROR_CODE,"车辆信息ID不能为空！");
        }
        KwfTruck truck = truckDao.selectById(params.getId());
        if (truck == null) {
            return HttpResult.error("车辆信息不存在！");
        }

        /**车辆信息**/
        BeanUtils.copyProperties(params, truck);
        //证件都有数据则为已认证(前端校验认证数据必填)
        boolean bool = checkLicense(params);
        if (bool) {
            truck.setStatus(Global.NUMERICAL_ONE);
        }
        HttpResult result = truckEdit(truck);
        if (result.getCode() != HttpStatus.SUCCESS_CODE) {
            return result;
        }

        /**车辆行驶证信息**/
        KwfTruckLicenseDto truckLicenseDto = params.getTruckLicense();
        if (truckLicenseDto != null) {
            truckLicenseDto.setTruckId(truck.getId());
            truckLicenseEdit(truckLicenseDto);
        }

        /**车辆行驶证信息**/
        KwfTransportLicenseDto transportLicenseDto = params.getTransportLicense();
        if (transportLicenseDto != null) {
            transportLicenseDto.setTruckId(truck.getId());
            transportLicenseEdit(transportLicenseDto);
        }

        /**车队班组绑定**/
        truckFleetEdit(truck.getId(), params.getFleetId());
        return HttpResult.ok("车辆信息修改成功！");
    }

    /**
     * @param {ids：主键ID（多个以逗号隔开）}
     * @description 删除
     * @author zk
     * @date 2023/7/6
     **/
    public HttpResult del(String ids) {
        /**数据校验**/
        if (StringUtils.isBlank(ids)) {
            return HttpResult.error("请选择要删除的数据！");
        }

        /**数据组装**/
        String[] idArray = ids.split(",");
        KwfTruckEnt truckEntQuery = new KwfTruckEnt();
        truckEntQuery.setEntId(LoginUserHolder.getEntId());
        for (String id : idArray) {
            truckEntQuery.setTruckId(Long.parseLong(id));
            KwfTruckEnt truckEnt = truckEntDao.findByTruckEnt(truckEntQuery);
            if (truckEnt != null) {
                truckEnt.setDelFlag(Global.YES);
                if (truckEntDao.updateById(truckEnt) <= 0) {
                    throw new SystemException(HttpStatus.CRUD_FAIL_CODE, HttpStatus.DELETE_FAIL);
                }
            } else {
                return HttpResult.error("选择删除的数据已不存在！");
            }
        }
        return HttpResult.ok("删除成功！");
    }

    /**
     * @param params 参数
     * @desc 更新车辆信息
     * @author zk
     * @date 2023/7/7
     **/
    public HttpResult truckEdit(KwfTruck params) {
        if (StringUtils.isBlank(params.getId())) {
            /**唯一性交易**/
            List<Map<String, Object>> trucks = truckDao.findList(new HashMap(){{ put("truckNo", params.getTruckNo()); }});
            if (!CollectionUtils.isEmpty(trucks)) {
                return HttpResult.error("车牌号已存在！");
            }

            /**新增**/
            params.setEntId(LoginUserHolder.getEntId());
            params.setEntId(params.getEntId() == null ? 1 : params.getEntId());// 暂时处理---------------zk
            int count = truckDao.insert(params);
            return count > 0 ? HttpResult.ok() : HttpResult.error("车辆信息新增失败！");
        } else {
            /**唯一性交易**/
            List<Map<String, Object>> trucks = truckDao.findList(new HashMap(){{ put("truckNo", params.getTruckNo()); }});
            //校验list中对象key值是否存在与value不一致的情况
            boolean bool = CollectionUtils.listByKeyValueV1(trucks, "id", String.valueOf(params.getId()));
            if (bool) {
                return HttpResult.error("车牌号已存在！");
            }

            /**更新**/
            int count = truckDao.updateById(params);
            return count > 0 ? HttpResult.ok() : HttpResult.error("车辆信息修改失败！");
        }
    }

    /**
     * @param params 参数
     * @desc 更新车辆行驶证信息
     * @author zk
     * @date 2023/7/7
     **/
    public HttpResult truckLicenseEdit(KwfTruckLicenseDto params) {
        /**数据copy**/
        KwfTruckLicense truckLicense = new KwfTruckLicense();
        BeanUtils.copyProperties(params, truckLicense);

        /**数据更新**/
        int count = 0;
        KwfTruckLicense license = truckLicenseDao.findByTruckId(params.getTruckId());
        if (license == null) {
            count = truckLicenseDao.insert(truckLicense);
        } else {
            truckLicense.setId(license.getId());
            count = truckLicenseDao.updateById(truckLicense);
        }

        /**校验车辆是否有证书并更新状态**/
        checkLicense(truckLicense.getId());
        return count > 0 ? HttpResult.ok("车辆行驶证信息修改成功！") : HttpResult.error("车辆行驶证信息修改失败！");
    }

    /**
     * @param key 参数
     * @desc 查询车辆行驶证信息
     * @author zk
     * @date 2023/7/7
     **/
    public KwfTruckLicense findTruckLicenseByKey(Long key) {
        return truckLicenseDao.findByTruckId(key);
    }

    /**
     * @param params 参数
     * @desc 更新车辆道路运输许可证
     * @author zk
     * @date 2023/7/7
     **/
    public HttpResult transportLicenseEdit(KwfTransportLicenseDto params) {
        /**数据copy**/
        KwfTransportLicense transportLicense = new KwfTransportLicense();
        BeanUtils.copyProperties(params, transportLicense);

        /**数据更新**/
        int count = 0;
        KwfTransportLicense license = transportLicenseDao.findByTruckId(params.getTruckId());
        if (license == null) {
            count = transportLicenseDao.insert(transportLicense);
            return count > 0 ? HttpResult.ok("车辆驾驶证信息更新成功！") : HttpResult.error("车辆驾驶证信息更新失败！");
        } else {
            transportLicense.setId(license.getId());
            count = transportLicenseDao.updateById(transportLicense);
        }

        /**校验车辆是否有证书并更新状态**/
        checkLicense(transportLicense.getTruckId());
        return count > 0 ? HttpResult.ok("车辆驾驶证信息修改成功！") : HttpResult.error("车辆驾驶证信息修改失败！");
    }

    /**
     * @param key 参数
     * @desc 查询车辆道路运输许可证
     * @author zk
     * @date 2023/7/7
     **/
    public KwfTransportLicense findTransportLicenseByKey(Long key) {
        return transportLicenseDao.findByTruckId(key);
    }

    /**
     * @param params 参数
     * @desc 新增车辆信息与企业关联信息
     * @author zk
     * @date 2023/7/7
     **/
    public void truckEntEdit(KwfTruck params) {
        KwfTruckEnt truckEnt = new KwfTruckEnt();
        truckEnt.setTruckId(params.getId());
        truckEnt.setEntId(params.getEntId());
        KwfTruckEnt ent = truckEntDao.findByTruckEnt(truckEnt);
        if (ent == null) {
            truckEntDao.insert(truckEnt);
        }
    }

    /**
     * @param truckId 车辆档案主键id fleetId 车队班组主键id
     * @desc 车队班组绑定
     * @author zk
     * @date 2023/7/7
     **/
    public HttpResult truckFleetEdit(Long truckId, Long fleetId) {
        /**数据校验**/
        if (fleetId == null) {
            return HttpResult.ok("未选择车队班组！");
        }
        KwfFleetTruck queryFleetTruck = new KwfFleetTruck();
        queryFleetTruck.setEntId(LoginUserHolder.getEntId());
        queryFleetTruck.setTruckId(truckId);
        KwfFleetTruck fleetTruck = fleetTruckDao.findByTruckFleet(queryFleetTruck);

        /**数据更新**/
        queryFleetTruck.setFleetId(fleetId);
        if (fleetTruck == null) {
            int count = fleetTruckDao.insert(queryFleetTruck);
            return count > 0 ? HttpResult.ok("车队班组绑定成功！") : HttpResult.error("车队班组绑定失败！");
        } else {
            queryFleetTruck.setId(fleetTruck.getId());
            int count = fleetTruckDao.updateById(queryFleetTruck);
            return count > 0 ? HttpResult.ok("车队班组绑定成功！") : HttpResult.error("车队班组绑定失败！");
        }
    }

    /**
     * @param truckId 车辆id
     * @param entId 企业id
     * @desc 查询车队班组
     * @author zk
     * @date 2023/7/20
     **/
    public KwfFleet findByFleetTruck(Long truckId, Long entId){
        return fleetTruckDao.findByFleetTruck(truckId, entId);
    }

    /**
     * @param params 参数
     * @desc 校验车辆是否有证书
     * @author zk
     * @date 2023/7/11
     **/
    public boolean checkLicense(KwfTruckDto params) {
        //车辆行驶证信息
        if (params.getTruckLicense() == null || StringUtils.isBlank(params.getTruckLicense().getDrivingNo())) {
            return false;
        }
        //车辆道路运输许可证
        if (params.getTransportLicense() == null || StringUtils.isBlank(params.getTransportLicense().getRoadTranNo())) {
            return false;
        }
        return true;
    }

    /**
     * @param truckId 车辆主键id
     * @desc 校验车辆是否有证书并更新状态
     * @author zk
     * @date 2023/7/11
     **/
    public void checkLicense(Long truckId) {
        //车辆行驶证信息
        KwfTruckLicense license = this.findTruckLicenseByKey(truckId);
        if (license == null || (StringUtils.isBlank(license.getCertificateMain())
                && StringUtils.isBlank(license.getCertificateRevolt()))) {
            return;
        }
        //车辆道路运输许可证
        KwfTransportLicense transportLicense = this.findTransportLicenseByKey(truckId);
        if (transportLicense == null || (StringUtils.isBlank(transportLicense.getCertificateMain())
                && StringUtils.isBlank(transportLicense.getCertificateRevolt()))) {
            return;
        }
        //更新数据
        KwfTruck truck = new KwfTruck();
        truck.setId(truckId);
        truck.setStatus(Global.NUMERICAL_ONE);
        truckDao.updateById(truck);
    }
}
