package com.sckw.fleet.service;

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.PasswordUtils;
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.KwfDriverVo;
import com.sckw.fleet.model.vo.KwfTableTopCount;
import com.sckw.redis.constant.RedisConstant;
import com.sckw.redis.utils.RedissonUtils;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.EntCacheResDto;
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.transaction.annotation.Transactional;
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;

/**
 * @desc 司机
 * @author zk
 * @date 2023/7/6 0006
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class KwfDriverService {

    @Autowired
    KwfDriverMapper driverDao;
    @Autowired
    KwfDriverEntMapper driverEntDao;
    @Autowired
    KwfDriverCardMapper KwfDriverCardDao;
    @Autowired
    KwfDriverLicenseMapper KwfDriverLicenseDao;
    @Autowired
    KwfDriverQualificationMapper KwfDriverQualificationDao;
    @Autowired
    KwfFleetDriverMapper fleetDriverDao;
    @DubboReference(version = "2.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;

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

    /**
     * @param params 参数
     * @desc 统计
     * @author zk
     * @date 2023/7/11
     **/
    public Map statistics(Map<String, Object> params) {
        /**统计数据**/
        List<KwfTableTopCount> counts = driverDao.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;
    }

    class KwfTableTopStatus {
        Map<String, Object> statusMap = new HashMap(){{put("1","正常"); put("2","临时"); put("3","异常");}};


    }

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

        /**获取查询数据**/
        List<Long> createBys = new ArrayList<>();
        List<Long> entIds = new ArrayList<>();
        for (KwfDriverVo driver:drivers) {
            createBys.add(Long.parseLong(driver.getCreateBy()));
            entIds.add(Long.parseLong(driver.getEntId()));
        }
        //用户数据集
        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);

        /**数据组装**/
        for (KwfDriverVo driver:drivers) {
            UserCacheResDto user = users == null ? null : users.get(Long.parseLong(driver.getCreateBy()));
            EntCacheResDto ent = ents == null ? null : ents.get(Long.parseLong(driver.getEntId()));
            driver.setCreateByName(user != null ? user.getName() : null);
            driver.setFirmName(ent != null ? ent.getFirmName() : null);
        }
        return drivers;
    }

    /**
     * @param params 查询参数
     * @desc 查询
     * @author zk
     * @date 2023/7/6
     **/
    public List<Map<String, Object>> findList(Map<String, Object> params) {
        return driverDao.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(KwfDriverDto params) {
        /**司机信息**/
        KwfDriver driver = new KwfDriver();
        BeanUtils.copyProperties(params, driver);
        //证件都有数据则为已认证(前端校验认证数据必填)
        boolean bool = checkLicense(params);
        if (bool) {
            driver.setStatus(Global.NUMERICAL_ONE);
        } else {
            driver.setStatus(Global.NUMERICAL_TWO);
        }
        HttpResult result = driverEdit(driver);
        if (result.getCode() != HttpStatus.SUCCESS_CODE) {
            return result;
        }

        /**身份证信息**/
        KwfDriverCardDto driverCardDto = params.getDriverCard();
        if (driverCardDto != null) {
            driverCardDto.setDriverId(driver.getId());
            driverCardEdit(driverCardDto);
        }

        /**司机驾驶证信息**/
        KwfDriverLicenseDto driverLicenseDto = params.getDriverLicense();
        if (driverLicenseDto != null) {
            driverLicenseDto.setDriverId(driver.getId());
            driverLicenseEdit(driverLicenseDto);
        }

        /**司机从业资格证**/
        KwfDriverQualificationDto driverQualificationDto = params.getDriverQualification();
        if (driverQualificationDto != null) {
            driverQualificationDto.setDriverId(driver.getId());
            driverQualificationEdit(driverQualificationDto);
        }

        /**司机信息与企业关联信息**/
        driverEntEdit(driver);

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

        return HttpResult.ok("司机信息新增成功！", driver);
    }

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

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

        /**身份证信息**/
        KwfDriverCardDto driverCardDto = params.getDriverCard();
        if (driverCardDto != null) {
            driverCardDto.setDriverId(driver.getId());
            driverCardEdit(driverCardDto);
        }

        /**司机驾驶证信息**/
        KwfDriverLicenseDto driverLicenseDto = params.getDriverLicense();
        if (driverLicenseDto != null) {
            driverLicenseDto.setDriverId(driver.getId());
            driverLicenseEdit(driverLicenseDto);
        }

        /**司机从业资格证**/
        KwfDriverQualificationDto driverQualificationDto = params.getDriverQualification();
        if (driverQualificationDto != null) {
            driverQualificationDto.setDriverId(driver.getId());
            driverQualificationEdit(driverQualificationDto);
        }

        /**车队班组绑定**/
        driverFleetEdit(driver.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(",");
        KwfDriverEnt driverEntQuery = new KwfDriverEnt();
        driverEntQuery.setEntId(LoginUserHolder.getEntId());
        for (String id : idArray) {
            driverEntQuery.setDriverId(Long.parseLong(id));
            KwfDriverEnt driverEnt = driverEntDao.findByDriverEnt(driverEntQuery);
            if (driverEnt != null) {
                driverEnt.setDelFlag(Global.YES);
                if (driverEntDao.updateById(driverEnt) <= 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 driverEdit(KwfDriver params) {
        if (StringUtils.isBlank(params.getId())) {
            /**唯一性交易**/
            List<Map<String, Object>> drivers = driverDao.findList(new HashMap(){{ put("phone", params.getPhone()); }});
            if (!CollectionUtils.isEmpty(drivers)) {
                return HttpResult.error("电话号码已存在！");
            }

            /**新增**/
            String md5 = PasswordUtils.md5(params.getPhone());
            String password = PasswordUtils.entryptPassword(md5);
            params.setSalt(PasswordUtils.getSaltSubPwd(password));
            params.setPassword(password);
            params.setEntId(LoginUserHolder.getEntId());
            params.setEntId(params.getEntId() == null ? 1 : params.getEntId());// 暂时处理---------------zk
            params.setBusinessStatus(Global.NO);
            int count = driverDao.insert(params);
            return count > 0 ? HttpResult.ok() : HttpResult.error("司机信息新增失败！");
        } else {
            /**唯一性交易**/
            List<Map<String, Object>> drivers = driverDao.findList(new HashMap(){{ put("phone", params.getPhone()); }});
            //校验list中对象key值是否存在与value不一致的情况
            boolean bool = CollectionUtils.listByKeyValueV1(drivers, "id", String.valueOf(params.getId()));
            if (bool) {
                return HttpResult.error("司机信息电话号码已存在！");
            }

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

    /**
     * @param params 参数
     * @desc 新增身份证信息
     * @author zk
     * @date 2023/7/7
     **/
    public HttpResult driverCardEdit(KwfDriverCardDto params) {
        /**数据校验**/
        if (StringUtils.isBlank(params.getDriverId())) {
            return HttpResult.error(HttpStatus.PARAMETERS_PATTERN_ERROR_CODE,"司机信息ID不能为空！");
        }
        KwfDriver driver = driverDao.selectById(params.getDriverId());
        if (driver == null) {
            return HttpResult.error("司机信息不存在！");
        }

        /**数据copy**/
        KwfDriverCard driverCard = new KwfDriverCard();
        BeanUtils.copyProperties(params, driverCard);

        /**数据更新**/
        int count = 0;
        KwfDriverCard card = KwfDriverCardDao.findByDriverId(params.getDriverId());
        if (card == null) {
            count = KwfDriverCardDao.insert(driverCard);
        } else {
            driverCard.setId(card.getId());
            count = KwfDriverCardDao.updateById(driverCard);
        }

        /**校验司机是否有证书并更新状态**/
        checkLicense(driverCard.getDriverId());
        return count > 0 ? HttpResult.ok("身份证信息修改成功！") : HttpResult.error("身份证信息修改失败！");
    }

    /**
     * @param key 参数
     * @desc 查询身份证信息
     * @author zk
     * @date 2023/7/7
     **/
    public KwfDriverCard findCarByKey(Long key) {
        return KwfDriverCardDao.findByDriverId(key);
    }

    /**
     * @param params 参数
     * @desc 新增司机驾驶证信息
     * @author zk
     * @date 2023/7/7
     **/
    public HttpResult driverLicenseEdit(KwfDriverLicenseDto params) {
        /**数据校验**/
        if (StringUtils.isBlank(params.getDriverId())) {
            return HttpResult.error(HttpStatus.PARAMETERS_PATTERN_ERROR_CODE,"司机信息ID不能为空！");
        }
        KwfDriver driver = driverDao.selectById(params.getDriverId());
        if (driver == null) {
            return HttpResult.error("司机信息不存在！");
        }

        /**数据copy**/
        KwfDriverLicense driverLicense = new KwfDriverLicense();
        BeanUtils.copyProperties(params, driverLicense);

        /**数据更新**/
        int count = 0;
        KwfDriverLicense license = KwfDriverLicenseDao.findByDriverId(params.getDriverId());
        if (license == null) {
            count = KwfDriverLicenseDao.insert(driverLicense);
            return count > 0 ? HttpResult.ok("司机驾驶证信息更新成功！") : HttpResult.error("司机驾驶证信息更新失败！");
        } else {
            driverLicense.setId(license.getId());
            count = KwfDriverLicenseDao.updateById(driverLicense);
        }

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

    /**
     * @param key 参数
     * @desc 查询司机驾驶证信息
     * @author zk
     * @date 2023/7/7
     **/
    public KwfDriverLicense findLicenseByKey(Long key) {
        return KwfDriverLicenseDao.findByDriverId(key);
    }

    /**
     * @param params 参数
     * @desc 新增司机从业资格证
     * @author zk
     * @date 2023/7/7
     **/
    public HttpResult driverQualificationEdit(KwfDriverQualificationDto params) {
        /**数据校验**/
        if (StringUtils.isBlank(params.getDriverId())) {
            return HttpResult.error(HttpStatus.PARAMETERS_PATTERN_ERROR_CODE,"司机信息ID不能为空！");
        }
        KwfDriver driver = driverDao.selectById(params.getDriverId());
        if (driver == null) {
            return HttpResult.error("司机信息不存在！");
        }

        /**数据copy**/
        KwfDriverQualification driverQual = new KwfDriverQualification();
        BeanUtils.copyProperties(params, driverQual);

        /**数据更新**/
        int count = 0;
        KwfDriverQualification qualification = KwfDriverQualificationDao.findByDriverId(params.getDriverId());
        if (qualification == null) {
            count = KwfDriverQualificationDao.insert(driverQual);
        } else {
            driverQual.setId(qualification.getId());
            count = KwfDriverQualificationDao.updateById(driverQual);
        }

        /**校验司机是否有证书并更新状态**/
        checkLicense(driverQual.getDriverId());
        return count > 0 ? HttpResult.ok("司机从业资格证信息修改成功！") : HttpResult.error("司机从业资格证信息修改失败！");
    }

    /**
     * @param key 参数
     * @desc 查询司机从业资格证
     * @author zk
     * @date 2023/7/7
     **/
    public KwfDriverQualification findQualificationByKey(Long key) {
        return KwfDriverQualificationDao.findByDriverId(key);
    }

    /**
     * @param params 参数
     * @desc 新增司机信息与企业关联信息
     * @author zk
     * @date 2023/7/7
     **/
    public void driverEntEdit(KwfDriver params) {
        KwfDriverEnt driverEnt = new KwfDriverEnt();
        driverEnt.setDriverId(params.getId());
        driverEnt.setEntId(params.getEntId());
        KwfDriverEnt ent = driverEntDao.findByDriverEnt(driverEnt);
        if (ent == null) {
            driverEntDao.insert(driverEnt);
        }
    }

    /**
     * @param driverId 司机档案主键id fleetId 车队班组主键id
     * @desc 车队班组绑定
     * @author zk
     * @date 2023/7/7
     **/
    public HttpResult driverFleetEdit(Long driverId, Long fleetId) {
        /**数据校验**/
        if (fleetId == null) {
            return HttpResult.ok("未选择车队班组！");
        }
        KwfFleetDriver queryFleetDriver = new KwfFleetDriver();
        queryFleetDriver.setEntId(LoginUserHolder.getEntId());
        queryFleetDriver.setDriverId(driverId);
        KwfFleetDriver fleetDriver = fleetDriverDao.findByTruckDriver(queryFleetDriver);

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

    /**
     * @param driverId 司机id
     * @param entId 企业id
     * @desc 查询车队班组
     * @author zk
     * @date 2023/7/20
     **/
    public KwfFleet findByFleetDriver(Long driverId, Long entId) {
        return fleetDriverDao.findByFleetDriver(driverId, entId);
    }


    /**
     * @param params 参数
     * @desc: 修改密码
     * @author: zk
     * @date: 2023/7/11
     */
    public HttpResult updatePassword(UpdatePasswordDto params) {
        /**获取信息**/
        Long driverId = null;//LoginUserHolder.getUserId(); //暂时----------------zk
        driverId = driverId == null ? params.getDriverId() : driverId;
        KwfDriver driver = driverDao.selectById(driverId);
        if (driver == null) {
            return HttpResult.error("信息不存在！");
        }

        /**原密码校验**/
        if (!PasswordUtils.validatePassword(params.getPassword(), driver.getPassword())) {
            return HttpResult.error("原密码不正确！");
        }

        /**新旧密码不能一只**/
        if (PasswordUtils.validatePassword(params.getNewPassword(), driver.getPassword())) {
            return HttpResult.error("原密码与新密码不能一致！");
        }

        /**更新数据**/
        driver.setPassword(PasswordUtils.entryptPassword(params.getNewPassword()));
        driver.setSalt(PasswordUtils.getSaltSubPwd(driver.getPassword()));
        int count = driverDao.updateById(driver);
        return count > 0 ? HttpResult.ok("密码修改成功！") : HttpResult.error("密码修改失败！");
    }

    /**
     * @param {driverId 司机主键id/登陆后缓存中取、phone 手机号、captcha 短信验证码}
     * @description 更换手机号
     * @author zk
     * @date 2023/07/11
     **/
    public HttpResult replacePhone(ReplacePhoneDto params) {
        /**获取信息**/
        Long driverId = null;//LoginUserHolder.getUserId(); //暂时----------------zk
        driverId = driverId == null ? params.getDriverId() : driverId;
        KwfDriver driver = driverDao.selectById(driverId);
        if (driver == null) {
            return HttpResult.error("信息不存在！");
        }

        /**从缓存中取出验证码/校验**/
        String valueKey = StringUtils.getKey(RedisConstant.MESSAGE_SMS_VERIFY_CODE_VALUE_KEY, params.getPhone());
        String phoneCaptcha = RedissonUtils.getString(valueKey);
        if (StringUtils.isBlank(phoneCaptcha)) {
            return HttpResult.error("手机验证码不正确请确认！");
        }
        if (!phoneCaptcha.equals(params.getCaptcha())) {
            return HttpResult.error("手机验证码不正确请确认！");
        }

        /**唯一性交易**/
        List<Map<String, Object>> drivers = driverDao.findList(new HashMap(){{ put("phone", params.getPhone()); }});
        if (!CollectionUtils.isEmpty(drivers)) {
            return HttpResult.error("电话号码已存在！");
        }

        /**更新数据**/
        driver.setPhone(params.getPhone());
        int count = driverDao.updateById(driver);
        return count > 0 ? HttpResult.ok("手机号更换成功！") : HttpResult.error("手机号更换失败！");
    }

    /**
     * @param params 参数
     * @desc 校验司机是否有证书
     * @author zk
     * @date 2023/7/11
     **/
    public boolean checkLicense(KwfDriverDto params) {
        //身份证
        if (params.getDriverCard() == null || StringUtils.isBlank(params.getDriverCard().getIdcard())) {
            return false;
        }
        //司机驾驶证信息
        if (params.getDriverLicense() == null || StringUtils.isBlank(params.getDriverLicense().getDriverNo())) {
            return false;
        }
        //司机从业资格证
        if (params.getDriverQualification() == null || StringUtils.isBlank(params.getDriverQualification().getQualiNo())) {
            return false;
        }
        return true;
    }

    /**
     * @param driverId 司机id
     * @desc 校验司机是否有证书并更新状态
     * @author zk
     * @date 2023/7/11
     **/
    public void checkLicense(Long driverId) {
        //身份证
        KwfDriverCard card = this.findCarByKey(driverId);
        if (card == null || (StringUtils.isBlank(card.getCertificateMain()) && StringUtils.isBlank(card.getCertificateRevolt()))) {
            return;
        }
        //司机驾驶证信息
        KwfDriverLicense license = this.findLicenseByKey(driverId);
        if (license == null || (StringUtils.isBlank(license.getCertificateMain()) && StringUtils.isBlank(license.getCertificateRevolt()))) {
            return;
        }
        //司机从业资格证
        KwfDriverQualification quali = this.findQualificationByKey(driverId);
        if (quali == null || (StringUtils.isBlank(quali.getCertificateMain()) && StringUtils.isBlank(quali.getCertificateRevolt()))) {
            return;
        }
        //更新数据
        KwfDriver driver = new KwfDriver();
        driver.setId(driverId);
        driver.setStatus(Global.NUMERICAL_ONE);
        driverDao.updateById(driver);
    }
}
