package cn.iocoder.yudao.module.jx.service.impl;

import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolCoach;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCoachService;
import cn.iocoder.yudao.module.jx.domain.DriveSchoolCar;
import cn.iocoder.yudao.module.jx.mapper.DriveSchoolCarMapper;
import cn.iocoder.yudao.module.jx.service.IDriveSchoolCarService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 车辆信息Service业务层处理
 *
 * @author ruoyi
 * @date 2024-05-08
 */
@Service
public class DriveSchoolCarServiceImpl extends ServiceImpl<DriveSchoolCarMapper,DriveSchoolCar> implements IDriveSchoolCarService
{
    @Autowired
    private DriveSchoolCarMapper driveSchoolCarMapper;
    @Resource
    private DlDriveSchoolCoachService coachService;

    /**
     * 查询车辆信息
     *
     * @param id 车辆信息主键
     * @return 车辆信息
     */
    @Override
    public DriveSchoolCar selectDriveSchoolCarById(Long id)
    {
        return driveSchoolCarMapper.selectDriveSchoolCarById(id);
    }

    /**
     * 查询车辆信息列表
     *
     * @param driveSchoolCar 车辆信息
     * @return 车辆信息
     */
    @Override
    public IPage<DriveSchoolCar> selectDriveSchoolCarList(Page<DriveSchoolCar> page,DriveSchoolCar driveSchoolCar)
    {
        return driveSchoolCarMapper.selectDriveSchoolCarList(driveSchoolCar,page);
    }

    @Override
    public List<DriveSchoolCar> selectDriveSchoolCarListAll(DriveSchoolCar driveSchoolCar)
    {
        return driveSchoolCarMapper.selectDriveSchoolCarListAll(driveSchoolCar);
    }

    /**
     * 新增车辆信息
     *
     * @param driveSchoolCar 车辆信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertDriveSchoolCar(DriveSchoolCar driveSchoolCar)
    {
        DriveSchoolCar driveSchoolCar1 = driveSchoolCarMapper.selectByCarNo(driveSchoolCar.getCarNo());
        if (ObjectUtils.isNotEmpty(driveSchoolCar1)){
            throw new RuntimeException("该车牌的车辆已存在！");
        }
        if (StringUtils.isNotEmpty(driveSchoolCar.getCoachId())){
            // 获取教练当前关联的所有车牌
            String coachCarNos = coachService.getCoachCarNos(driveSchoolCar.getCoachId());
            // 教练与车牌关联
            if (StringUtils.isEmpty(coachCarNos)) {
                // 如果教练当前没有关联车辆，直接设置新车牌
                coachService.updateSchoolCoachCarId(driveSchoolCar.getCoachId(), driveSchoolCar.getCarNo());
            } else {
                // 检查车牌是否已关联
                List<String> carNoList = Arrays.asList(coachCarNos.split(";"));
                if (!carNoList.contains(driveSchoolCar.getCarNo())) {
                    // 不重复则追加新车牌
                    String updatedCarNos = coachCarNos + ";" + driveSchoolCar.getCarNo();
                    coachService.updateSchoolCoachCarId(driveSchoolCar.getCoachId(), updatedCarNos);
                }
                // 如果已存在则不处理
            }
        }
        return driveSchoolCarMapper.insert(driveSchoolCar);
    }

    /**
     * 修改车辆信息（支持教练多车关联）
     *
     * @param driveSchoolCar 车辆信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateDriveSchoolCar(DriveSchoolCar driveSchoolCar) {
        // 获取车辆原始信息 检查教练变更
        DriveSchoolCar originalCar = driveSchoolCarMapper.selectById(driveSchoolCar.getId());
        if (originalCar == null) {
            throw new RuntimeException("车辆不存在");
        }

        // 处理教练关联逻辑
        if (StringUtils.isNotEmpty(driveSchoolCar.getCoachId())) {
            // 获取教练当前关联的所有车牌
            String currentCarNos = coachService.getCoachCarNos(driveSchoolCar.getCoachId());

            // 如果教练有变更，需要从原教练中移除，添加到新教练
            if (!StringUtils.equals(originalCar.getCoachId(), driveSchoolCar.getCoachId())) {
                // 从原教练中移除当前车牌 如果原教练存在
                if (StringUtils.isNotEmpty(originalCar.getCoachId())) {
                    coachService.removeCarFromCoach(originalCar.getCoachId(), originalCar.getCarNo());
                }

                // 添加到新教练 不重复添加
                if (StringUtils.isEmpty(currentCarNos)) {
                    coachService.updateSchoolCoachCarId(driveSchoolCar.getCoachId(), driveSchoolCar.getCarNo());
                } else {
                    List<String> carNoList = Arrays.asList(currentCarNos.split(";"));
                    if (!carNoList.contains(driveSchoolCar.getCarNo())) {
                        String updatedCarNos = currentCarNos + ";" + driveSchoolCar.getCarNo();
                        coachService.updateSchoolCoachCarId(driveSchoolCar.getCoachId(), updatedCarNos);
                    }
                }
            } else {
                // 教练未变更，只检查车牌号是否变更
                if (!StringUtils.equals(originalCar.getCarNo(), driveSchoolCar.getCarNo())) {
                    // 车牌号变更，需要更新教练关联的车牌号
                    if (StringUtils.isNotEmpty(currentCarNos)) {
                        List<String> carNoList = new ArrayList<>(Arrays.asList(currentCarNos.split(";")));
                        // 移除旧车牌
                        carNoList.remove(originalCar.getCarNo());
                        // 添加新车牌（如果不重复）
                        if (!carNoList.contains(driveSchoolCar.getCarNo())) {
                            carNoList.add(driveSchoolCar.getCarNo());
                        }
                        coachService.updateSchoolCoachCarId(driveSchoolCar.getCoachId(), String.join(";", carNoList));
                    }
                }
            }
        } else if (StringUtils.isNotEmpty(originalCar.getCoachId())) {
            // 新教练ID为空，但原教练ID不为空，需要从原教练中移除
            coachService.removeCarFromCoach(originalCar.getCoachId(), originalCar.getCarNo());
        }

        // 更新车辆信息
        return driveSchoolCarMapper.updateById(driveSchoolCar);
    }

    /**
     * 修改车辆信息
     *
     * @param driveSchoolCar 车辆信息
     * @return 结果
     */
    /*@Override
    @Transactional(rollbackFor = Exception.class)
    public int updateDriveSchoolCar(DriveSchoolCar driveSchoolCar)
    {
        if (StringUtils.isNotEmpty(driveSchoolCar.getCoachId())){
            coachService.updateSchoolCoachCarId(driveSchoolCar.getCoachId(), driveSchoolCar.getCarNo());
        }
        return driveSchoolCarMapper.updateById(driveSchoolCar);
    }*/

    /**
     * 批量删除车辆信息
     *
     * @param ids 需要删除的车辆信息主键
     * @return 结果
     */
    /*@Override
    public int deleteDriveSchoolCarByIds(Long[] ids)
    {
        return driveSchoolCarMapper.deleteDriveSchoolCarByIds(ids);
    }*/

    /*@Override
    public int deleteDriveSchoolCarByIds(Long[] ids) {
        // 检查所有ID对应的车辆是否存在且未被删除
        List<DriveSchoolCar> carsToDelete = driveSchoolCarMapper.selectList(
                new LambdaQueryWrapper<DriveSchoolCar>()
                        .in(DriveSchoolCar::getId, Arrays.asList(ids))
                        .eq(DriveSchoolCar::getDeleted, 0)
        );
        if (carsToDelete.size() != ids.length) {
            throw new RuntimeException("部分车辆不存在或已被删除");
        }

        Map<String, List<String>> coachCarMap = carsToDelete.stream()
                .filter(car -> StringUtils.isNotEmpty(car.getCoachId()))
                .collect(Collectors.groupingBy(
                        DriveSchoolCar::getCoachId,
                        Collectors.mapping(DriveSchoolCar::getCarNo, Collectors.toList())
                ));

        coachCarMap.forEach((coachId, carNos) -> {
            DlDriveSchoolCoach coach = coachService.getById(coachId);
            if (coach != null && StringUtils.isNotEmpty(coach.getCarId())) {
                List<String> remainingCars = Arrays.stream(coach.getCarId().split(";"))
                        .filter(carNo -> !carNos.contains(carNo))
                        .collect(Collectors.toList());

                String updatedCarIds = remainingCars.isEmpty() ? null : String.join(";", remainingCars);

                DlDriveSchoolCoach updateCoach = new DlDriveSchoolCoach();
                updateCoach.setId(coachId);
                updateCoach.setCarId(updatedCarIds);
                coachService.updateById(updateCoach);
            }
        });

        return driveSchoolCarMapper.deleteDriveSchoolCarByIds(ids);
    }*/
    @Override
    public int deleteDriveSchoolCarByIds(Long[] ids) {
        List<DriveSchoolCar> carsToDelete = driveSchoolCarMapper.selectBatchIds(Arrays.asList(ids));
        if (carsToDelete.size() != ids.length) {
            throw new RuntimeException("部分车辆不存在或已被删除");
        }

        for (DriveSchoolCar car : carsToDelete) {
            if (StringUtils.isNotEmpty(car.getCoachId())) {
                coachService.removeCarFromCoach(car.getCoachId(), car.getCarNo());
            }
        }

        return driveSchoolCarMapper.deleteDriveSchoolCarByIds(ids);
    }

    /**
     * 删除车辆信息信息
     *
     * @param id 车辆信息主键
     * @return 结果
     */
    @Override
    public int deleteDriveSchoolCarById(Long id)
    {
        // 获取要删除的车辆信息
        DriveSchoolCar carToDelete = driveSchoolCarMapper.selectById(id);
        if (carToDelete == null) {
            throw new RuntimeException("车辆不存在或已被删除");
        }

        // 如果车辆有关联教练，从教练的关联车牌中移除该车牌
        if (StringUtils.isNotEmpty(carToDelete.getCoachId())) {
            coachService.removeCarFromCoach(carToDelete.getCoachId(), carToDelete.getCarNo());
        }

        // 删除车辆
        return driveSchoolCarMapper.deleteById(id);
    }

    @Override
    public String importCars(List<DriveSchoolCar> carsList, boolean updateSupport, String operName) throws Exception {
        if (CollectionUtils.isEmpty(carsList)){
            throw new Exception("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        for (DriveSchoolCar driveSchoolCar : carsList) {
            DriveSchoolCar driveSchoolCar1 = driveSchoolCarMapper.selectByCarNo(driveSchoolCar.getCarNo());
            if (ObjectUtils.isEmpty(driveSchoolCar1)){
                driveSchoolCarMapper.insert(driveSchoolCar);
                successNum++;
            }else {
                failureNum++;
            }
        }
        return "数据已全部导入成功！";
    }

    @Override
    public DriveSchoolCar selectByCoachId(Long coachId) {
        LambdaQueryWrapper<DriveSchoolCar> queryWrapper = new LambdaQueryWrapper<DriveSchoolCar>()
                .eq(DriveSchoolCar::getUserId,coachId)
                .orderByDesc(BaseDO::getCreateTime);
        List<DriveSchoolCar> list = this.list(queryWrapper);
        return list.isEmpty()?null:list.get(0);
    }

    /**
     * 根据教练用户id获取车牌号码列表
     */
    @Override
    public List<DriveSchoolCar> getCarNoByCoachUserId(Long userId) {
        return driveSchoolCarMapper.selectList(
                new LambdaQueryWrapper<DriveSchoolCar>()
                        .eq(DriveSchoolCar::getUserId, userId)
                        .eq(DriveSchoolCar::getDeleted, 0)
                        .orderByDesc(DriveSchoolCar::getCreateTime)
        );
    }

    @Override
    public List<DriveSchoolCar> getCarNoAll() {
        return driveSchoolCarMapper.selectList(
                new LambdaQueryWrapper<DriveSchoolCar>()
                        .eq(DriveSchoolCar::getDeleted, 0)
                        .orderByDesc(DriveSchoolCar::getCreateTime)
        );
    }

    /**
     * 根据教练id获取车牌号
     */
    @Override
    public List<DriveSchoolCar> getCarNoByCoachId(Long coachId) {
        return driveSchoolCarMapper.selectList(
                new LambdaQueryWrapper<DriveSchoolCar>()
                        .eq(DriveSchoolCar::getUserId, coachId)
                        .eq(DriveSchoolCar::getDeleted, 0)
                        .orderByDesc(DriveSchoolCar::getCreateTime)
        );
    }


    /**
     * 根据车牌号获取教练信息
     */
    @Override
    public List<DriveSchoolCar> getCoachInfoByCarNo(String carNo) {
        return driveSchoolCarMapper.selectList(
                new LambdaQueryWrapper<DriveSchoolCar>()
                        .eq(DriveSchoolCar::getCarNo, carNo)
                        .eq(DriveSchoolCar::getDeleted, 0)
                        .orderByDesc(DriveSchoolCar::getCreateTime)
        );
    }
}
