package com.tashow.cloud.ai.service.aisample;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleTagPageReqVO;
import com.tashow.cloud.ai.controller.admin.aisample.vo.AiSampleTagSaveReqVO;
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagDO;
import com.tashow.cloud.ai.dal.dataobject.aisample.AiSampleTagGroupDO;
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagGroupMapper;
import com.tashow.cloud.ai.dal.mysql.aisample.AiSampleTagMapper;
import com.tashow.cloud.common.pojo.PageResult;
import com.tashow.cloud.common.util.object.BeanUtils;
import com.tashow.cloud.mybatis.mybatis.core.util.MyBatisUtils;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.Arrays;
import java.util.List;

@Service
@Validated
public class AiSampleTagServiceImpl implements AiSampleTagService {

    private static final Integer ENUM_TYPE = 1;
    private static final Integer DEFAULT_TAG_TYPE = 2;

    @Resource
    private AiSampleTagMapper aiSampleTagMapper;
    @Resource
    private AiSampleTagGroupMapper aiSampleTagGroupMapper;

    @Override
    public Long createAiSampleTag(AiSampleTagSaveReqVO createReqVO) {
        Integer tagType = createReqVO.getTagType() == null ? DEFAULT_TAG_TYPE : createReqVO.getTagType();
        createReqVO.setTagType(tagType);
        if (isEnumType(tagType)) {
            validateEnumTagGroup(createReqVO.getGroupId());
        }

        AiSampleTagDO tag = BeanUtils.toBean(createReqVO, AiSampleTagDO.class);
        aiSampleTagMapper.insert(tag);
        return tag.getId();
    }

    @Override
    public void updateAiSampleTag(AiSampleTagSaveReqVO updateReqVO) {
        AiSampleTagDO existingTag = aiSampleTagMapper.selectById(updateReqVO.getId());
        if (isEnumType(existingTag.getTagType())) {
            if (!existingTag.getTagType().equals(updateReqVO.getTagType())) {
                throw new IllegalArgumentException("Enum tag type cannot be changed");
            }
            if (!existingTag.getGroupId().equals(updateReqVO.getGroupId())) {
                throw new IllegalArgumentException("Enum tag group cannot be changed");
            }
        }
        AiSampleTagDO tag = BeanUtils.toBean(updateReqVO, AiSampleTagDO.class);
        aiSampleTagMapper.updateById(tag);
    }

    @Override
    public void deleteAiSampleTag(Long id) {
        AiSampleTagDO tag = aiSampleTagMapper.selectById(id);
        if (isEnumType(tag.getTagType())) {
            throw new IllegalArgumentException("Enum tag cannot be deleted");
        }
        aiSampleTagMapper.deleteById(id);
    }

    @Override
    public AiSampleTagDO getAiSampleTag(Long id) {
        return aiSampleTagMapper.selectById(id);
    }

    @Override
    public PageResult<AiSampleTagDO> getAiSampleTagPage(AiSampleTagPageReqVO pageReqVO) {
        IPage<AiSampleTagDO> page = aiSampleTagMapper.getAiSampleTagPage(MyBatisUtils.buildPage(pageReqVO), pageReqVO);
        return new PageResult<>(page.getRecords(), page.getTotal());
    }

    @Override
    public List<AiSampleTagDO> getAiSampleTagList() {
        return aiSampleTagMapper.selectList(new LambdaQueryWrapper<AiSampleTagDO>().orderByDesc(AiSampleTagDO::getId));
    }

    @Override
    public List<AiSampleTagGroupDO> getGroupListByTagId(Long tagId) {
        AiSampleTagDO tag = aiSampleTagMapper.selectById(tagId);
        return aiSampleTagGroupMapper.selectBatchIds(parseGroupIds(tag.getGroupId()));
    }

    private void validateEnumTagGroup(String groupIdStr) {
        Long groupId = getFirstGroupId(groupIdStr);
        AiSampleTagGroupDO group = aiSampleTagGroupMapper.selectById(groupId);
        if (group == null || !isEnumType(group.getGroupType())) {
            throw new IllegalArgumentException("Enum tag can only bind enum group");
        }
    }

    private boolean isEnumType(Integer type) {
        return ENUM_TYPE.equals(type);
    }

    private Long getFirstGroupId(String groupIds) {
        return parseGroupIds(groupIds).get(0);
    }

    private List<Long> parseGroupIds(String groupIds) {
        return Arrays.stream(groupIds.split(StrUtil.COMMA))
                .map(String::trim)
                .map(Long::parseLong)
                .toList();
    }
}
