package com.liquidnet.client.admin.zhengzai.goblin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.liquidnet.client.admin.zhengzai.goblin.dto.SqbPerfGoodsBindItemParam;
import com.liquidnet.client.admin.zhengzai.goblin.service.ISqbPerformanceGoodsService;
import com.liquidnet.client.admin.zhengzai.goblin.utils.GoblinRedisUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.dto.vo.GoblinAdminSqbGoodsVo;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbPerfLinkedGoodsVo;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbPerfListRespVo;
import com.liquidnet.service.goblin.entity.GoblinGoods;
import com.liquidnet.service.goblin.entity.GoblinGoodsSku;
import com.liquidnet.service.goblin.entity.GoblinSqbPerformanceConfig;
import com.liquidnet.service.goblin.entity.GoblinSqbPerformanceGoods;
import com.liquidnet.service.goblin.mapper.GoblinGoodsMapper;
import com.liquidnet.service.goblin.mapper.GoblinGoodsSkuMapper;
import com.liquidnet.service.goblin.mapper.GoblinSqbPerformanceConfigMapper;
import com.liquidnet.service.goblin.mapper.GoblinSqbPerformanceGoodsMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 演出-收钱吧商品关联 服务实现
 * 直连 MySQL，写入/删除时同步删除 Redis 缓存
 */
@Slf4j
@Service
public class SqbPerformanceGoodsServiceImpl implements ISqbPerformanceGoodsService {

    /** skuType=33 代表收钱吧商品 */
    private static final int SQB_SKU_TYPE = 33;

    /** 与前台 Goblin 一致：单品上架状态 3=上架 */
    private static final String SHELVES_ON = "3";

    private static boolean isSqbSkuAndSpuOnShelf(GoblinGoodsSku sku, GoblinGoods spu) {
        if (sku == null || spu == null) {
            return false;
        }
        if (!"0".equals(sku.getDelFlg()) || !"0".equals(spu.getDelFlg())) {
            return false;
        }
        return SHELVES_ON.equals(sku.getShelvesStatus()) && SHELVES_ON.equals(spu.getShelvesStatus());
    }

    private static String shelfStatusLabel(boolean onShelf) {
        return onShelf ? "上架" : "已下架";
    }

    private static String sqbSpuSkuDisplay(String spuTitle, String skuTitle) {
        String s = spuTitle != null ? spuTitle.trim() : "";
        String k = skuTitle != null ? skuTitle.trim() : "";
        if (!s.isEmpty() && !k.isEmpty()) {
            return s + "-" + k;
        }
        if (!s.isEmpty()) {
            return s;
        }
        return k;
    }

    /** 头图：SKU 无图时回落到 SPU 封面（收钱吧 SKU 常未维护 sku_pic） */
    private static String pickSkuOrSpuCover(String skuPic, String spuCoverPic) {
        if (StringUtils.hasText(skuPic)) {
            return skuPic;
        }
        return StringUtils.hasText(spuCoverPic) ? spuCoverPic : "";
    }

    @Autowired
    private GoblinSqbPerformanceGoodsMapper performanceGoodsMapper;

    @Autowired
    private GoblinSqbPerformanceConfigMapper performanceConfigMapper;

    @Autowired
    private GoblinGoodsMapper goblinGoodsMapper;

    @Autowired
    private GoblinGoodsSkuMapper goblinGoodsSkuMapper;

    @Autowired
    private GoblinRedisUtils goblinRedisUtils;

    @Override
    public ResponseDto<Boolean> bind(String performancesId, List<SqbPerfGoodsBindItemParam> items, Integer autoOffline) {
        if (!StringUtils.hasText(performancesId)) {
            return ResponseDto.failure("演出ID不能为空");
        }
        if (items == null || items.isEmpty()) {
            return ResponseDto.failure("商品列表不能为空");
        }

        LocalDateTime nowTime = LocalDateTime.now();
        String nowStr = nowTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        try {
            // 1. 保存全局配置
            GoblinSqbPerformanceConfig config = performanceConfigMapper.selectById(performancesId);
            if (config == null) {
                config = new GoblinSqbPerformanceConfig();
                config.setPerformancesId(performancesId);
                config.setAutoOffline(autoOffline != null ? autoOffline : 0);
                config.setCreatedAt(nowStr);
                config.setUpdatedAt(nowStr);
                performanceConfigMapper.insert(config);
            } else {
                config.setAutoOffline(autoOffline != null ? autoOffline : 0);
                config.setUpdatedAt(nowStr);
                performanceConfigMapper.updateById(config);
            }

            // 2. 批量处理商品绑定
            for (SqbPerfGoodsBindItemParam item : items) {
                String skuId = item.getSkuId();
                if (!StringUtils.hasText(skuId)) {
                    continue;
                }

                LambdaQueryWrapper<GoblinGoodsSku> skuQuery = new LambdaQueryWrapper<>();
                skuQuery.eq(GoblinGoodsSku::getSkuId, skuId).last("LIMIT 1");
                GoblinGoodsSku sku = goblinGoodsSkuMapper.selectOne(skuQuery);
                if (sku == null) {
                    log.warn("[演出商品关联] SKU不存在，skuId={}", skuId);
                    return ResponseDto.failure("SKU不存在：" + skuId);
                }

                LambdaQueryWrapper<GoblinSqbPerformanceGoods> existQuery = new LambdaQueryWrapper<>();
                existQuery.eq(GoblinSqbPerformanceGoods::getPerformancesId, performancesId)
                        .eq(GoblinSqbPerformanceGoods::getSkuId, skuId)
                        .last("LIMIT 1");
                GoblinSqbPerformanceGoods existing = performanceGoodsMapper.selectOne(existQuery);

                if (sku.getSkuType() == null || sku.getSkuType() != SQB_SKU_TYPE) {
                    return ResponseDto.failure("仅可关联收钱吧商品（skuType=33），skuId=" + skuId);
                }
                if (existing == null) {
                    GoblinGoods spu = goblinGoodsMapper.selectOne(new LambdaQueryWrapper<GoblinGoods>()
                            .eq(GoblinGoods::getSpuId, sku.getSpuId()).last("LIMIT 1"));
                    if (!isSqbSkuAndSpuOnShelf(sku, spu)) {
                        return ResponseDto.failure("商品未上架或已下架，不可关联。请先让商户上架后再操作。skuId=" + skuId);
                    }
                }

                int sortVal = item.getSort() != null ? item.getSort() : 0;

                if (existing != null) {
                    LambdaUpdateWrapper<GoblinSqbPerformanceGoods> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(GoblinSqbPerformanceGoods::getPerformancesId, performancesId)
                            .eq(GoblinSqbPerformanceGoods::getSkuId, skuId)
                            .set(GoblinSqbPerformanceGoods::getSort, sortVal)
                            .set(GoblinSqbPerformanceGoods::getStatus, 1)
                            .set(GoblinSqbPerformanceGoods::getSettlementPrice, item.getSettlementPrice())
                            .set(GoblinSqbPerformanceGoods::getUpdatedAt, nowStr);
                    performanceGoodsMapper.update(null, updateWrapper);
                } else {
                    GoblinSqbPerformanceGoods entity = new GoblinSqbPerformanceGoods();
                    entity.setPerformancesId(performancesId);
                    entity.setSpuId(sku.getSpuId());
                    entity.setSkuId(skuId);
                    entity.setSort(sortVal);
                    entity.setStatus(1);
                    entity.setSettlementPrice(item.getSettlementPrice());
                    entity.setCreatedAt(nowStr);
                    entity.setUpdatedAt(nowStr);
                    performanceGoodsMapper.insert(entity);
                }
            }

            goblinRedisUtils.delPerformanceGoodsCache(performancesId);
            return ResponseDto.success(Boolean.TRUE);
        } catch (Exception e) {
            log.error("[演出商品关联] bind 异常，performancesId={}", performancesId, e);
            return ResponseDto.failure("关联操作失败：" + e.getMessage());
        }
    }

    @Override
    public ResponseDto<Boolean> unbind(String performancesId, String skuId) {
        if (!StringUtils.hasText(performancesId)) {
            return ResponseDto.failure("演出ID不能为空");
        }
        if (!StringUtils.hasText(skuId)) {
            return ResponseDto.failure("SKU ID不能为空");
        }

        try {
            LambdaUpdateWrapper<GoblinSqbPerformanceGoods> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(GoblinSqbPerformanceGoods::getPerformancesId, performancesId)
                    .eq(GoblinSqbPerformanceGoods::getSkuId, skuId)
                    .set(GoblinSqbPerformanceGoods::getStatus, 0)
                    .set(GoblinSqbPerformanceGoods::getUpdatedAt,
                            LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            int rows = performanceGoodsMapper.update(null, updateWrapper);

            if (rows == 0) {
                return ResponseDto.failure("关联记录不存在");
            }

            goblinRedisUtils.delPerformanceGoodsCache(performancesId);
            return ResponseDto.success(Boolean.TRUE);
        } catch (Exception e) {
            log.error("[演出商品关联] unbind 异常，performancesId={}, skuId={}", performancesId, skuId, e);
            return ResponseDto.failure("解除关联失败：" + e.getMessage());
        }
    }

    @Override
    public ResponseDto<GoblinSqbPerfListRespVo> list(String performancesId) {
        if (!StringUtils.hasText(performancesId)) {
            return ResponseDto.failure("演出ID不能为空");
        }

        try {
            GoblinSqbPerfListRespVo resp = new GoblinSqbPerfListRespVo();
            
            // 1. 查询全局配置
            GoblinSqbPerformanceConfig config = performanceConfigMapper.selectById(performancesId);
            resp.setAutoOffline(config != null ? config.getAutoOffline() : 0);

            // 2. 查询关联商品
            LambdaQueryWrapper<GoblinSqbPerformanceGoods> query = new LambdaQueryWrapper<>();
            query.eq(GoblinSqbPerformanceGoods::getPerformancesId, performancesId)
                    .eq(GoblinSqbPerformanceGoods::getStatus, 1)
                    .orderByAsc(GoblinSqbPerformanceGoods::getSort);
            List<GoblinSqbPerformanceGoods> relations = performanceGoodsMapper.selectList(query);

            if (relations == null || relations.isEmpty()) {
                resp.setGoodsList(new ArrayList<>());
                return ResponseDto.success(resp);
            }

            List<String> skuIds = relations.stream()
                    .map(GoblinSqbPerformanceGoods::getSkuId).collect(Collectors.toList());

            LambdaQueryWrapper<GoblinGoodsSku> skuQuery = new LambdaQueryWrapper<>();
            skuQuery.in(GoblinGoodsSku::getSkuId, skuIds);
            Map<String, GoblinGoodsSku> skuMap = goblinGoodsSkuMapper.selectList(skuQuery)
                    .stream().collect(Collectors.toMap(GoblinGoodsSku::getSkuId, Function.identity(), (a, b) -> a));

            List<String> spuIdList = relations.stream()
                    .map(GoblinSqbPerformanceGoods::getSpuId)
                    .filter(StringUtils::hasText)
                    .distinct()
                    .collect(Collectors.toList());
            Map<String, String> spuNameById = new HashMap<>();
            Map<String, String> spuCoverById = new HashMap<>();
            Map<String, GoblinGoods> spuById = new HashMap<>();
            if (!spuIdList.isEmpty()) {
                LambdaQueryWrapper<GoblinGoods> goodsQuery = new LambdaQueryWrapper<>();
                goodsQuery.in(GoblinGoods::getSpuId, spuIdList)
                        .select(GoblinGoods::getSpuId, GoblinGoods::getName, GoblinGoods::getCoverPic,
                                GoblinGoods::getShelvesStatus, GoblinGoods::getDelFlg);
                for (GoblinGoods g : goblinGoodsMapper.selectList(goodsQuery)) {
                    if (g.getSpuId() != null) {
                        spuNameById.put(g.getSpuId(), g.getName());
                        spuCoverById.put(g.getSpuId(), g.getCoverPic());
                        spuById.put(g.getSpuId(), g);
                    }
                }
            }

            List<GoblinSqbPerfLinkedGoodsVo> goodsList = new ArrayList<>();
            for (GoblinSqbPerformanceGoods rel : relations) {
                GoblinSqbPerfLinkedGoodsVo vo = new GoblinSqbPerfLinkedGoodsVo();
                vo.setSkuId(rel.getSkuId());
                vo.setSpuId(rel.getSpuId());
                vo.setSort(rel.getSort());
                vo.setSettlementPrice(rel.getSettlementPrice());
                vo.setStatus(rel.getStatus());

                GoblinGoodsSku sku = skuMap.get(rel.getSkuId());
                if (sku != null) {
                    vo.setSkuName(sku.getName());
                    vo.setSpuName(spuNameById.getOrDefault(rel.getSpuId(), ""));
                    vo.setCoverPic(pickSkuOrSpuCover(sku.getSkuPic(), spuCoverById.get(rel.getSpuId())));
                    vo.setPrice(sku.getPrice());
                    vo.setStock(sku.getSkuStock());
                    GoblinGoods spu = spuById.get(rel.getSpuId());
                    boolean onShelf = isSqbSkuAndSpuOnShelf(sku, spu);
                    vo.setLinkable(onShelf);
                    vo.setShelfStatusLabel(shelfStatusLabel(onShelf));
                } else {
                    vo.setLinkable(false);
                    vo.setShelfStatusLabel("已下架");
                }
                goodsList.add(vo);
            }
            resp.setGoodsList(goodsList);

            return ResponseDto.success(resp);
        } catch (Exception e) {
            log.error("[演出商品关联] list 异常，performancesId={}", performancesId, e);
            return ResponseDto.failure("查询失败：" + e.getMessage());
        }
    }

    @Override
    public ResponseDto<List<GoblinAdminSqbGoodsVo>> searchGoods(String keyword) {
        try {
            LambdaQueryWrapper<GoblinGoodsSku> skuQuery = new LambdaQueryWrapper<>();
            skuQuery.eq(GoblinGoodsSku::getSkuType, SQB_SKU_TYPE).ne(GoblinGoodsSku::getDelFlg, "1");
            if (StringUtils.hasText(keyword)) {
                LambdaQueryWrapper<GoblinGoods> goodsQuery = new LambdaQueryWrapper<>();
                goodsQuery.select(GoblinGoods::getSpuId)
                        .ne(GoblinGoods::getDelFlg, "1")
                        .like(GoblinGoods::getName, keyword)
                        .last("LIMIT 300");
                List<String> spuIds = goblinGoodsMapper.selectList(goodsQuery).stream()
                        .map(GoblinGoods::getSpuId)
                        .filter(StringUtils::hasText)
                        .distinct()
                        .collect(Collectors.toList());
                if (spuIds.isEmpty()) {
                    return ResponseDto.success(new ArrayList<>());
                }
                skuQuery.in(GoblinGoodsSku::getSpuId, spuIds);
            }
            skuQuery.last("LIMIT 50");
            List<GoblinGoodsSku> skuList = goblinGoodsSkuMapper.selectList(skuQuery);

            if (skuList.isEmpty()) {
                return ResponseDto.success(new ArrayList<>());
            }

            List<String> spuIdForTitle = skuList.stream()
                    .map(GoblinGoodsSku::getSpuId)
                    .filter(StringUtils::hasText)
                    .distinct()
                    .collect(Collectors.toList());
            Map<String, String> spuTitleById = new HashMap<>();
            Map<String, String> spuCoverById = new HashMap<>();
            Map<String, GoblinGoods> spuRowById = new HashMap<>();
            if (!spuIdForTitle.isEmpty()) {
                LambdaQueryWrapper<GoblinGoods> gq = new LambdaQueryWrapper<>();
                gq.in(GoblinGoods::getSpuId, spuIdForTitle)
                        .select(GoblinGoods::getSpuId, GoblinGoods::getName, GoblinGoods::getCoverPic,
                                GoblinGoods::getShelvesStatus, GoblinGoods::getDelFlg);
                for (GoblinGoods g : goblinGoodsMapper.selectList(gq)) {
                    if (g.getSpuId() != null) {
                        spuTitleById.put(g.getSpuId(), g.getName());
                        spuCoverById.put(g.getSpuId(), g.getCoverPic());
                        spuRowById.put(g.getSpuId(), g);
                    }
                }
            }

            List<GoblinAdminSqbGoodsVo> result = new ArrayList<>();
            for (GoblinGoodsSku sku : skuList) {
                GoblinAdminSqbGoodsVo vo = new GoblinAdminSqbGoodsVo();
                vo.setSpuId(sku.getSpuId());
                vo.setSkuId(sku.getSkuId());
                String spuTitle = spuTitleById.getOrDefault(sku.getSpuId(), "");
                String skuTitle = sku.getName() != null ? sku.getName() : "";
                vo.setSpuTitle(spuTitle);
                vo.setSkuTitle(skuTitle);
                GoblinGoods spu = spuRowById.get(sku.getSpuId());
                boolean onShelf = isSqbSkuAndSpuOnShelf(sku, spu);
                vo.setLinkable(onShelf);
                vo.setShelfStatusLabel(shelfStatusLabel(onShelf));
                vo.setTitle(sqbSpuSkuDisplay(spuTitle, skuTitle) + (onShelf ? "" : "（已下架）"));
                vo.setSkuPic(pickSkuOrSpuCover(sku.getSkuPic(), spuCoverById.get(sku.getSpuId())));
                vo.setPrice(sku.getPrice());
                vo.setSkuStock(sku.getSkuStock());
                result.add(vo);
            }
            return ResponseDto.success(result);
        } catch (Exception e) {
            log.error("[演出商品关联] searchGoods 异常，keyword={}", keyword, e);
            return ResponseDto.failure("搜索失败：" + e.getMessage());
        }
    }

}
