package com.ozs.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.ozs.common.core.domain.AjaxResult;
import com.ozs.common.exception.ServiceException;
import com.ozs.common.utils.StringUtils;
import com.ozs.common.utils.bean.BeanUtils;
import com.ozs.common.utils.bean.BeanValidators;
import com.ozs.entity.BaseRailwayManagement;
import com.ozs.entity.BaseVehicleTerminal;
import com.ozs.entity.BaseVehicle;
import com.ozs.entity.BaseTerminal;
import com.ozs.entity.vo.BaseVehicleTerminalDto;
import com.ozs.entity.vo.BaseVehicleTerminalVo;
import com.ozs.entity.vo.BaseVehicleVo;
import com.ozs.entity.vo.VehicleTreeVo;
import com.ozs.mapper.BaseDeviceDynamicManagementMapper;
import com.ozs.mapper.BaseVehicleTerminalMapper;
import com.ozs.mapper.BaseVehicleMapper;
import com.ozs.mapper.BaseTerminalMapper;
import com.ozs.service.BaseVehicleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.validation.Validator;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 机车信息表 服务实现类
 * </p>
 *
 * @author ozs
 * @since 2023-04-11
 */
@Service
public class BaseVehicleServiceImpl extends ServiceImpl<BaseVehicleMapper, BaseVehicle> implements BaseVehicleService {

    @Autowired
    private BaseVehicleMapper baseVehicleMapper;
    @Autowired
    private BaseVehicleTerminalMapper baseVehicleTerminalMapper;
    @Autowired
    BaseDeviceDynamicManagementMapper baseDeviceDynamicManagementMapper;
    @Autowired
    private BaseTerminalMapper baseTerminalMapper;
    @Autowired
    protected Validator validator;

    @Override
    public IPage<BaseVehicle> vehicleList(BaseVehicleVo baseVehicle) {
        LambdaQueryWrapper<BaseVehicle> wrapper = new LambdaQueryWrapper<BaseVehicle>();
        if (!StringUtils.isEmptySunhh(baseVehicle) && !StringUtils.isEmptySunhh(baseVehicle.getVehicleName())) {
            wrapper.like(BaseVehicle::getVehicleName, baseVehicle.getVehicleName());
        }
        if (!StringUtils.isEmptySunhh(baseVehicle) && !StringUtils.isEmptySunhh(baseVehicle.getVehicleCode())) {
            wrapper.like(BaseVehicle::getVehicleCode, baseVehicle.getVehicleCode());
        }
        wrapper.orderByDesc(BaseVehicle::getCreateTime);
        int pageNum = Integer.parseInt(baseVehicle.getPageNum().toString());
        int pageSize = Integer.parseInt(baseVehicle.getPageSize().toString());
        com.github.pagehelper.Page<BaseVehicle> page = PageHelper.startPage(pageNum, pageSize)
                .doSelectPage(() -> baseVehicleMapper.selectList(wrapper));
        if (!StringUtils.isEmptySunhh(page) && page.getResult().size() > 0) {
            List<BaseVehicle> dto1 = page.getResult().stream().map(o -> {
                BaseVehicleTerminal baseVehicleTerminal = baseVehicleTerminalMapper.selectTerminal(o.getVehicleCode(),o.getEnds());
                if (!StringUtils.isEmptySunhh(baseVehicleTerminal) && !StringUtils.isEmptySunhh(baseVehicleTerminal.getVehicleCode())) {
                    LambdaQueryWrapper<BaseTerminal> wrapperBaseTerminal = new LambdaQueryWrapper<>();
                    if (!StringUtils.isEmptySunhh(baseVehicleTerminal) && !StringUtils.isEmptySunhh(baseVehicleTerminal.getTerminalCode())) {
                        wrapperBaseTerminal.eq(BaseTerminal::getTerminalCode, baseVehicleTerminal.getTerminalCode());
                    }
                    BaseTerminal baseTerminal1 = baseTerminalMapper.selectOne(wrapperBaseTerminal);
                    if (!StringUtils.isEmptySunhh(baseTerminal1) && !StringUtils.isEmptySunhh(baseTerminal1.getTerminalName())) {
                        o.setTerminalName(baseTerminal1.getTerminalName());
                    }
                }
                return o;
            }).collect(Collectors.toList());
        }
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<BaseVehicle> pageR =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNum, pageSize);
        pageR.setRecords(page.getResult());
        pageR.setTotal(page.getTotal());
        return pageR;
    }

    @Override
    public AjaxResult vehicleAdd(BaseVehicle baseVehicle, String userId) {
//        LambdaQueryWrapper<BaseVehicle> wrapper = new LambdaQueryWrapper<BaseVehicle>();
//        if (!StringUtils.isEmptySunhh(baseVehicle) && !StringUtils.isEmptySunhh(baseVehicle.getVehicleCode())) {
//            wrapper.eq(BaseVehicle::getVehicleCode, baseVehicle.getVehicleCode());
//        }
//        List<BaseVehicle> baseVehicles = baseVehicleMapper.selectList(wrapper);
//        if (baseVehicles.size() > 0) {
//            return AjaxResult.error("机车号已存在！");
//        }
        Date date = new Date();
        baseVehicle.setCreateBy(userId);
        baseVehicle.setUpdateBy(userId);
        baseVehicle.setCreateTime(date);
        baseVehicle.setUpdateTime(date);
        int insert = baseVehicleMapper.insert(baseVehicle);
        if (insert > 0) {
            return AjaxResult.success();
        } else {
            return AjaxResult.error();
        }
    }

    @Override
    public AjaxResult vehicleUpdate(BaseVehicle baseVehicle, String userId) {
//        LambdaQueryWrapper<BaseVehicle> wrapper = new LambdaQueryWrapper<>();
//        if (!StringUtils.isEmptySunhh(baseVehicle) && !StringUtils.isEmptySunhh(baseVehicle.getVehicleCode())) {
//            wrapper.eq(BaseVehicle::getVehicleCode, baseVehicle.getVehicleCode());
//        }
//        if (!StringUtils.isEmptySunhh(baseVehicle) && !StringUtils.isEmptySunhh(baseVehicle.getId())) {
//            wrapper.ne(BaseVehicle::getId, baseVehicle.getId());
//        }
//        List<BaseVehicle> baseVehicles = baseVehicleMapper.selectList(wrapper);
//        if (baseVehicles.size() > 0) {
//            return AjaxResult.error("机车号已存在！");
//        }
        baseVehicle.setUpdateBy(userId);
        baseVehicle.setUpdateTime(new Date());
        int update = baseVehicleMapper.updateById(baseVehicle);
        if (update > 0) {
            return AjaxResult.success();
        } else {
            return AjaxResult.error();
        }
    }

    @Override
    public String importBaseVehicle(List<BaseVehicle> accountManageList, boolean updateSupport, String userId) {
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (BaseVehicle baseVehicle2 : accountManageList) {
            try {
                BaseVehicle baseVehicle = new BaseVehicle();
                BeanUtils.copyProperties(baseVehicle2, baseVehicle);
                // 判断机车号是否存在
//                LambdaQueryWrapper<BaseVehicle> lw = new LambdaQueryWrapper<BaseVehicle>();
//                if (!StringUtils.isEmptySunhh(baseVehicle.getVehicleCode())) {
//                    lw.eq(BaseVehicle::getVehicleCode, baseVehicle.getVehicleCode());
//                }
//                BaseVehicle baseVehicle1 = baseVehicleMapper.selectOne(lw);
//                if (ObjectUtils.isEmpty(baseVehicle1)) {
                    BeanValidators.validateWithException(validator, baseVehicle);
                    baseVehicle.setUpdateBy(userId);
                    baseVehicle.setCreateBy(userId);
                    Date date = new Date();
                    baseVehicle.setCreateTime(date);
                    baseVehicle.setUpdateTime(date);
                    int insert = baseVehicleMapper.insert(baseVehicle);
                    successNum++;
                    successMsg.append(successNum + "、机车号 " + baseVehicle.getVehicleCode() + " 导入成功");
//                } else if (updateSupport) {
//                    BeanValidators.validateWithException(validator, baseVehicle);
//                    LambdaQueryWrapper<BaseVehicle> lambdaQueryWrapper = new LambdaQueryWrapper<BaseVehicle>();
//                    if (!StringUtils.isEmptySunhh(baseVehicle.getVehicleCode())) {
//                        lambdaQueryWrapper.eq(BaseVehicle::getVehicleCode, baseVehicle.getVehicleCode());
//                    }
//                    BaseVehicle baseVehicle4 = baseVehicleMapper.selectOne(lambdaQueryWrapper);
//                    if (StringUtils.isEmptySunhh(baseVehicle4)) {
//                        baseVehicle.setUpdateBy(userId);
//                        baseVehicle.setUpdateTime(new Date());
//                        baseVehicle.setId(baseVehicle4.getId());
//                        baseVehicleMapper.updateById(baseVehicle);
//                        successNum++;
//                        successMsg.append(successNum + "、机车号 " + baseVehicle.getVehicleCode() + " 更新成功");
//                } else {
//                    failureNum++;
//                    failureMsg.append(failureNum + "、机车号 " + baseVehicle.getVehicleCode() + "已存在");
//                }
            } catch (Exception e) {
                String msg = null;
                failureNum++;
                if (ObjectUtils.isEmpty(baseVehicle2)) {
                    msg = "导入的文档格式不正确";
                } else {
                    msg = failureNum + "、机车号 " + baseVehicle2.getVehicleCode() + " 导入失败：";
                }
                failureMsg.append(msg);
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条。");
        }
        return successMsg.toString();
    }

    @Override
    public AjaxResult vehicleDetails(BaseVehicle baseVehicle) {
        BaseVehicle baseVehicle1 = baseVehicleMapper.selectById(baseVehicle.getId());
        return AjaxResult.success(baseVehicle1);
    }

    @Override
    public List<BaseVehicle> exportBaseVehicle(BaseVehicle baseVehicle) {
        LambdaQueryWrapper<BaseVehicle> wrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmptySunhh(baseVehicle) && !StringUtils.isEmptySunhh(baseVehicle.getVehicleName())) {
            wrapper.eq(BaseVehicle::getVehicleName, baseVehicle.getVehicleName());
        }
        if (!StringUtils.isEmptySunhh(baseVehicle) && !StringUtils.isEmptySunhh(baseVehicle.getVehicleCode())) {
            wrapper.eq(BaseVehicle::getVehicleCode, baseVehicle.getVehicleCode());
        }
        if (baseVehicle.getIds().size() > 0) {
            wrapper.in(BaseVehicle::getId, baseVehicle.getIds());
        }
        List<BaseVehicle> baseVehicles = baseVehicleMapper.selectList(wrapper);
        for (BaseVehicle baseVehicle1 : baseVehicles) {
            BaseVehicleTerminal baseTerminal = baseVehicleTerminalMapper.selectTerminal(baseVehicle1.getVehicleCode(),baseVehicle1.getEnds());
            if (!StringUtils.isEmptySunhh(baseTerminal) && !StringUtils.isEmptySunhh(baseTerminal.getVehicleCode())) {
                LambdaQueryWrapper<BaseTerminal> wrapperBaseVehicleTerminal = new LambdaQueryWrapper<>();
                if (!StringUtils.isEmptySunhh(baseTerminal) && !StringUtils.isEmptySunhh(baseTerminal.getTerminalCode())) {
                    wrapperBaseVehicleTerminal.eq(BaseTerminal::getTerminalCode, baseTerminal.getTerminalCode());
                }
                BaseTerminal baseVehicleTerminal = baseTerminalMapper.selectOne(wrapperBaseVehicleTerminal);
                if (!StringUtils.isEmptySunhh(baseVehicleTerminal) && !StringUtils.isEmptySunhh(baseVehicleTerminal.getTerminalName())) {
                    baseVehicle1.setTerminalName(baseVehicleTerminal.getTerminalName());
                } else {
                    baseVehicle1.setTerminalName("");
                }
            }
        }
        return baseVehicles;
    }

    @Override
    public IPage<BaseVehicleTerminalVo> vehicleTerminal(BaseVehicleVo baseVehicleVo) {
        BaseVehicleTerminal baseTerminal = baseVehicleTerminalMapper.selectTerminal(baseVehicleVo.getVehicleCode(),baseVehicleVo.getEnds());
        List<String> terminalCodeList = baseVehicleTerminalMapper.selectMountCode(baseVehicleVo.getVehicleCode());
        // List<String> collect = terminalCodeList.stream().map(BaseTerminal::getTerminalCode).collect(Collectors.toList());
        LambdaQueryWrapper<BaseTerminal> wrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmptySunhh(terminalCodeList) && terminalCodeList.size() > 0) {
            wrapper.notIn(BaseTerminal::getTerminalCode, terminalCodeList);
        }
        wrapper.eq(BaseTerminal::getStatus, 1);
//        List<BaseVehicleTerminal> baseVehicleTerminalList = baseVehicleTerminalMapper.selectList(wrapper);
        int pageNum = Integer.parseInt(baseVehicleVo.getPageNum().toString());
        int pageSize = Integer.parseInt(baseVehicleVo.getPageSize().toString());
        com.github.pagehelper.Page<BaseTerminal> page = PageHelper
                .startPage(pageNum, pageSize).doSelectPage(() -> baseTerminalMapper.selectList(wrapper));
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<BaseVehicleTerminalVo> pageR =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNum, pageSize);
        if (!ObjectUtils.isEmpty(page) && page.getResult().size() > 0) {
            List<BaseVehicleTerminalVo> dto1 = page.getResult().stream().map(o -> {
                BaseVehicleTerminalVo baseVehicleTerminalVo = new BaseVehicleTerminalVo();
                BeanUtils.copyProperties(o, baseVehicleTerminalVo);
                if (!StringUtils.isEmptySunhh(baseTerminal)) {
                    if (baseTerminal.getTerminalCode().equals(o.getTerminalCode())) {
                        baseVehicleTerminalVo.setIsMount("2");
                    } else {
                        baseVehicleTerminalVo.setIsMount("1");
                    }
                } else {
                    baseVehicleTerminalVo.setIsMount("1");
                }
                return baseVehicleTerminalVo;
            }).collect(Collectors.toList());
            pageR.setRecords(dto1);
        }
        return pageR;
    }

    @Override
    public AjaxResult vehicleTerminalAdd(BaseVehicleTerminal baseTerminal1, String userId) {
        LambdaQueryWrapper<BaseVehicleTerminal> wrapper1 = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmptySunhh(baseTerminal1) && !StringUtils.isEmptySunhh(baseTerminal1.getVehicleCode())) {
            wrapper1.ne(BaseVehicleTerminal::getVehicleCode, baseTerminal1.getVehicleCode());
        }
        if (!StringUtils.isEmptySunhh(baseTerminal1) && !StringUtils.isEmptySunhh(baseTerminal1.getTerminalCode())) {
            wrapper1.eq(BaseVehicleTerminal::getTerminalCode, baseTerminal1.getTerminalCode());
        }
        List<BaseVehicleTerminal> baseTerminals = baseVehicleTerminalMapper.selectList(wrapper1);
        if (!StringUtils.isEmptySunhh(baseTerminals) && baseTerminals.size() > 0) {
            return AjaxResult.error("此终端已经挂载其他机车！");
        }

        LambdaQueryWrapper<BaseVehicleTerminal> wrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmptySunhh(baseTerminal1) && !StringUtils.isEmptySunhh(baseTerminal1.getVehicleCode())) {
            wrapper.eq(BaseVehicleTerminal::getVehicleCode, baseTerminal1.getVehicleCode());
        }
        BaseVehicleTerminal baseTerminal = baseVehicleTerminalMapper.selectOne(wrapper);
        if (StringUtils.isEmptySunhh(baseTerminal)) {
            BaseVehicleTerminal baseTerminal2 = new BaseVehicleTerminal();
            baseTerminal2.setVehicleCode(baseTerminal1.getVehicleCode());
            baseTerminal2.setTerminalCode(baseTerminal1.getTerminalCode());
            baseTerminal2.setCreateBy(userId);
            baseTerminal2.setUpdateBy(userId);
            baseTerminal2.setEnds(baseTerminal1.getEnds());
            Date date = new Date();
            baseTerminal2.setCreateTime(date);
            baseTerminal2.setUpdateTime(date);
            int insert = baseVehicleTerminalMapper.insert(baseTerminal2);
        } else {
            baseTerminal.setUpdateBy(userId);
            baseTerminal.setUpdateTime(new Date());
            baseTerminal.setVehicleCode(baseTerminal1.getVehicleCode());
            baseTerminal.setTerminalCode(baseTerminal1.getTerminalCode());
            baseTerminal.setEnds(baseTerminal1.getEnds());
            int updateById = baseVehicleTerminalMapper.updateById(baseTerminal);
        }
        return AjaxResult.success();
    }

    @Override
    public Boolean isMount(BaseVehicleVo baseVehicleVo) {
        LambdaQueryWrapper<BaseVehicleTerminal> wrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmptySunhh(baseVehicleVo) && !StringUtils.isEmptySunhh(baseVehicleVo.getVehicleCode())) {
            wrapper.eq(BaseVehicleTerminal::getVehicleCode, baseVehicleVo.getVehicleCode());
        }
        BaseVehicleTerminal baseTerminal = baseVehicleTerminalMapper.selectOne(wrapper);
        if (StringUtils.isEmptySunhh(baseTerminal)) {
            return true;
        }
        return false;
    }

    @Override
    public List<BaseVehicleTerminalDto> vehicleList() {
        List<BaseVehicleTerminalDto> dtoList = baseDeviceDynamicManagementMapper.vehicleTreelist(null);
        List<String> strings = dtoList.stream().map(BaseVehicleTerminalDto::getVehicleCode).collect(Collectors.toList());
        LambdaQueryWrapper<BaseVehicle> bw = new LambdaQueryWrapper<>();
        bw.in(BaseVehicle::getVehicleCode, strings);
        List<BaseVehicle> vehicles = baseVehicleMapper.selectList(bw);
        for (BaseVehicleTerminalDto terminalDto : dtoList) {
            for (BaseVehicle vehicle : vehicles) {
                if (terminalDto.getVehicleCode().equals(vehicle.getVehicleCode())) {
                    terminalDto.setVehicleName(vehicle.getVehicleName());
                    break;
                }
            }
        }
        return dtoList;
    }

    @Override
    public List<BaseVehicle> vehicleListDT(BaseVehicleVo baseVehicle) {
        //查到所有机车数据
        LambdaQueryWrapper<BaseVehicle> wrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmptySunhh(baseVehicle) && !StringUtils.isEmptySunhh(baseVehicle.getVehicleCode())) {
            wrapper.like(BaseVehicle::getVehicleCode, baseVehicle.getVehicleCode());
        }
        List<BaseVehicle> baseVehicles = baseVehicleMapper.selectList(wrapper);
        //查到机车关联的终端
        if (!StringUtils.isEmptySunhh(baseVehicles)) {
            List<String> terminalCodeList = new ArrayList<>();
            baseVehicles = baseVehicles.stream().map(o -> {
                //查到已保存的关联信息
                BaseVehicleTerminal baseVehicleTerminal = baseVehicleTerminalMapper.selectTerminal(o.getVehicleCode(),o.getEnds());
                if (!StringUtils.isEmptySunhh(baseVehicleTerminal) && !StringUtils.isEmptySunhh(baseVehicleTerminal.getVehicleCode())) {
                    terminalCodeList.add(baseVehicleTerminal.getVehicleCode());
                    LambdaQueryWrapper<BaseTerminal> wrapperBaseVehicleTerminal = new LambdaQueryWrapper<>();
                    if (!StringUtils.isEmptySunhh(baseVehicleTerminal) && !StringUtils.isEmptySunhh(baseVehicleTerminal.getTerminalCode())) {
                        wrapperBaseVehicleTerminal.eq(BaseTerminal::getTerminalCode, baseVehicleTerminal.getTerminalCode());
                    }
                    //根据编码获取终端名称
                    BaseTerminal baseTerminal = baseTerminalMapper.selectOne(wrapperBaseVehicleTerminal);
                    if (!StringUtils.isEmptySunhh(baseTerminal) && !StringUtils.isEmptySunhh(baseTerminal.getTerminalName())) {
                        o.setTerminalName(baseTerminal.getTerminalName());
                    }
                }
                return o;
            }).collect(Collectors.toList());
            VehicleTreeVo vehicleTreeVo = new VehicleTreeVo();
            vehicleTreeVo.setTerminalCodeList(terminalCodeList);
            //机车和终端在行驶记录中最后的位置信息
            List<BaseVehicleTerminalDto> list = baseDeviceDynamicManagementMapper.vehicleTreelist(vehicleTreeVo);
            for (BaseVehicle vehicle : baseVehicles) {
                for (BaseVehicleTerminalDto terminalDto : list) {
                    if (terminalDto.getVehicleCode().equals(vehicle.getVehicleCode())) {
                        vehicle.setVehicleTerminalDto(terminalDto);
                        break;
                    }
                }
            }
        }
        return baseVehicles;
    }

    @Override
    public AjaxResult vehicleTerminalUnmount(BaseVehicleTerminal baseTerminal) {
        LambdaQueryWrapper<BaseVehicleTerminal> wrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmptySunhh(baseTerminal) && !StringUtils.isEmptySunhh(baseTerminal.getVehicleCode())) {
            wrapper.eq(BaseVehicleTerminal::getVehicleCode, baseTerminal.getVehicleCode());
        }
        baseVehicleTerminalMapper.delete(wrapper);
        return AjaxResult.success();
    }

    @Override
    @Transactional
    public AjaxResult removeByIdList(List<Long> ids) {
        for (Long vehicleId : ids) {
            BaseVehicle baseVehicle = baseVehicleMapper.selectById(vehicleId);
            if (!StringUtils.isEmptySunhh(baseVehicle) && !StringUtils.isEmptySunhh(baseVehicle.getVehicleCode())) {
                LambdaQueryWrapper<BaseVehicleTerminal> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(BaseVehicleTerminal::getVehicleCode, baseVehicle.getVehicleCode());
                int delete = baseVehicleTerminalMapper.delete(wrapper);
                int i = baseVehicleMapper.deleteById(vehicleId);
            }
        }
        return AjaxResult.success(true);
    }
}
