package com.ai.da.service.impl;

import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.mapper.primary.CollectionSortMapper;
import com.ai.da.mapper.primary.entity.CollectionSort;
import com.ai.da.model.dto.CollectionSortDTO;
import com.ai.da.model.enums.CollectionType;
import com.ai.da.service.CollectionSortService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public class CollectionSortServiceImpl extends ServiceImpl<CollectionSortMapper, CollectionSort> implements CollectionSortService {

    @Override
    public CollectionSort addCollectionSort(Long relationId, String relationType, Long projectId, Long collectionSortParentId) {
        CollectionSort collectionSort = queryCollectionSortByRelation(relationId, relationType, projectId);
        if (Objects.nonNull(collectionSort)) {
            return collectionSort;
        }

        CollectionSort userLikeSort = new CollectionSort();
//        userLikeSort.setUserLikeGroupId(userGroupId);
//        userLikeSort.setUserLikeId(relationId);
        userLikeSort.setProjectId(projectId);
        userLikeSort.setRelationId(relationId);
        userLikeSort.setRelationType(relationType);

        if (null != collectionSortParentId) {
            userLikeSort.setParentId(collectionSortParentId);
        }
        userLikeSort.setCreateTime(LocalDateTime.now());
        int retryCount = 3;
        while (retryCount-- > 0) {
            try {
                int sort = getNextSort(projectId, collectionSortParentId);
                userLikeSort.setSort(sort);
                baseMapper.insert(userLikeSort);
                return userLikeSort;
            } catch (DuplicateKeyException e) {
                // 如果发生唯一约束冲突，重试
                if (retryCount == 0) {
                    throw new BusinessException("获取排序号失败，请重试");
                }
            }
        }
        throw new BusinessException("获取排序号失败");
    }

    public CollectionSort queryCollectionSortByRelation(Long relationId, String relationType, Long projectId) {
        QueryWrapper<CollectionSort> qw = new QueryWrapper<>();
        qw.lambda().eq(CollectionSort::getProjectId, projectId).
                eq(CollectionSort::getRelationId, relationId).
                eq(CollectionSort::getRelationType, relationType);
        return baseMapper.selectOne(qw);
    }

    /*@Override
    public int getNextSort(Long projectId, Long parentId) {
        QueryWrapper<CollectionSort> qw = new QueryWrapper<>();
        qw.lambda().eq(CollectionSort::getProjectId, projectId);
        if (null != parentId) {
            qw.lambda().eq(CollectionSort::getParentId, parentId);
        }else {
            qw.lambda().isNull(CollectionSort::getParentId);
        }
        List<CollectionSort> userLikeSorts = baseMapper.selectList(qw);
        if (CollectionUtils.isEmpty(userLikeSorts)) {
            return 1;
        }
        return userLikeSorts.size() + 1;
    }*/

    // 添加唯一约束
    // ALTER TABLE collection_sort ADD UNIQUE KEY sort (project_id, parent_id, sort);
    public int getNextSort(Long projectId, Long parentId) {
        int retryCount = 3;
        while (retryCount-- > 0) {
            try {
                int maxSort = Math.toIntExact(getMaxSortFromDB(projectId, parentId));
                return maxSort + 1;
            } catch (DuplicateKeyException e) {
                // 如果发生唯一约束冲突，重试
                if (retryCount == 0) {
                    throw new BusinessException("获取排序号失败，请重试");
                }
            }
        }
        throw new BusinessException("获取排序号失败");
    }

    private Integer getMaxSortFromDB(Long projectId, Long parentId) {
        QueryWrapper<CollectionSort> qw = new QueryWrapper<>();
        qw.select("COALESCE(MAX(sort), 0) as maxSort")
                .eq("project_id", projectId);

        if (null != parentId) {
            qw.eq("parent_id", parentId);
        } else {
            qw.isNull("parent_id");
        }

        Map<String, Object> result = baseMapper.selectMaps(qw).get(0);
        Object maxSortObj = result.get("maxSort");
        if (maxSortObj instanceof Long) {
            return ((Long) maxSortObj).intValue();
        } else if (maxSortObj instanceof Integer) {
            return (Integer) maxSortObj;
        }
        return (Integer) result.get("maxSort");
    }

    @Override
    /*public void deleteCollectionSort(Long relationId, String relationType, Long projectId, Long parentId) {
        QueryWrapper<CollectionSort> qw = new QueryWrapper<>();
        qw.lambda().eq(CollectionSort::getProjectId, projectId);
        if (null != parentId) {
            qw.lambda().eq(CollectionSort::getParentId, parentId);
        } else {
            qw.lambda().isNull(CollectionSort::getParentId);
        }
        qw.lambda().orderByDesc(CollectionSort::getSort);
        List<CollectionSort> userLikeSorts = baseMapper.selectList(qw);
        CollectionSort userLikeSort = getUserLikeSortByUserLikeId(relationId, relationType, projectId);
        if (Objects.nonNull(userLikeSort)) {
            Long userLikeSortId = userLikeSort.getId();
            for (CollectionSort likeSort : userLikeSorts) {
                if (Objects.equals(likeSort.getId(), userLikeSortId)) {
                    baseMapper.deleteById(likeSort);
                    deleteByParentId(likeSort.getId());
                    break;
                } else {
                    likeSort.setSort(likeSort.getSort() - 1);
                    baseMapper.updateById(likeSort);
                }
            }
        }
    }*/
    @Transactional
    public void deleteCollectionSort(Long relationId, String relationType, Long projectId, Long parentId) {
        // 1. 找到要删除的记录
        CollectionSort userLikeSort = getUserLikeSortByUserLikeId(relationId, relationType, projectId, null);
        if (Objects.isNull(userLikeSort)) {
            return;
        }

        Long userLikeSortId = userLikeSort.getId();
        int deletedSort = userLikeSort.getSort();

        // 2. 先删除记录
        baseMapper.deleteById(userLikeSortId);
        deleteByParentId(userLikeSortId);

        // 3. 批量更新排序号（使用自定义Mapper方法）
//        baseMapper.decrementSortAfterDelete(projectId, parentId, deletedSort);
        resort(projectId, parentId);
    }

    private void deleteByParentId(Long parentId) {
        QueryWrapper<CollectionSort> qw = new QueryWrapper<>();
        qw.lambda().eq(CollectionSort::getParentId, parentId);
        baseMapper.delete(qw);
    }

    @Override
    public CollectionSort getUserLikeSortByUserLikeId(Long relationId, String relationType, Long projectId, Long parentId) {
        QueryWrapper<CollectionSort> qw = new QueryWrapper<>();
        qw.lambda().eq(CollectionSort::getRelationId, relationId);
        qw.lambda().eq(CollectionSort::getRelationType, relationType);
        qw.lambda().eq(CollectionSort::getProjectId, projectId);
        if (Objects.nonNull(parentId)){
            qw.lambda().eq(CollectionSort::getParentId, parentId);
        }
        CollectionSort userLikeSort = baseMapper.selectOne(qw);
        return userLikeSort;
    }

    @Override
    public Boolean sort(CollectionSortDTO userLikeSortDTO) {
        for (CollectionSort userLikeSort : userLikeSortDTO.getUserLikeSortList()) {
            baseMapper.updateById(userLikeSort);
        }
        return Boolean.TRUE;
    }

    /**
     * 只有当使用子集中的元素进行生成时，才需要重新排序
     *
     * @param childId        生成元素的id
     * @param parentId       父级id
     * @param relationType   生成功能
     * @param userLikeSortId 子集排序表中的id
     */
    @Transactional
    @Override
    public Integer rearrangeChildSort(Long childId, String relationType, Long parentId, Long userLikeSortId) {
        // 对父级元素进行生成不需要重新排序
        if (Objects.isNull(userLikeSortId) || parentId.equals(userLikeSortId)) {
            return null;
        }

        // 相同的relation_id，relation_type重复排序，有脏数据
        List<CollectionSort> childList = baseMapper.selectList(
                new QueryWrapper<CollectionSort>().eq("relation_id", childId)
                        .eq("relation_type", relationType).orderByDesc("id"));
        if (childList.isEmpty()) {
            return null;
        } else if (childList.size() > 1) {
            log.error("CollectionSort表中，relation_id为{}，relation_type为{}的记录有 {} 条，", childId, relationType, childList.size());
        }
        CollectionSort child = childList.get(0);
        CollectionSort collectionSort = baseMapper.selectById(userLikeSortId);
        if (Objects.isNull(collectionSort)) {
            return null;
        }
        child.setSort(collectionSort.getSort());
        // 原来排序的大于等于userLikeSortId的排序的，都要＋1
        baseMapper.increaseGenerateSortAbove(parentId, /*relationType,*/ collectionSort.getSort() - 1);
//        resort(collectionSort.getProjectId(), parentId);
        // 当前的生成结果则填入userLikeSortId的排序位置
        child.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(child);
        return collectionSort.getSort();
    }

    @Override
    public Long getParentIdByElementIdAndElementType(Long elementId, String elementType) {
        QueryWrapper<CollectionSort> qw = new QueryWrapper<>();
        qw.lambda().eq(CollectionSort::getRelationId, elementId);

        elementType = transElementType(elementType);
        qw.lambda().eq(CollectionSort::getRelationType, elementType);
        List<CollectionSort> collectionSortList = baseMapper.selectList(qw);
        if (CollectionUtils.isEmpty(collectionSortList)) {
            return null;
        }
        CollectionSort collectionSort = collectionSortList.get(0);
        Long parentId = collectionSort.getParentId();
        if (parentId == null) {
            return collectionSort.getId();
        }
        return collectionSort.getParentId();
    }

    private String transElementType(String elementType) {
        if (elementType.equals("DesignOutfit")) {
            return CollectionType.DESIGN.getValue();
        } else if (elementType.equals("ToProductImage")) {
            return CollectionType.TO_PRODUCT_IMAGE.getValue();
        } else if (elementType.equals("PoseTransfer")) {
            return CollectionType.POSE_TRANSFORM.getValue();
        } else {
            return "";
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void resort(Long projectId, Long parentId) {

        LambdaQueryWrapper<CollectionSort> wrapper = new LambdaQueryWrapper<CollectionSort>()
                .eq(CollectionSort::getProjectId, projectId)
                .orderByAsc(CollectionSort::getSort);

        if (parentId != null) {
            wrapper.eq(CollectionSort::getParentId, parentId);
        } else {
            wrapper.isNull(CollectionSort::getParentId);
        }
        // 2. 查询同组数据，按原排序升序
        List<CollectionSort> list = baseMapper.selectList(wrapper);

        // 3. 重新编号 sort，从 1 开始
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setSort(i + 1);
        }

        // 4. 批量更新
        if (!list.isEmpty()) {
            updateBatchById(list);
        }
    }

    /**
     * 批量更新（如果你使用 MyBatis-Plus，可以继承 ServiceImpl 来用内置的 updateBatchById）
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateBatchById(List<CollectionSort> list) {
        for (CollectionSort item : list) {
            baseMapper.updateById(item);
        }
    }
}
