package com.clx.performance.service.impl.collect;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clx.performance.dao.collect.CollectDriverTransportIntentionDao;
import com.clx.performance.dao.collect.CollectDriverTransportIntentionRecordDao;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.enums.ResultEnum;
import com.clx.performance.enums.collect.CollectDriverTransportIntentionEnum;
import com.clx.performance.model.collect.CollectDriverTransportIntention;
import com.clx.performance.model.collect.CollectDriverTransportIntentionRecord;
import com.clx.performance.param.app.collect.*;
import com.clx.performance.service.collect.CollectDriverTransportIntentionService;
import com.clx.performance.struct.collect.CollectDriverTransportIntentionDaoStruct;
import com.clx.performance.struct.collect.CollectDriverTransportIntentionRecordDaoStruct;
import com.clx.performance.vo.pc.collect.CarrierDriverCollectTransportIntentionRecordVO;
import com.clx.performance.vo.pc.collect.CarrierDriverCollectTransportIntentionVO;
import com.msl.common.base.Optional;
import com.msl.common.exception.ServiceSystemException;
import com.msl.user.utils.TokenUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author kavin
 * Date 2024-10-17
 * Time 16:26
 */
@Service
@Slf4j
@AllArgsConstructor
public class CollectDriverTransportIntentionServiceImpl implements CollectDriverTransportIntentionService {

    private final CollectDriverTransportIntentionDao collectDriverTransportIntentionDao;
    private final CollectDriverTransportIntentionRecordDao collectDriverTransportIntentionRecordDao;
    private final CollectDriverTransportIntentionDaoStruct collectDriverTransportIntentionDaoStruct;
    private final CollectDriverTransportIntentionRecordDaoStruct collectDriverTransportIntentionRecordDaoStruct;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveCarrierDriverCollectTransportIntention(CarrierDriverCollectTransportIntentionAddParam param) {

        if (Objects.isNull(param) || param.getCollectIntentionRecordList().isEmpty()) {
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND);
        }
        // 查询当前名字的数据是否存在
        List<CollectDriverTransportIntention> returnList = collectDriverTransportIntentionDao.listByField(CollectDriverTransportIntention::getCollectName, param.getCollectName());
        if (!CollectionUtils.isEmpty(returnList)) {
            throw new ServiceSystemException(PerformanceResultEnum.DATA_REPEAT);
        }

        CollectDriverTransportIntention collectDriverTransportIntention = new CollectDriverTransportIntention();
        // 默认排序
        collectDriverTransportIntention.setSortNo(0L);
        collectDriverTransportIntention.setCollectName(param.getCollectName());
        collectDriverTransportIntention.setCollectDescribe(param.getCollectDescribe());
        collectDriverTransportIntention.setCollectCheckType(param.getCollectCheckType());
        collectDriverTransportIntention.setCollectType(param.getCollectType());
        collectDriverTransportIntention.setCreateUserNo(TokenUtil.getLoginUserInfo().getUserNo());
        collectDriverTransportIntention.setCreateUserName(TokenUtil.getLoginUserInfo().getUserName());
        // 逻辑删除状态，默认未删除
        collectDriverTransportIntention.setDeleteStatus(CollectDriverTransportIntentionEnum
                .DeleteStatusType.DELETE_STATUS_NO.getCode());
        // 状态，默认启用
        collectDriverTransportIntention.setStatus(CollectDriverTransportIntentionEnum
                .StatusType.STATUS_ENABLE.getCode());
        collectDriverTransportIntention.setCreateTime(LocalDateTime.now());
        collectDriverTransportIntention.setModifiedTime(LocalDateTime.now());
        // 1.保存信息主表
        collectDriverTransportIntentionDao.saveEntity(collectDriverTransportIntention);

        log.info("saveCarrierDriverCollectTransportIntention id:{}", collectDriverTransportIntention.getId());
        Integer id = collectDriverTransportIntention.getId();

        List<CollectDriverTransportIntentionRecord> recordList = new ArrayList<>();
        for (CarrierDriverCollectTransportIntentionRecordParam recordParam : param.getCollectIntentionRecordList()) {
            CollectDriverTransportIntentionRecord record = new CollectDriverTransportIntentionRecord();
            record.setCollectDriverTransportIntentionId(id);
            record.setCollectRecordSort(CollectDriverTransportIntentionEnum.DefaultSortType.DEFAULT_SORT.getCode());
            record.setCollectRecordName(recordParam.getCollectRecordName());
            record.setCreateUserNo(TokenUtil.getLoginUserInfo().getUserNo());
            record.setCreateUserName(TokenUtil.getLoginUserInfo().getUserName());
            record.setDeleteStatus(CollectDriverTransportIntentionEnum
                    .DeleteStatusType.DELETE_STATUS_NO.getCode());
            record.setCreateTime(LocalDateTime.now());
            record.setModifiedTime(LocalDateTime.now());
            recordList.add(record);
        }
        // 2.保存子表选项信息子表
        boolean result = collectDriverTransportIntentionRecordDao.saveBatchList(recordList);
        log.info("saveCarrierDriverCollectTransportIntention result:{}", result);

        return result ? 1 : 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateCarrierDriverCollectTransportIntention(CarrierDriverCollectTransportIntentionEditParam param) {
        if (Objects.isNull(param) || param.getCollectIntentionRecordList().isEmpty()) {
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND);
        }
        // 1.修改主表信息
        CollectDriverTransportIntention updateCollectDriverTransportIntention = new CollectDriverTransportIntention();
        updateCollectDriverTransportIntention.setId(param.getId());
        updateCollectDriverTransportIntention.setCollectName(param.getCollectName());
        updateCollectDriverTransportIntention.setCollectDescribe(param.getCollectDescribe());
        updateCollectDriverTransportIntention.setCollectCheckType(param.getCollectCheckType());
        updateCollectDriverTransportIntention.setModifiedTime(LocalDateTime.now());
        collectDriverTransportIntentionDao.updateEntityByKey(updateCollectDriverTransportIntention);
        // 2.删除子表信息
        collectDriverTransportIntentionRecordDao
                .deleteInField(CollectDriverTransportIntentionRecord::getCollectDriverTransportIntentionId,
                        Collections.singletonList(param.getId()));
        // 3.保存子表信息
        List<CollectDriverTransportIntentionRecord> recordList = new ArrayList<>();
        for (CarrierDriverCollectTransportIntentionRecordParam recordParam : param.getCollectIntentionRecordList()) {
            CollectDriverTransportIntentionRecord record = new CollectDriverTransportIntentionRecord();
            record.setCollectDriverTransportIntentionId(param.getId());
            record.setCollectRecordSort(CollectDriverTransportIntentionEnum.DefaultSortType.DEFAULT_SORT.getCode());
            record.setCollectRecordName(recordParam.getCollectRecordName());
            record.setCreateUserNo(TokenUtil.getLoginUserInfo().getUserNo());
            record.setCreateUserName(TokenUtil.getLoginUserInfo().getUserName());
            record.setDeleteStatus(CollectDriverTransportIntentionEnum
                    .DeleteStatusType.DELETE_STATUS_NO.getCode());
            record.setCreateTime(LocalDateTime.now());
            record.setModifiedTime(LocalDateTime.now());
            recordList.add(record);
        }
        // 2.保存子表选项信息子表
        boolean result = collectDriverTransportIntentionRecordDao.saveBatchList(recordList);
        log.info("updateCarrierDriverCollectTransportIntention result:{}", result);

        return result ? 1 : 0;
    }

    @Override
    public Integer enableCarrierDriverCollectTransportIntention(CarrierDriverCollectTransportIntentionEnableParam param) {
        CollectDriverTransportIntention updateCollectDriverTransportIntention = new CollectDriverTransportIntention();
        updateCollectDriverTransportIntention.setId(param.getId());
        updateCollectDriverTransportIntention.setStatus(param.getStatus());
        return collectDriverTransportIntentionDao.updateEntityByKey(updateCollectDriverTransportIntention) ? 1 : 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteCarrierDriverCollectTransportIntention(CarrierDriverCollectTransportIntentionDetailParam param) {
        if (Objects.isNull(param)) {
            log.info("deleteCarrierDriverCollectTransportIntention param is null");
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND);
        }

        // 1.删除主表信息
        collectDriverTransportIntentionDao.deleteByField(CollectDriverTransportIntention::getId, param.getId());
        // 2.删除子表信息
        boolean result = collectDriverTransportIntentionRecordDao
                .deleteByField(CollectDriverTransportIntentionRecord::getCollectDriverTransportIntentionId, param.getId());
        return result ? 1 : 0;
    }

    @Override
    public IPage<CarrierDriverCollectTransportIntentionVO> listCarrierDriverCollectTransportIntention(CarrierDriverCollectTransportIntentionListParam param) {
        IPage<CollectDriverTransportIntention> page = collectDriverTransportIntentionDao.listByCondition(param);
        List<CarrierDriverCollectTransportIntentionVO> list = collectDriverTransportIntentionDaoStruct.covertList(page.getRecords());
        return new Page<CarrierDriverCollectTransportIntentionVO>().setPages(page.getPages()).setTotal(page.getTotal()).setRecords(list);
    }

    @Override
    public List<CarrierDriverCollectTransportIntentionRecordVO> detailCarrierDriverCollectTransportIntention(CarrierDriverCollectTransportIntentionDetailParam param) {
        List<CollectDriverTransportIntentionRecord> list = collectDriverTransportIntentionRecordDao
                .listByField(CollectDriverTransportIntentionRecord::getCollectDriverTransportIntentionId, param.getId());
        List<CarrierDriverCollectTransportIntentionRecordVO> listVO = collectDriverTransportIntentionRecordDaoStruct.covertList(list);
        return listVO;
    }

    @Override
    public IPage<CarrierDriverCollectTransportIntentionVO> listCarrierDriverCollectTransportIntentionAll(AppCarrierDriverCollectTransportIntentionParam param) {
        // 1.查询所有已启用的信息
        IPage<CollectDriverTransportIntention> page = collectDriverTransportIntentionDao.listEnableInfo(param);
        if (CollectionUtils.isEmpty(page.getRecords())) {
            log.info("listCarrierDriverCollectTransportIntentionAll page is null");
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND);
        }
        List<CarrierDriverCollectTransportIntentionVO> listVO = collectDriverTransportIntentionDaoStruct.covertList(page.getRecords());
        // 筛选主键id
        List<Integer> ids = listVO.stream().map(CarrierDriverCollectTransportIntentionVO::getId).toList();
        // 2.关联子表
        List<CollectDriverTransportIntentionRecord> recordList = collectDriverTransportIntentionRecordDao
                .listInField(CollectDriverTransportIntentionRecord::getCollectDriverTransportIntentionId, ids);
        if (CollectionUtils.isEmpty(recordList)) {
            log.info("listCarrierDriverCollectTransportIntentionAll recordList is null");
            throw new ServiceSystemException(PerformanceResultEnum.DATA_NOT_FIND);
        }

        List<CarrierDriverCollectTransportIntentionRecordVO> recordVOList
                = collectDriverTransportIntentionRecordDaoStruct.covertList(recordList);

        // 构建map
        Map<Integer, List<CarrierDriverCollectTransportIntentionRecordVO>> recordVoMap =
                recordVOList.stream().collect(Collectors
                        .groupingBy(CarrierDriverCollectTransportIntentionRecordVO::getCollectDriverTransportIntentionId));

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime currentTime = LocalDateTime.now();
        // 遍历主编数据，构建子表数据
        for (CarrierDriverCollectTransportIntentionVO vo : listVO) {
            // 赋值系统时间
            vo.setCurrentTime(formatter.format(currentTime));
            if (recordVoMap.containsKey(vo.getId())) {
                vo.setCollectIntentionRecordList(recordVoMap.get(vo.getId()));
            }
        }
        return new Page<CarrierDriverCollectTransportIntentionVO>().setPages(page.getPages()).setTotal(page.getTotal()).setRecords(listVO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateAdjustOrder(Integer adjustOrderId, Integer adjustOrderBeforeId) {
        Optional<CollectDriverTransportIntention> one = collectDriverTransportIntentionDao.getEntityByKey(adjustOrderId);
        //如果上调，这条记录传的是移动数据后面的记录id，如果下调，这条记录传的是移动数据前面的记录id
        Optional<CollectDriverTransportIntention> two = collectDriverTransportIntentionDao.getEntityByKey(adjustOrderBeforeId);
        if (!one.isPresent() || !two.isPresent()) {
            throw new ServiceSystemException(ResultEnum.DATA_NOT_FIND);
        }
        boolean isUp = false;
        //通过seq判断是上调还是下调
        if (one.get().getSortNo() < two.get().getSortNo()) {
            isUp = true;
        }
        //上调：大于two 这条记录的seq + 1 ； 下调：大于等于two这条记录的seq + 1 ;
        collectDriverTransportIntentionDao.updateRecordOrder(two.get().getSortNo(), isUp);
        if (isUp) {   //上调
            //调整的记录使用 two 的seq + 1;
            CollectDriverTransportIntention updateOne = new CollectDriverTransportIntention();
            updateOne.setId(one.get().getId());
            updateOne.setSortNo(two.get().getSortNo() + 1);
            collectDriverTransportIntentionDao.updateEntityByKey(updateOne);
        } else {    //下调
            //调整的记录使用 two 的seq;
            CollectDriverTransportIntention updateOne = new CollectDriverTransportIntention();
            updateOne.setId(one.get().getId());
            updateOne.setSortNo(two.get().getSortNo());
            collectDriverTransportIntentionDao.updateEntityByKey(updateOne);
        }
    }
}
