package com.jeesharp.business.modules.common.bizscene.support;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jeesharp.business.modules.common.bizscene.vo.BizSceneOptionVO;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 优惠券 legacy {@code scene_code} 与 {@code cfg_biz_scene.scene_code} 双向映射及 ext_json 解析。
 *
 * @author jeesharp
 * @since 2026-07-03
 */
public final class BizSceneCouponLegacySupport {

  private static final Map<String, String> LEGACY_TO_CANONICAL;

  static {
    Map<String, String> map = new LinkedHashMap<>();
    map.put("MALL", "MALL_SPU");
    map.put("HOTEL", "HOTEL");
    map.put("FOOD", "FOOD_PACKAGE");
    map.put("SCENIC", "TICKET_VENUE");
    map.put("STUDY", "STUDY_PLAN");
    map.put("YEARCARD", "YEARCARD");
    map.put("FOOD_MEAL", "FOOD_RESTAURANT");
    LEGACY_TO_CANONICAL = Collections.unmodifiableMap(map);
  }

  private BizSceneCouponLegacySupport() {
  }

  /**
   * 将优惠券模板/会员券上的 legacy 或 canonical 编号解析为注册表 canonical {@code scene_code}。
   */
  public static String resolveCanonicalSceneCode(String sceneCode) {
    if (StrUtil.isBlank(sceneCode)) {
      return null;
    }
    String normalized = sceneCode.trim().toUpperCase();
    return LEGACY_TO_CANONICAL.getOrDefault(normalized, normalized);
  }

  /**
   * 将注册表场景转为优惠券模块对外使用的 legacy {@code scene_code}（模板表单、历史数据兼容）。
   */
  public static String toCouponLegacySceneCode(BizSceneOptionVO scene) {
    if (scene == null) {
      return null;
    }
    CouponExtMeta meta = parseCouponExt(scene.getExtJson());
    if (StrUtil.isNotBlank(meta.legacySceneCode())) {
      return meta.legacySceneCode();
    }
    String canonical = StrUtil.nullToEmpty(scene.getSceneCode()).trim().toUpperCase();
    for (Map.Entry<String, String> entry : LEGACY_TO_CANONICAL.entrySet()) {
      if (entry.getValue().equals(canonical)) {
        return entry.getKey();
      }
    }
    return scene.getSceneCode();
  }

  /**
   * 由注册表选项组装优惠券场景下拉项字段（legacy 编号 + 选品 URL）。
   */
  public static CouponScenePickerFields toCouponPickerFields(BizSceneOptionVO scene) {
    CouponScenePickerFields fields = new CouponScenePickerFields();
    fields.setSceneCode(toCouponLegacySceneCode(scene));
    fields.setSceneName(scene.getSceneName());

    CouponExtMeta meta = parseCouponExt(scene.getExtJson());
    fields.setSupportCategoryBrand(meta.supportCategoryBrand());

    BizScenePickerSupport.PickerFields picker =
        BizScenePickerSupport.resolve(scene, BizScenePickerSupport.PICKER_COUPON_SCOPE);
    fields.setRequestUrl(picker.getListUrl());
    fields.setKeywordField(picker.getKeywordField());
    fields.setNameField(picker.getNameField());
    fields.setScopeItemLabel(BizScenePickerSupport.resolveCouponScopeItemLabel(scene));
    return fields;
  }

  public static boolean hasRegistryMapping(String sceneCode) {
    if (StrUtil.isBlank(sceneCode)) {
      return false;
    }
    String normalized = sceneCode.trim().toUpperCase();
    return LEGACY_TO_CANONICAL.containsKey(normalized)
        || LEGACY_TO_CANONICAL.containsValue(normalized);
  }

  private static CouponExtMeta parseCouponExt(String extJson) {
    if (StrUtil.isBlank(extJson)) {
      return CouponExtMeta.EMPTY;
    }
    JSONObject root = JSONUtil.parseObj(extJson);
    JSONObject coupon = root.getJSONObject("coupon");
    String legacySceneCode = coupon != null ? coupon.getStr("legacySceneCode") : null;
    Integer supportCategoryBrand = coupon != null ? coupon.getInt("supportCategoryBrand") : null;
    JSONObject pickers = root.getJSONObject("pickers");
    return new CouponExtMeta(legacySceneCode, supportCategoryBrand, pickers, coupon);
  }

  private record CouponExtMeta(String legacySceneCode, Integer supportCategoryBrand, JSONObject pickers,
      JSONObject coupon) {

    private static final CouponExtMeta EMPTY = new CouponExtMeta(null, null, null, null);
  }

  /**
   * 优惠券场景选品元数据（由注册表映射而来）。
   */
  @lombok.Data
  public static class CouponScenePickerFields {

    private String sceneCode;
    private String sceneName;
    private String requestUrl;
    private String keywordField;
    private String nameField;
    private Integer supportCategoryBrand;
    /** 券模板「指定适用项」展示名，如商品、房型、套餐 */
    private String scopeItemLabel;
  }
}
