package com.hotent.project.manager.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hotent.base.manager.impl.BaseManagerImpl;
import com.hotent.base.util.StringUtil;
import com.hotent.project.dao.CostProjectTaskMaterialSummaryDao;
import com.hotent.project.manager.CostProjectTaskMaterialSummaryDetailManager;
import com.hotent.project.manager.CostProjectTaskMaterialSummaryManager;
import com.hotent.project.model.CostProjectTaskMaterialSummaryDetail;
import com.hotent.project.model.CostProjectTaskMaterialSummary;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 资料归纳主表 服务实现类
 *
 * @company 山西清众科技股份有限公司
 * @author 超级管理员
 * @since 2025-01-27
 */
@Service
public class CostProjectTaskMaterialSummaryManagerImpl extends BaseManagerImpl<CostProjectTaskMaterialSummaryDao, CostProjectTaskMaterialSummary> implements CostProjectTaskMaterialSummaryManager {

    @Autowired
    private CostProjectTaskMaterialSummaryDetailManager costProjectTaskMaterialSummaryDetailManager;

    @Override
    public List<CostProjectTaskMaterialSummary> listByTaskId(String taskId) {
        if (StringUtil.isEmpty(taskId)) {
            return java.util.Collections.emptyList();
        }

        // 查询主表列表，过滤掉封面(-1)、目录(-2)、封底(-3)
        LambdaQueryWrapper<CostProjectTaskMaterialSummary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostProjectTaskMaterialSummary::getTaskId, taskId)
                .and(w -> w.isNull(CostProjectTaskMaterialSummary::getMaterialOrderNum)
                        .or()
                        .ge(CostProjectTaskMaterialSummary::getMaterialOrderNum, 0))
                .orderByAsc(CostProjectTaskMaterialSummary::getMaterialOrderNum);

        List<CostProjectTaskMaterialSummary> summaryList = this.list(queryWrapper);

        // 填充明细列表
        fillDetailList(summaryList);

        return summaryList;
    }

    @Override
    public List<CostProjectTaskMaterialSummary> listAllByTaskId(String taskId) {
        if (StringUtil.isEmpty(taskId)) {
            return java.util.Collections.emptyList();
        }

        // 查询全部主表列表（包含封面/目录/封底）
        LambdaQueryWrapper<CostProjectTaskMaterialSummary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostProjectTaskMaterialSummary::getTaskId, taskId)
                .orderByAsc(CostProjectTaskMaterialSummary::getMaterialOrderNum);

        List<CostProjectTaskMaterialSummary> summaryList = this.list(queryWrapper);

        // 填充明细列表
        fillDetailList(summaryList);

        return summaryList;
    }

    @Override
    public CostProjectTaskMaterialSummary getDetail(String id) {
        if (StringUtil.isEmpty(id)) {
            return null;
        }

        CostProjectTaskMaterialSummary summary = this.getById(id);
        if (summary == null) {
            return null;
        }

        // 填充明细列表
        fillDetailList(java.util.Collections.singletonList(summary));

        return summary;
    }

    /**
     * 填充明细列表
     */
    private void fillDetailList(List<CostProjectTaskMaterialSummary> summaryList) {
        if (summaryList == null || summaryList.isEmpty()) {
            return;
        }

        List<String> masterIds = summaryList.stream()
                .map(CostProjectTaskMaterialSummary::getId)
                .collect(Collectors.toList());

        // 批量查询明细
        LambdaQueryWrapper<CostProjectTaskMaterialSummaryDetail> detailQueryWrapper = new LambdaQueryWrapper<>();
        detailQueryWrapper.in(CostProjectTaskMaterialSummaryDetail::getMasterId, masterIds)
                .orderByAsc(CostProjectTaskMaterialSummaryDetail::getOrderNum);

        List<CostProjectTaskMaterialSummaryDetail> allDetails = costProjectTaskMaterialSummaryDetailManager.list(detailQueryWrapper);

        // 按masterId分组
        java.util.Map<String, List<CostProjectTaskMaterialSummaryDetail>> detailMap = allDetails.stream()
                .collect(Collectors.groupingBy(CostProjectTaskMaterialSummaryDetail::getMasterId));

        // 设置到对应的主表
        for (CostProjectTaskMaterialSummary summary : summaryList) {
            List<CostProjectTaskMaterialSummaryDetail> detailList = detailMap.getOrDefault(summary.getId(), java.util.Collections.emptyList());
            summary.setDetailList(detailList);
        }
    }

    @Override
    @Transactional
    public void createOrUpdate(CostProjectTaskMaterialSummary summary) {
        if (summary == null) {
            return;
        }

        this.saveOrUpdate(summary);
    }

    @Override
    @Transactional
    public void saveWithDetails(CostProjectTaskMaterialSummary summary) {
        if (summary == null) {
            return;
        }

        // 1. 保存或更新主表
        boolean isNew = StringUtil.isEmpty(summary.getId());
        this.saveOrUpdate(summary);

        String masterId = summary.getId();

        // 2. 如果不是新增，需要处理明细的删除（前端未传入的明细需要删除）
        java.util.Set<String> incomingDetailIds = new java.util.HashSet<>();
        if (summary.getDetailList() != null && !summary.getDetailList().isEmpty()) {
            summary.getDetailList().stream()
                    .filter(d -> StringUtil.isNotEmpty(d.getId()))
                    .forEach(d -> incomingDetailIds.add(d.getId()));
        }

        // 查询数据库中已存在的明细
        if (!isNew && !incomingDetailIds.isEmpty()) {
            LambdaQueryWrapper<CostProjectTaskMaterialSummaryDetail> existingQueryWrapper = new LambdaQueryWrapper<>();
            existingQueryWrapper.eq(CostProjectTaskMaterialSummaryDetail::getMasterId, masterId);
            List<CostProjectTaskMaterialSummaryDetail> existingDetails = costProjectTaskMaterialSummaryDetailManager.list(existingQueryWrapper);

            // 物理删除不在传入列表中的明细
            for (CostProjectTaskMaterialSummaryDetail existing : existingDetails) {
                if (!incomingDetailIds.contains(existing.getId())) {
                    costProjectTaskMaterialSummaryDetailManager.removeById(existing.getId());
                }
            }
        } else if (!isNew && (summary.getDetailList() == null || summary.getDetailList().isEmpty())) {
            // 如果传入的明细列表为空，物理删除所有明细
            LambdaQueryWrapper<CostProjectTaskMaterialSummaryDetail> deleteQueryWrapper = new LambdaQueryWrapper<>();
            deleteQueryWrapper.eq(CostProjectTaskMaterialSummaryDetail::getMasterId, masterId);
            List<CostProjectTaskMaterialSummaryDetail> allDetails = costProjectTaskMaterialSummaryDetailManager.list(deleteQueryWrapper);
            List<String> detailIds = allDetails.stream()
                    .map(CostProjectTaskMaterialSummaryDetail::getId)
                    .collect(Collectors.toList());
            if (!detailIds.isEmpty()) {
                costProjectTaskMaterialSummaryDetailManager.removeByIds(detailIds);
            }
        }

        // 3. 保存或更新明细列表
        if (summary.getDetailList() != null && !summary.getDetailList().isEmpty()) {
            for (CostProjectTaskMaterialSummaryDetail detail : summary.getDetailList()) {
                detail.setMasterId(masterId);
                detail.setTaskId(summary.getTaskId());

                // 如果明细没有id且没有orderNum，设置orderNum（如果是新增）
                if (StringUtil.isEmpty(detail.getId()) && detail.getOrderNum() == null) {
                    // 查询当前主表下最大的orderNum
                    LambdaQueryWrapper<CostProjectTaskMaterialSummaryDetail> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(CostProjectTaskMaterialSummaryDetail::getMasterId, masterId)
                            .orderByDesc(CostProjectTaskMaterialSummaryDetail::getOrderNum)
                            .last("LIMIT 1");
                    CostProjectTaskMaterialSummaryDetail lastDetail = costProjectTaskMaterialSummaryDetailManager.getOne(queryWrapper);
                    int nextOrderNum = lastDetail != null && lastDetail.getOrderNum() != null ? lastDetail.getOrderNum() + 1 : 1;
                    detail.setOrderNum(nextOrderNum);
                } else if (detail.getOrderNum() == null) {
                    // 如果更新时orderNum为空，设置为1
                    detail.setOrderNum(1);
                }

                costProjectTaskMaterialSummaryDetailManager.saveOrUpdate(detail);
            }
        }
    }

    @Override
    @Transactional
    public void deleteById(String id) {
        if (StringUtil.isEmpty(id)) {
            return;
        }

        // 1. 物理删除所有明细
        LambdaQueryWrapper<CostProjectTaskMaterialSummaryDetail> detailQueryWrapper = new LambdaQueryWrapper<>();
        detailQueryWrapper.eq(CostProjectTaskMaterialSummaryDetail::getMasterId, id);
        List<CostProjectTaskMaterialSummaryDetail> detailList = costProjectTaskMaterialSummaryDetailManager.list(detailQueryWrapper);
        List<String> detailIds = detailList.stream()
                .map(CostProjectTaskMaterialSummaryDetail::getId)
                .collect(Collectors.toList());
        if (!detailIds.isEmpty()) {
            costProjectTaskMaterialSummaryDetailManager.removeByIds(detailIds);
        }

        // 2. 物理删除主表
        this.removeById(id);
    }

    @Override
    @Transactional
    public void sort(String id, String direction) {
        if (StringUtil.isEmpty(id) || StringUtil.isEmpty(direction)) {
            return;
        }

        CostProjectTaskMaterialSummary current = this.getById(id);
        if (current == null) {
            return;
        }

        String taskId = current.getTaskId();

        // 查询同任务下的所有记录，按序号和ID排序
        LambdaQueryWrapper<CostProjectTaskMaterialSummary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostProjectTaskMaterialSummary::getTaskId, taskId)
                .orderByAsc(CostProjectTaskMaterialSummary::getMaterialOrderNum)
                .orderByAsc(CostProjectTaskMaterialSummary::getId);
        List<CostProjectTaskMaterialSummary> list = this.list(queryWrapper);

        // 找到当前位置
        int currentIndex = -1;
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getId().equals(id)) {
                currentIndex = i;
                break;
            }
        }
        if (currentIndex == -1) {
            return;
        }

        // 获取最大序号作为临时序号
        Integer tempOrderNum = list.stream()
                .filter(s -> s.getMaterialOrderNum() != null)
                .map(CostProjectTaskMaterialSummary::getMaterialOrderNum)
                .max(Integer::compareTo)
                .orElse(0) + 10000;

        if ("down".equals(direction) && currentIndex < list.size() - 1) {
            // 下移：与下一个交换
            CostProjectTaskMaterialSummary next = list.get(currentIndex + 1);
            Integer currentOrder = current.getMaterialOrderNum();
            Integer nextOrder = next.getMaterialOrderNum();
            current.setMaterialOrderNum(tempOrderNum);
            this.updateById(current);
            next.setMaterialOrderNum(currentOrder);
            this.updateById(next);
            current.setMaterialOrderNum(nextOrder);
            this.updateById(current);
        } else if ("up".equals(direction) && currentIndex > 0) {
            // 上移：与上一个交换
            CostProjectTaskMaterialSummary prev = list.get(currentIndex - 1);
            Integer currentOrder = current.getMaterialOrderNum();
            Integer prevOrder = prev.getMaterialOrderNum();
            current.setMaterialOrderNum(tempOrderNum);
            this.updateById(current);
            prev.setMaterialOrderNum(currentOrder);
            this.updateById(prev);
            current.setMaterialOrderNum(prevOrder);
            this.updateById(current);
        }
    }

    @Override
    public CostProjectTaskMaterialSummary getArchiveDocument(String taskId, Integer documentType) {
        if (StringUtil.isEmpty(taskId) || documentType == null) {
            return null;
        }

        // 使用负数序号区分卷宗文书：-1=封面，-2=目录，-3=封底
        int orderNum = -documentType;

        LambdaQueryWrapper<CostProjectTaskMaterialSummary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostProjectTaskMaterialSummary::getTaskId, taskId)
                .eq(CostProjectTaskMaterialSummary::getMaterialOrderNum, orderNum);

        return this.getOne(queryWrapper);
    }

}

