package com.ai.da.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.enums.CollectionLevel1TypeEnum;
import com.ai.da.common.enums.DesignTypeEnum;
import com.ai.da.common.utils.CopyUtil;
import com.ai.da.common.utils.DateUtil;
import com.ai.da.common.utils.MinioUtil;
import com.ai.da.common.utils.RedisUtil;
import com.ai.da.mapper.primary.CollectionMapper;
import com.ai.da.mapper.primary.MoodboardPositionMapper;
import com.ai.da.mapper.primary.entity.Collection;
import com.ai.da.mapper.primary.entity.CollectionElement;
import com.ai.da.mapper.primary.entity.Gradient;
import com.ai.da.mapper.primary.entity.MoodboardPosition;
import com.ai.da.model.vo.CollectionColorVO;
import com.ai.da.model.vo.CollectionElementVO;
import com.ai.da.model.vo.UserLikeCollectionVO;
import com.ai.da.service.CollectionElementService;
import com.ai.da.service.CollectionService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author yanglei
 * @since 2022-09-30
 */
@Slf4j
@Service
public class CollectionServiceImpl extends ServiceImpl<CollectionMapper, Collection> implements CollectionService {
    @Resource
    private CollectionMapper collectionMapper;
    @Resource
    private CollectionElementService collectionElementService;
    @Resource
    private MinioUtil minioUtil;
    @Resource
    private MoodboardPositionMapper moodboardPositionMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long saveCollection(Long accountId, String timeZone, String moodTemplateId, String moodboardPosition) {
        Collection collection = new Collection();
        collection.setAccountId(accountId);
        collection.setCreateDate(DateUtil.getByTimeZone(timeZone));
        collection.setMoodTemplateId(moodTemplateId);
        collection.setMoodboardPosition(moodboardPosition);
        if (collectionMapper.insert(collection) <= 0) {
            throw new BusinessException("save.collection.failed");
        }
        return collection.getId();
    }

    @Override
    public Collection findById(Long id) {
        return collectionMapper.selectById(id);
    }

    @Resource
    private RedisUtil redisUtil;

    @Override
    public UserLikeCollectionVO chooseCollection(Long id) {
        UserLikeCollectionVO response = new UserLikeCollectionVO();
        Collection collection = getById(id);
        if (Objects.isNull(collection)) {
            throw new BusinessException("collection.not.found");
        }
        List<CollectionElement> collectionElements = collectionElementService.getByCollectionId(id);
        if (CollectionUtils.isEmpty(collectionElements)) {
            throw new BusinessException("collectionElements.not.found");
        }
        response.setCollectionId(id);
        response.setMoodTemplateId(collection.getMoodTemplateId());
        if (collection.getMoodTemplateId() != null) {
            CollectionElement byId = collectionElementService.getById(response.getMoodTemplateId());
            if (null != collection.getMoodboardPosition()) {
                String moodboardPositionString = getMoodboardPositionString(collection.getId());
                if (StringUtils.isBlank(moodboardPositionString)) {
                    response.setMoodboardPosition(collection.getMoodboardPosition());
                }else {
                    response.setMoodboardPosition(moodboardPositionString);
                }
            }
            if (Objects.nonNull(byId)) {
                if (minioUtil.doesObjectExist(byId.getUrl())) {
                    response.setMoodTemplateName(byId.getName());
                    response.setMoodTemplateUrl(minioUtil.getPreSignedUrl(byId.getUrl(), 24 * 60));
                }else {
                    response.setMoodTemplateId(null);
                    if (!StringUtils.isBlank(response.getMoodboardPosition())) {
                        response.setMoodboardPosition(null);
                    }
                }
            }
        }
        Map<String, List<CollectionElement>> maps = collectionElements
                .stream()
                .collect(Collectors.groupingBy(CollectionElement::getLevel1Type));

        maps.forEach((k, v) -> {
            CollectionLevel1TypeEnum level1TypeEnum = CollectionLevel1TypeEnum.uploadOf(k);
            if (Objects.isNull(level1TypeEnum)) {
                throw new BusinessException("unknown.level1TypeEnum");
            }
            switch (level1TypeEnum) {
                case MOOD_BOARD:
                    List<CollectionElementVO> moodBoards = CopyUtil.copyList(v, CollectionElementVO.class, (o, d) -> {
                        d.setDesignType(DesignTypeEnum.COLLECTION.getRealName());
                        String url = o.getUrl();
                        d.setOriginalUrl(url);
                        if (minioUtil.doesObjectExist(url)) {
                            d.setUrl(minioUtil.getPreSignedUrl(url, 24 * 60));
                        }
                    });
                    response.setMoodBoards(moodBoards.stream()
                            .filter(d -> minioUtil.doesObjectExist(d.getOriginalUrl()))
                            .collect(Collectors.toList()));
                    break;

                case PRINT_BOARD:
                    List<CollectionElementVO> printBoards = CopyUtil.copyList(v, CollectionElementVO.class, (o, d) -> {
                        d.setIsPin(o.getHasPin());
                        d.setDesignType(DesignTypeEnum.COLLECTION.getRealName());
                        String url = o.getUrl();
                        d.setOriginalUrl(url);
                        if (minioUtil.doesObjectExist(url)) {
                            d.setUrl(minioUtil.getPreSignedUrl(url, 24 * 60));
                        }
                    });
                    response.setPrintBoards(printBoards.stream()
                            .filter(d -> minioUtil.doesObjectExist(d.getOriginalUrl()))
                            .collect(Collectors.toList()));
                    break;

                case SKETCH_BOARD:
                    List<CollectionElementVO> sketchBoards = CopyUtil.copyList(v, CollectionElementVO.class, (o, d) -> {
                        d.setIsPin(o.getHasPin());
                        d.setDesignType(DesignTypeEnum.COLLECTION.getRealName());
                        String url = o.getUrl();
                        d.setOriginalUrl(url);
                        if (minioUtil.doesObjectExist(url)) {
                            d.setUrl(minioUtil.getPreSignedUrl(url, 24 * 60));
                            if (url.contains(".")) {
                                String[] split = url.split("\\.");
                                d.setUrlWithWhiteSide(minioUtil.getPreSignedUrl(split[0] + "-show." + split[1], 24 * 60));
                            } else {
                                d.setUrlWithWhiteSide(minioUtil.getPreSignedUrl(url + "-show", 24 * 60));
                            }
                        }
                    });
                    response.setSketchBoards(sketchBoards.stream()
                            .filter(d -> minioUtil.doesObjectExist(d.getOriginalUrl()))
                            .collect(Collectors.toList()));
                    break;

                case COLOR_BOARD:
                    response.setColorBoards(resolveColorBoard(v));
                    break;

                case MARKETING_SKETCH:
                    response.setMarketingSketchs(CopyUtil.copyList(v, CollectionElementVO.class, (o, d) -> {
                        d.setDesignType(DesignTypeEnum.COLLECTION.getRealName());
                    }));
                    break;

                default:
                    break;
            }
        });

        if (CollectionUtil.isNotEmpty(response.getColorBoards())) {
            List<CollectionColorVO> collect = response.getColorBoards().stream()
                    .distinct()
                    .collect(Collectors.toList());
            response.setColorBoards(collect);
        }
        return response;
    }

    @Override
    public String getMoodboardPositionString(Long id) {
        QueryWrapper<MoodboardPosition> qw = new QueryWrapper<>();
        qw.lambda().eq(MoodboardPosition::getCollectionId, id);
        List<MoodboardPosition> moodboardPositions = moodboardPositionMapper.selectList(qw);
        if (moodboardPositions != null && !moodboardPositions.isEmpty()) {
            // 将查询结果转换为 JSON 字符串
            JSONObject resultJson = new JSONObject();

            // 遍历 MoodboardPosition 列表，根据实际情况填充到 resultJson 中
            for (MoodboardPosition position : moodboardPositions) {
                String type = position.getType();
                String styleData = position.getStyleData();
                int sequence = position.getSequence(); // 获取 sequence 值

                // 如果 type 字段为 "class"，直接将其作为字符串处理
                if ("class".equals(type)) {
                    // 如果 type 字段还没有对应的 JSONArray，则初始化它
                    if (!resultJson.containsKey(type)) {
                        resultJson.put(type, new ArrayList<>());
                    }

                    // 获取对应类型的列表
                    List<String> classList = (List<String>) resultJson.get(type);

                    // 确保列表长度足够，可以容纳 `sequence` 索引
                    while (classList.size() <= sequence) {
                        classList.add(""); // 添加空字符串，直到长度大于 `sequence`
                    }

                    // 将 class 字段直接存入列表
                    classList.set(sequence, styleData); // 根据 sequence 设置数据

                    resultJson.put(type, classList);
                } else {
                    // 如果 type 字段为其他类型，按照正常方式处理
                    if (!resultJson.containsKey(type)) {
                        resultJson.put(type, new ArrayList<>());
                    }

                    // 获取对应类型的列表
                    List<JSONObject> styleList = (List<JSONObject>) resultJson.get(type);

                    // 确保列表长度足够，可以容纳 `sequence` 索引
                    while (styleList.size() <= sequence) {
                        styleList.add(new JSONObject()); // 添加空的 JSONObject，直到长度大于 `sequence`
                    }

                    // 将解析的样式数据存入正确的索引位置
                    JSONObject styleObject = JSON.parseObject(styleData);
                    styleList.set(sequence, styleObject); // 根据 sequence 设置数据

                    resultJson.put(type, styleList);
                }
            }

            // 将最终结果转换为字符串
            return resultJson.toJSONString();
        } else {
            return null; // 返回空的 JSON 对象
        }
    }

    @Override
    public List<CollectionColorVO> resolveColorBoard(List<CollectionElement> collectionElements) {
        return CopyUtil.copyList(collectionElements, CollectionColorVO.class, (o, d) -> {
            String name = o.getName();
            if (StringUtils.isBlank(name)) {
                d.setId(null);
                d.setName(null);
            } else {
                String[] idName = name.split("_");
                if (idName.length > 1) {
                    if (idName[0].equals("null")) {
                        d.setId(null);
                    }else {
                        d.setId(StringUtil.isNullOrEmpty(idName[0]) ? null : Integer.valueOf(idName[0]));
                    }
                    d.setName(idName[1]);
                    d.setTcx(idName[2]);
                }
            }
            d.setRgbValue(o.getColorRgb());
            // 渐变色
            d.setGradient(JSONObject.parseObject(o.getGradientString(), Gradient.class));
        });
    }
}
