package com.liquidnet.service.kylin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.liquidnet.service.kylin.constant.KylinPerformanceStatusEnum;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dao.KylinArtistPerformanceDao;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.kylin.dto.vo.returns.KylinArtistDetailFrontVo;
import com.liquidnet.service.kylin.dto.vo.returns.KylinArtistPerformanceFrontVo;
import com.liquidnet.service.kylin.dto.vo.returns.KylinArtistProductFrontVo;
import com.liquidnet.service.kylin.entity.KylinArtist;
import com.liquidnet.service.kylin.entity.KylinArtistAlbum;
import com.liquidnet.service.kylin.entity.KylinArtistProduct;
import com.liquidnet.service.kylin.mapper.KylinArtistAlbumMapper;
import com.liquidnet.service.kylin.mapper.KylinArtistMapper;
import com.liquidnet.service.kylin.mapper.KylinArtistPerformanceMapper;
import com.liquidnet.service.kylin.mapper.KylinArtistProductMapper;
import com.liquidnet.service.kylin.service.IKylinArtistFrontService;
import com.liquidnet.service.kylin.utils.DataUtils;
import com.liquidnet.service.kylin.utils.GoblinRedisUtils;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsInfoVo;
import com.liquidnet.service.goblin.dto.vo.GoblinGoodsSkuInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.math.BigDecimal;
import java.util.stream.Collectors;

@Slf4j
@Service
public class KylinArtistFrontServiceImpl implements IKylinArtistFrontService {

    @Autowired
    private KylinArtistMapper kylinArtistMapper;
    @Autowired
    private KylinArtistAlbumMapper kylinArtistAlbumMapper;
    @Autowired
    private KylinArtistPerformanceMapper kylinArtistPerformanceMapper;
    @Autowired
    private KylinArtistProductMapper kylinArtistProductMapper;
    @Autowired
    private DataUtils dataUtils;
    @Autowired
    private GoblinRedisUtils goblinRedisUtils;
    @Autowired
    private KylinPerformancesServiceImpl kylinPerformancesService;

    @Override
    public KylinArtistDetailFrontVo getArtistDetail(String artistId) {
        String cacheKey = KylinRedisConst.ARTIST_DETAIL + artistId;
        KylinArtistDetailFrontVo cached = dataUtils.getArtistFrontCache(cacheKey);
        if (cached != null) {
            return cached;
        }
        KylinArtist artist = loadArtistForFront(artistId);
        if (artist == null) {
            return null;
        }
        KylinArtistDetailFrontVo vo = new KylinArtistDetailFrontVo();
        vo.setArtistId(artist.getArtistId());
        vo.setArtistName(artist.getArtistName());
        vo.setArtistType(artist.getArtistType());
        vo.setArtistTypeName(resolveArtistTypeName(artist.getArtistType()));
        vo.setAvatarUrl(artist.getAvatarUrl());
        vo.setIntroduction(artist.getIntroduction());
        dataUtils.setArtistFrontCache(cacheKey, vo);
        return vo;
    }

    @Override
    public List<String> getArtistAlbum(String artistId) {
        String cacheKey = KylinRedisConst.ARTIST_ALBUM + artistId;
        List<String> cached = dataUtils.getArtistFrontCache(cacheKey);
        if (cached != null) {
            return cached;
        }
        List<KylinArtistAlbum> albumList = kylinArtistAlbumMapper.selectByArtistId(artistId);
        List<String> imageUrls = new ArrayList<>();
        if (!CollectionUtils.isEmpty(albumList)) {
            imageUrls = albumList.stream().map(KylinArtistAlbum::getImageUrl).collect(Collectors.toList());
        }
        dataUtils.setArtistFrontCache(cacheKey, imageUrls);
        return imageUrls;
    }

    @Override
    public List<KylinArtistPerformanceFrontVo> getArtistPerformances(String artistId) {
        String cacheKey = KylinRedisConst.ARTIST_PERFORMANCES + artistId;
        List<KylinArtistPerformanceDao> baseList = dataUtils.getArtistFrontCache(cacheKey);
        if (baseList == null) {
            baseList = loadPerformanceBaseList(artistId);
            dataUtils.setArtistFrontCache(cacheKey, baseList);
        }
        return buildPerformanceFrontList(baseList);
    }

    @Override
    public List<KylinArtistProductFrontVo> getArtistProducts(String artistId) {
        String cacheKey = KylinRedisConst.ARTIST_PRODUCTS + artistId;
        List<KylinArtistProduct> baseList = dataUtils.getArtistFrontCache(cacheKey);
        if (baseList == null) {
            baseList = loadProductRelationBaseList(artistId);
            dataUtils.setArtistFrontCache(cacheKey, baseList);
        }
        return buildProductFrontList(baseList);
    }

    private List<KylinArtistProduct> loadProductRelationBaseList(String artistId) {
        List<KylinArtistProduct> relations = kylinArtistProductMapper.selectByArtistId(artistId);
        if (CollectionUtils.isEmpty(relations)) {
            return new ArrayList<>();
        }
        return relations;
    }

    private List<KylinArtistPerformanceDao> loadPerformanceBaseList(String artistId) {
        List<KylinArtistPerformanceDao> performanceList = kylinArtistPerformanceMapper.selectPerformanceDaoByArtistId(artistId);
        if (CollectionUtils.isEmpty(performanceList)) {
            return new ArrayList<>();
        }
        Map<String, KylinArtistPerformanceDao> dedup = new LinkedHashMap<>();
        for (KylinArtistPerformanceDao item : performanceList) {
            dedup.putIfAbsent(item.getPerformanceId(), item);
        }
        return new ArrayList<>(dedup.values());
    }

    private List<KylinArtistPerformanceFrontVo> buildPerformanceFrontList(List<KylinArtistPerformanceDao> baseList) {
        List<KylinArtistPerformanceFrontVo> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(baseList)) {
            return result;
        }
        for (KylinArtistPerformanceDao item : baseList) {
            KylinPerformanceVo performanceVo = dataUtils.getPerformanceVo(item.getPerformanceId());
            if (performanceVo == null) {
                continue;
            }
            performanceVo = kylinPerformancesService.checkAppStatusInfo(performanceVo);
            Integer appStatus = performanceVo.getAppStatus();
            if (appStatus == null || appStatus == 10 || appStatus == 7 || appStatus == 3 || appStatus == 11) {
                continue;
            }
            if (appStatus != 6 && appStatus != 9 && appStatus != 8) {
                continue;
            }
            KylinArtistPerformanceFrontVo vo = new KylinArtistPerformanceFrontVo();
            vo.setPerformanceId(item.getPerformanceId());
            vo.setTitle(item.getTitle());
            vo.setCoverPic(performanceVo.getImgPoster());
            vo.setTimeStart(item.getTimeStart());
            vo.setFieldName(performanceVo.getFieldName());
            vo.setPrice(performanceVo.getPrice());
            vo.setAppStatus(appStatus);
            vo.setStatusName(KylinPerformanceStatusEnum.getName(appStatus));
            result.add(vo);
        }
        return result;
    }

    private List<KylinArtistProductFrontVo> buildProductFrontList(List<KylinArtistProduct> relations) {
        List<KylinArtistProductFrontVo> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(relations)) {
            return result;
        }
        for (KylinArtistProduct relation : relations) {
            GoblinGoodsInfoVo goods = goblinRedisUtils.getGoodsInfoVo(relation.getSpuId());
            if (goods == null || !"0".equals(goods.getDelFlg()) || !"3".equals(goods.getShelvesStatus())) {
                continue;
            }
            KylinArtistProductFrontVo vo = new KylinArtistProductFrontVo();
            vo.setSpuId(goods.getSpuId());
            vo.setSpuType(goods.getSpuType());
            vo.setName(goods.getName());
            vo.setCoverPic(goods.getCoverPic());
            vo.setSellPrice(resolveGoodsSellPrice(goods));
            vo.setSort(relation.getSort());
            result.add(vo);
        }
        return result;
    }

    /**
     * SPU sellPrice 常为空，与 goblin 前台一致：SKU 最低价 → priceGe → priceLe
     */
    private BigDecimal resolveGoodsSellPrice(GoblinGoodsInfoVo goodsInfoVo) {
        if (goodsInfoVo == null) {
            return null;
        }
        if (goodsInfoVo.getSellPrice() != null) {
            return goodsInfoVo.getSellPrice();
        }
        BigDecimal minSkuPrice = null;
        if (!CollectionUtils.isEmpty(goodsInfoVo.getSkuIdList())) {
            for (String skuId : goodsInfoVo.getSkuIdList()) {
                GoblinGoodsSkuInfoVo skuInfoVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
                if (skuInfoVo == null) {
                    continue;
                }
                BigDecimal skuShowPrice = skuInfoVo.getSellPrice() != null
                        ? skuInfoVo.getSellPrice() : skuInfoVo.getPrice();
                if (skuShowPrice == null) {
                    continue;
                }
                if (minSkuPrice == null || skuShowPrice.compareTo(minSkuPrice) < 0) {
                    minSkuPrice = skuShowPrice;
                }
            }
        }
        if (minSkuPrice != null) {
            return minSkuPrice;
        }
        if (goodsInfoVo.getPriceGe() != null) {
            return goodsInfoVo.getPriceGe();
        }
        return goodsInfoVo.getPriceLe();
    }

    /**
     * 简介详情用：按 artist_id 查 kylin_artist（不按 status 过滤）
     */
    private KylinArtist loadArtistForFront(String artistId) {
        if (artistId == null || artistId.isEmpty()) {
            return null;
        }
        return kylinArtistMapper.selectOne(
                Wrappers.lambdaQuery(KylinArtist.class).eq(KylinArtist::getArtistId, artistId)
        );
    }

    private String resolveArtistTypeName(Integer artistType) {
        if (artistType == null) {
            return "未知";
        }
        switch (artistType) {
            case 1:
                return "音乐人";
            case 2:
                return "艺术家";
            case 3:
                return "厂牌";
            case 4:
                return "品牌方";
            default:
                return "未知";
        }
    }
}
