package com.starry.admin.modules.media.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.media.entity.PlayMediaEntity;
import com.starry.admin.modules.media.enums.MediaOwnerType;
import com.starry.admin.modules.media.enums.MediaStatus;
import com.starry.admin.modules.media.mapper.PlayMediaMapper;
import com.starry.admin.modules.media.service.IPlayMediaService;
import java.util.*;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class PlayMediaServiceImpl extends ServiceImpl<PlayMediaMapper, PlayMediaEntity>
        implements IPlayMediaService {

    @Override
    public List<PlayMediaEntity> listByOwner(String ownerType, String ownerId) {
        return listByOwner(ownerType, ownerId, null);
    }

    @Override
    public List<PlayMediaEntity> listByOwner(String ownerType, String ownerId, Collection<String> statuses) {
        LambdaQueryWrapper<PlayMediaEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PlayMediaEntity::getOwnerType, ownerType)
                .eq(PlayMediaEntity::getOwnerId, ownerId)
                .orderByAsc(PlayMediaEntity::getOrderIndex)
                .orderByDesc(PlayMediaEntity::getCreatedTime);
        if (CollectionUtil.isNotEmpty(statuses)) {
            wrapper.in(PlayMediaEntity::getStatus, statuses);
        }
        return this.list(wrapper);
    }

    @Override
    public List<PlayMediaEntity> listApprovedByOwner(String ownerType, String ownerId) {
        return listByOwner(ownerType, ownerId, Collections.singleton(MediaStatus.READY.getCode()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PlayMediaEntity normalizeAndSave(PlayMediaEntity entity) {
        Assert.notNull(entity, "媒资信息不能为空");
        Assert.isTrue(StrUtil.isNotBlank(entity.getOwnerId()), "媒资归属ID不能为空");
        // ownerType 默认 clerk
        if (StrUtil.isBlank(entity.getOwnerType())) {
            entity.setOwnerType(MediaOwnerType.CLERK);
        }
        if (entity.getOrderIndex() == null) {
            entity.setOrderIndex(resolveNextOrderIndex(entity.getOwnerType(), entity.getOwnerId()));
        }
        if (StrUtil.isBlank(entity.getStatus())) {
            entity.setStatus(MediaStatus.UPLOADED.getCode());
        }
        boolean saved = this.save(entity);
        if (!saved) {
            throw new CustomException("媒资保存失败");
        }
        return entity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrder(String ownerType, String ownerId, List<String> orderedIds) {
        List<PlayMediaEntity> mediaList = listByOwner(ownerType, ownerId);
        if (CollectionUtil.isEmpty(mediaList)) {
            return;
        }
        Map<String, PlayMediaEntity> mediaById = mediaList.stream()
                .collect(Collectors.toMap(PlayMediaEntity::getId, item -> item));
        Set<String> keepSet = new LinkedHashSet<>();
        if (CollectionUtil.isNotEmpty(orderedIds)) {
            keepSet.addAll(orderedIds);
        }
        List<PlayMediaEntity> updates = new ArrayList<>();
        int index = 0;
        for (String mediaId : keepSet) {
            PlayMediaEntity entity = mediaById.get(mediaId);
            if (entity == null) {
                throw new CustomException("媒资不存在或已被删除");
            }
            entity.setOrderIndex(index++);
            if (MediaStatus.REJECTED.getCode().equals(entity.getStatus())) {
                entity.setStatus(MediaStatus.READY.getCode());
            }
            updates.add(entity);
        }
        // 其他未保留的标记为 rejected
        for (PlayMediaEntity entity : mediaList) {
            if (!keepSet.contains(entity.getId())
                    && !MediaStatus.REJECTED.getCode().equals(entity.getStatus())) {
                entity.setStatus(MediaStatus.REJECTED.getCode());
                entity.setOrderIndex(0);
                updates.add(entity);
            }
        }
        if (CollectionUtil.isNotEmpty(updates)) {
            this.updateBatchById(updates);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void softDelete(String ownerType, String ownerId, String mediaId) {
        PlayMediaEntity entity = this.getById(mediaId);
        if (entity == null) {
            return;
        }
        if (!ownerType.equals(entity.getOwnerType()) || !ownerId.equals(entity.getOwnerId())) {
            throw new CustomException("无权删除该媒资");
        }
        entity.setStatus(MediaStatus.REJECTED.getCode());
        entity.setOrderIndex(0);
        this.updateById(entity);
    }

    private int resolveNextOrderIndex(String ownerType, String ownerId) {
        LambdaQueryWrapper<PlayMediaEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PlayMediaEntity::getOwnerType, ownerType)
                .eq(PlayMediaEntity::getOwnerId, ownerId)
                .ne(PlayMediaEntity::getStatus, MediaStatus.REJECTED.getCode())
                .orderByDesc(PlayMediaEntity::getOrderIndex)
                .last("limit 1");
        PlayMediaEntity last = this.getOne(wrapper, false);
        if (last == null || last.getOrderIndex() == null) {
            return 0;
        }
        return last.getOrderIndex() + 1;
    }
}
