package cn.qihangerp.service.external.pdd;

import cn.qihangerp.model.entity.OGoods;
import cn.qihangerp.model.entity.OGoodsSku;
import cn.qihangerp.model.request.ExternalGoodsUpsertRequest;
import cn.qihangerp.model.vo.ExternalGoodsUpsertResultVo;
import cn.qihangerp.module.service.OGoodsService;
import cn.qihangerp.module.service.OGoodsSkuService;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * <p><b>平台商品映射由 ERP-Open 落库</b>：中台仅调用 {@code /external/goods/upsert}、改库存等 HTTP，不持久化拼多多/京东等平台侧 ID。
 * 各渠道在 {@code o_goods}/{@code o_goods_sku}.{@code canonicalExt} 使用<strong>独立键名</strong>（拼多多为 {@value #CANONICAL_PDD_GOODS_ID}、{@value #CANONICAL_PDD_SKU_ID}），
 * 未来京东/天猫可并行增加 {@code jdSkuId} 等，改库存接口按平台从本库解析后再调 POP。</p>
 *
 * <p>拼多多：仅根据 {@code pdd.goods.add} 成功响应中的 {@code sku_list} 回填 {@value #CANONICAL_PDD_SKU_ID}；<strong>不在本服务内</strong>调用
 * {@code pdd.goods.detail.get}。{@code pdd.goods.information.update} 若未带 {@code sku_list}，则 {@code pddSkuId} 须由主数据在适当时机
 * 调 {@code POST /external/pdd/goods/detail} 成功后，由主数据再调 {@code POST /external/pdd/goods/sku-canonical-sync} 将
 * {@code sku_list} 映射合并写入 {@code o_goods_sku.canonical_ext}（键 {@value #CANONICAL_PDD_SKU_ID}）。</p>
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OGoodsPddMappingPersistence {

    public static final String CANONICAL_PDD_GOODS_ID = "pddGoodsId";
    public static final String CANONICAL_PDD_SKU_ID = "pddSkuId";

    private final OGoodsService goodsService;
    private final OGoodsSkuService skuService;

    /**
     * 在 upsert 拼多多链路成功（{@link ExternalGoodsUpsertResultVo#getPddPublishSuccess()}==true）后调用。
     * <p>只落 {@code pddGoodsId}，以及 {@code GOODS_ADD} 响应片段中能解析到的 SKU 映射；不发起 {@code detail.get}。</p>
     *
     * @param req 保留入参供调用方兼容；本方法不再使用 {@code pddPopAuth} 拉 detail
     */
    public void persistAfterPddPublishSuccess(Long erpGoodsId, ExternalGoodsUpsertRequest req,
                                              ExternalGoodsUpsertResultVo vo) {
        if (erpGoodsId == null || vo == null || !Boolean.TRUE.equals(vo.getPddPublishSuccess())) {
            return;
        }
        Long pddGoodsId = vo.getPddGoodsId();
        if (pddGoodsId == null || pddGoodsId <= 0) {
            log.warn("[PDD] skip persist mapping: pddGoodsId missing erpGoodsId={}", erpGoodsId);
            return;
        }
        OGoods g = goodsService.getById(erpGoodsId);
        if (g == null) {
            return;
        }
        g.setCanonicalExt(mergeJsonLongField(g.getCanonicalExt(), CANONICAL_PDD_GOODS_ID, pddGoodsId));
        g.setUpdateTime(new Date());
        goodsService.updateById(g);

        Map<String, Long> outerToPddSku = new LinkedHashMap<>();
        String lane = vo.getPddPublishLane();
        if (lane != null && "GOODS_ADD".equalsIgnoreCase(lane.trim())) {
            outerToPddSku.putAll(PddOpenApiSupport.parseOuterKeyToPddSkuIdFromGoodsAddResponse(vo.getPddResponseSnippet()));
        }
        int fromAdd = applyPddSkuMappings(erpGoodsId, outerToPddSku);
        if (!outerToPddSku.isEmpty()) {
            log.info("[PDD] persisted pddGoodsId + sku from GOODS_ADD snippet erpGoodsId={} lane={} skuRowsUpdated={}",
                    erpGoodsId, lane, fromAdd);
        } else {
            log.info("[PDD] persisted pddGoodsId on o_goods (no GOODS_ADD sku_list; no ERP-side detail.get) erpGoodsId={} lane={}",
                    erpGoodsId, lane);
        }
    }

    /**
     * 从 {@code pdd.goods.detail.get} 的 POP 原始 JSON 解析 {@code sku_list}，按 {@code outerErpSkuId} 合并写入
     * {@code o_goods_sku.canonicalExt.pddSkuId}（与 {@link #persistAfterPddPublishSuccess} 中 GOODS_ADD 片段逻辑一致）。
     *
     * @return 实际更新行数
     */
    public int mergePddSkuCanonicalFromGoodsDetailPop(Long erpGoodsId, String goodsDetailPopRaw) {
        if (erpGoodsId == null || erpGoodsId <= 0) {
            return 0;
        }
        Map<String, Long> outerToPddSku =
                PddOpenApiSupport.parseOuterKeyToPddSkuIdFromGoodsDetailGetResponse(goodsDetailPopRaw);
        return applyPddSkuMappings(erpGoodsId, outerToPddSku);
    }

    /**
     * 将 {@code outerKey -> 拼多多 sku_id} 合并写入 {@code o_goods_sku.canonicalExt}（键 {@value #CANONICAL_PDD_SKU_ID}）。
     *
     * @return 实际更新行数
     */
    private int applyPddSkuMappings(Long erpGoodsId, Map<String, Long> outerToPddSku) {
        if (outerToPddSku == null || outerToPddSku.isEmpty()) {
            return 0;
        }
        List<OGoodsSku> rows = skuService.list(new LambdaQueryWrapper<OGoodsSku>()
                .eq(OGoodsSku::getGoodsId, erpGoodsId));
        if (rows == null || rows.isEmpty()) {
            return 0;
        }
        int updated = 0;
        for (OGoodsSku row : rows) {
            if (row == null || !StringUtils.hasText(row.getOuterErpSkuId())) {
                continue;
            }
            Long pddSkuId = outerToPddSku.get(row.getOuterErpSkuId().trim());
            if (pddSkuId == null || pddSkuId <= 0) {
                continue;
            }
            row.setCanonicalExt(mergeJsonLongField(row.getCanonicalExt(), CANONICAL_PDD_SKU_ID, pddSkuId));
            row.setUpdateTime(new Date());
            skuService.updateById(row);
            updated++;
        }
        return updated;
    }

    private static String mergeJsonLongField(String existingJson, String field, long value) {
        JSONObject o;
        if (StringUtils.hasText(existingJson)) {
            try {
                o = JSON.parseObject(existingJson);
            } catch (Exception e) {
                o = new JSONObject();
            }
            if (o == null) {
                o = new JSONObject();
            }
        } else {
            o = new JSONObject();
        }
        o.put(field, value);
        return o.toJSONString();
    }
}
