package cn.qihangerp.erp.controller;

import cn.qihangerp.common.AjaxResult;
import cn.qihangerp.common.enums.EnumShopType;
import cn.qihangerp.model.request.ExternalGoodsDelistRequest;
import cn.qihangerp.model.request.ExternalGoodsPddQuantityUpdateRequest;
import cn.qihangerp.model.request.ExternalGoodsUpsertRequest;
import cn.qihangerp.model.vo.ExternalGoodsPddQuantityUpdateResultVo;
import cn.qihangerp.model.vo.ExternalGoodsUpsertResultVo;
import cn.qihangerp.security.common.BaseController;
import cn.qihangerp.erp.config.ExternalGoodsApiLogProperties;
import cn.qihangerp.erp.support.ExternalGoodsRequestLogSupport;
import cn.qihangerp.service.external.ExternalGoodsAppService;
import cn.qihangerp.service.external.ExternalGoodsPddQuantityUpdateAppService;
import cn.qihangerp.service.external.pdd.ExternalPddProperties;
import com.alibaba.fastjson2.JSON;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * External goods entry（AK/SK 由安全过滤器校验）。
 * <p>不查询 {@code o_shop}：{@code shopId} 仅作业务侧店铺维度标识写入 {@code o_goods}/{@code o_goods_sku}。</p>
 * <ul>
 *   <li>{@code POST /external/goods/upsert} — 商品上架/同步（新建默认 {@code o_goods.status=1}）</li>
 *   <li>{@code POST /external/goods/delist} — 本地下架（{@code status=2}）；可选 {@code pddGoodsId}+{@code pddPopAuth} 调拼多多 {@code pdd.goods.sale.status.set}（{@code is_onsale=0}）</li>
 *   <li>{@code POST /external/goods/pdd/quantity/update} — 按 {@code shopId}+{@code outGoodsId}+{@code outSkuId} 解析本地映射后调 {@code pdd.goods.quantity.update}</li>
 * </ul>
 *
 * @author guochengyu
 */
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/external/goods")
public class ExternalGoodsController extends BaseController {
    private final ExternalGoodsAppService externalGoodsAppService;
    private final ExternalGoodsPddQuantityUpdateAppService externalGoodsPddQuantityUpdateAppService;
    private final ExternalPddProperties externalPddProperties;
    private final ExternalGoodsApiLogProperties goodsApiLogProperties;

    @PostMapping("/upsert")
    public AjaxResult upsert(@RequestBody ExternalGoodsUpsertRequest req) {
        if (goodsApiLogProperties.isLogFullRequest()) {
            log.info("[external/goods/upsert] request={}", ExternalGoodsRequestLogSupport.upsertRequestJsonForLog(req));
        }
        if (req == null || req.getShopId() == null || req.getShopId() <= 0) {
            return AjaxResult.error("参数错误：shopId不能为空");
        }
        if (!StringUtils.hasText(req.getPlatform())) {
            return AjaxResult.error("参数错误：platform不能为空");
        }
        if (!StringUtils.hasText(req.getOutGoodsId())) {
            return AjaxResult.error("参数错误：outGoodsId不能为空");
        }
        if (!StringUtils.hasText(req.getTitle())) {
            return AjaxResult.error("参数错误：title不能为空");
        }
        if (!StringUtils.hasText(req.getCategoryCode())) {
            return AjaxResult.error("参数错误：categoryCode不能为空");
        }
        if (!hasMainVisual(req)) {
            return AjaxResult.error("参数错误：mainImage 与 images 至少填一种");
        }
        if (req.getSkus() != null) {
            for (var s : req.getSkus()) {
                if (s == null || !StringUtils.hasText(s.getOutSkuId())) {
                    continue;
                }
                if (s.getSalePrice() == null && s.getRetailPrice() == null) {
                    return AjaxResult.error("参数错误：sku 需填写 salePrice 或 retailPrice，outSkuId=" + s.getOutSkuId());
                }
            }
        }

        EnumShopType platform;
        try {
            platform = EnumShopType.valueOf(req.getPlatform().trim());
        } catch (Exception ex) {
            return AjaxResult.error("platform不合法");
        }

        if (EnumShopType.PDD.equals(platform)) {
            log.info("[external/goods/upsert] pdd.publish-enabled={} gatewayHost={} categoryMapKeys={}",
                    externalPddProperties.isPublishEnabled(),
                    safeHostForLog(externalPddProperties.getGatewayUrl()),
                    externalPddProperties.getCategoryMap() != null
                            ? externalPddProperties.getCategoryMap().keySet().toString()
                            : "null");
        }

        if (EnumShopType.PDD.equals(platform) && externalPddProperties.isPublishEnabled()) {
            if (req.getPddPopAuth() == null) {
                return AjaxResult.error("参数错误：开启拼多多发布时 pddPopAuth 不能为空");
            }
            var auth = req.getPddPopAuth();
            if (!StringUtils.hasText(auth.getAppKey()) || !StringUtils.hasText(auth.getAppSecret())
                    || !StringUtils.hasText(auth.getAccessToken())) {
                return AjaxResult.error("参数错误：pddPopAuth 需提供 appKey、appSecret、accessToken");
            }
        }

        ExternalGoodsUpsertResultVo vo = externalGoodsAppService.upsertGoods(req);
        log.info("[external/goods/upsert] response shopId={} outGoodsId={} erpGoodsId={} platform={}",
                req.getShopId(), req.getOutGoodsId(), vo.getGoodsId(), req.getPlatform());
        if (EnumShopType.PDD.equals(platform)) {
            log.info("[external/goods/upsert] pddPublish attempted={} success={} message={}",
                    vo.getPddPublishAttempted(),
                    vo.getPddPublishSuccess(),
                    truncateLog(vo.getPddPublishMessage(), 800));
        }
        return AjaxResult.success(vo);
    }

    /**
     * 本地下架：将 {@code o_goods.status} 置为 2；若传 {@code pddGoodsId} 则同步拼多多在售状态（见 {@code external.pdd.sale-status-set-enabled}）。
     */
    @PostMapping("/delist")
    public AjaxResult delist(@RequestBody ExternalGoodsDelistRequest req) {
        if (goodsApiLogProperties.isLogFullRequest()) {
            log.info("[external/goods/delist] request={}", req == null ? "null" : JSON.toJSONString(req));
        }
        if (req == null || req.getShopId() == null || req.getShopId() <= 0) {
            return AjaxResult.error("参数错误：shopId不能为空");
        }
        if (!StringUtils.hasText(req.getOutGoodsId())) {
            return AjaxResult.error("参数错误：outGoodsId不能为空");
        }
        if (req.getPddGoodsId() != null && req.getPddGoodsId() > 0 && externalPddProperties.isSaleStatusSetEnabled()) {
            var auth = req.getPddPopAuth();
            if (auth == null || !StringUtils.hasText(auth.getAppKey()) || !StringUtils.hasText(auth.getAppSecret())
                    || !StringUtils.hasText(auth.getAccessToken())) {
                return AjaxResult.error("参数错误：传 pddGoodsId 下架拼多多时，pddPopAuth 需提供 appKey、appSecret、accessToken");
            }
        }
        try {
            externalGoodsAppService.delistGoods(req);
            return AjaxResult.success();
        } catch (IllegalArgumentException ex) {
            return AjaxResult.error(ex.getMessage());
        }
    }

    /**
     * 拼多多改库存：入参与 upsert 对齐（{@code shopId}、{@code outGoodsId}、{@code outSkuId}），不传拼多多 goods/sku id。
     */
    @PostMapping("/pdd/quantity/update")
    public AjaxResult pddQuantityUpdate(@RequestBody ExternalGoodsPddQuantityUpdateRequest req) {
        if (goodsApiLogProperties.isLogFullRequest()) {
            log.info("[external/goods/pdd/quantity/update] request={}",
                    ExternalGoodsRequestLogSupport.goodsPddQuantityUpdateRequestJsonForLog(req));
        }
        if (req == null || req.getShopId() == null || req.getShopId() <= 0) {
            return AjaxResult.error("参数错误：shopId不能为空");
        }
        if (!StringUtils.hasText(req.getOutGoodsId())) {
            return AjaxResult.error("参数错误：outGoodsId不能为空");
        }
        if (!StringUtils.hasText(req.getOutSkuId())) {
            return AjaxResult.error("参数错误：outSkuId不能为空");
        }
        if (req.getQuantity() == null || req.getQuantity() < 0) {
            return AjaxResult.error("参数错误：quantity 不能为空且不能为负");
        }
        if (req.getPddPopAuth() == null) {
            return AjaxResult.error("参数错误：pddPopAuth 不能为空");
        }
        var auth = req.getPddPopAuth();
        if (!StringUtils.hasText(auth.getAppKey()) || !StringUtils.hasText(auth.getAppSecret())
                || !StringUtils.hasText(auth.getAccessToken())) {
            return AjaxResult.error("参数错误：pddPopAuth 需提供 appKey、appSecret、accessToken");
        }
        ExternalGoodsPddQuantityUpdateResultVo vo = externalGoodsPddQuantityUpdateAppService.updateQuantity(req);
        if (!Boolean.TRUE.equals(vo.getPopBizSuccess())) {
            return AjaxResult.error(StringUtils.hasText(vo.getMessage()) ? vo.getMessage() : "pdd.goods.quantity.update 失败");
        }
        return AjaxResult.success(vo);
    }

    private static String safeHostForLog(String gatewayUrl) {
        if (!StringUtils.hasText(gatewayUrl)) {
            return "";
        }
        try {
            java.net.URI u = java.net.URI.create(gatewayUrl.trim());
            String h = u.getHost();
            return h != null ? h : gatewayUrl.trim();
        } catch (Exception e) {
            return gatewayUrl.trim();
        }
    }

    private static String truncateLog(String s, int max) {
        if (s == null) {
            return "";
        }
        return s.length() <= max ? s : s.substring(0, max) + "...";
    }

    private static boolean hasMainVisual(ExternalGoodsUpsertRequest req) {
        if (StringUtils.hasText(req.getMainImage())) {
            return true;
        }
        List<String> imgs = req.getImages();
        if (imgs == null || imgs.isEmpty()) {
            return false;
        }
        for (String u : imgs) {
            if (StringUtils.hasText(u)) {
                return true;
            }
        }
        return false;
    }
}
