package com.gxwebsoft.common.system.controller;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.common.core.Constants;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.Order;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.common.system.param.SubscriptionOrderParam;
import com.gxwebsoft.common.system.result.SubscriptionOrderCreateResult;
import com.gxwebsoft.common.system.result.SubscriptionOrderPayResult;
import com.gxwebsoft.common.system.result.SubscriptionPriceResult;
import com.gxwebsoft.common.system.service.SettingService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
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 javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;

/**
 * 订阅订单接口
 */
@Tag(name = "订阅订单")
@RestController
@RequestMapping("/api/system/subscription-order")
public class TenantSubscriptionOrderController extends BaseController {

  @Resource
  private SettingService settingService;
  @Resource
  private WxNativePayController wxNativePayController;

  @Operation(summary = "计算订阅订单价格")
  @PostMapping("/calculate-price")
  public ApiResult<SubscriptionPriceResult> calculatePrice(@RequestBody SubscriptionOrderParam param) {
    final User loginUser = getLoginUser();
    if (loginUser == null) {
      return fail("请先登录", null);
    }
    if (param.getPackageId() == null) {
      return fail("套餐ID不能为空", null);
    }

    JSONObject config = loadSubscriptionConfig();
    final SubscriptionPriceResult result = buildPriceResult(param, config);
    return success(result);
  }

  @Operation(summary = "创建订阅订单")
  @PostMapping("/create")
  public ApiResult<SubscriptionOrderCreateResult> create(@RequestBody SubscriptionOrderParam param) {
    final User loginUser = getLoginUser();
    if (loginUser == null) {
      return fail("请先登录", null);
    }
    if (param.getPackageId() == null) {
      return fail("套餐ID不能为空", null);
    }

    JSONObject config = loadSubscriptionConfig();
    final SubscriptionPriceResult price = buildPriceResult(param, config);

    SubscriptionOrderCreateResult result = new SubscriptionOrderCreateResult();
    result.setOrderNo(IdUtil.getSnowflakeNextIdStr());
    result.setPrice(price);
    return success(result);
  }

  @Operation(summary = "订阅订单支付（生成微信Native二维码）")
  @PostMapping("/pay")
  public ApiResult<SubscriptionOrderPayResult> pay(@RequestBody SubscriptionOrderParam param) {
    final User loginUser = getLoginUser();
    if (loginUser == null) {
      return fail("请先登录", null);
    }
    if (param.getPackageId() == null) {
      return fail("套餐ID不能为空", null);
    }

    JSONObject config = loadSubscriptionConfig();
    final SubscriptionPriceResult price = buildPriceResult(param, config);
    price.setPayPrice(new BigDecimal("0.01"));
    if (price.getPayPrice() == null || price.getPayPrice().compareTo(BigDecimal.ZERO) <= 0) {
      return fail("支付金额必须大于0", null);
    }

    // 构造订单用于生成支付二维码
    Order order = new Order();
    order.setPayPrice(price.getPayPrice());
    order.setTotalPrice(price.getTotalPrice());
    order.setComments("订阅套餐-" + param.getPackageId());
    order.setPayType(param.getPayType());
    order.setUserId(loginUser.getUserId());
    order.setTenantId(loginUser.getTenantId());

    ApiResult<?> payResp = wxNativePayController.getCodeUrl(order);
    if (payResp.getCode() == null || !payResp.getCode().equals(Constants.RESULT_OK_CODE)) {
      return fail(payResp.getMessage(), null);
    }

    SubscriptionOrderPayResult result = new SubscriptionOrderPayResult();
    result.setOrderNo(order.getOrderNo());
    result.setCodeUrl(String.valueOf(payResp.getData()));
    result.setPrice(price);
    return success(result);
  }

  /**
   * 从配置表读取订阅套餐配置（尝试多种key以兼容历史数据）
   */
  private JSONObject loadSubscriptionConfig() {
    final List<String> keys = Arrays.asList("subscription", "subscription-package", "subscriptionOrder");
    for (String key : keys) {
      try {
        JSONObject cfg = settingService.getBySettingKey(key);
        if (cfg != null) {
          return cfg;
        }
      } catch (Exception ignored) {
      }
    }
    return getDefaultSubscriptionConfig();
  }

  /**
   * 计算价格结果
   */
  private SubscriptionPriceResult buildPriceResult(SubscriptionOrderParam param, JSONObject config) {
    BigDecimal originalPrice = resolveBasePrice(param.getPackageId(), config);
    BigDecimal factor = BigDecimal.ONE;
    StringBuilder remark = new StringBuilder();

    boolean usingDefault = config != null && config.getBooleanValue("defaultConfig");
    if (usingDefault) {
      remark.append("订阅价格未配置，已使用默认配置；");
    } else if (config == null || config.isEmpty()) {
      remark.append("未查询到订阅价格配置，已按0元试算；");
    }
    if (originalPrice.compareTo(BigDecimal.ZERO) == 0 && config != null && !config.isEmpty()) {
      remark.append("未找到套餐价格，已按0元试算；");
    }

    if (isTrue(param.getIsRenewal())) {
      BigDecimal renewalFactor = resolveFactor(config, "renewalDiscount");
      factor = factor.multiply(renewalFactor);
      remark.append("续费系数:").append(renewalFactor).append(";");
    }

    if (isTrue(param.getIsUpgrade())) {
      BigDecimal upgradeFactor = resolveFactor(config, "upgradeDiscount");
      factor = factor.multiply(upgradeFactor);
      remark.append("升级系数:").append(upgradeFactor).append(";");
    }

    BigDecimal payTypeFactor = resolvePayTypeFactor(config, param.getPayType());
    factor = factor.multiply(payTypeFactor);
    if (param.getPayType() != null) {
      remark.append("支付系数:").append(payTypeFactor).append(";");
    }

    BigDecimal payPrice = originalPrice.multiply(factor).setScale(2, RoundingMode.HALF_UP);
    BigDecimal discount = originalPrice.subtract(payPrice);
    if (discount.compareTo(BigDecimal.ZERO) < 0) {
      discount = BigDecimal.ZERO;
    }

    SubscriptionPriceResult result = new SubscriptionPriceResult();
    result.setPackageId(param.getPackageId());
    result.setIsRenewal(param.getIsRenewal());
    result.setIsUpgrade(param.getIsUpgrade());
    result.setPayType(param.getPayType());
    result.setOriginalPrice(originalPrice.setScale(2, RoundingMode.HALF_UP));
    result.setTotalPrice(originalPrice.setScale(2, RoundingMode.HALF_UP));
    result.setPayPrice(payPrice);
    result.setDiscountAmount(discount.setScale(2, RoundingMode.HALF_UP));
    result.setRemark(remark.toString());
    return result;
  }

  private boolean isTrue(Integer value) {
    return value != null && value.equals(1);
  }

  /**
   * 解析套餐价格，支持 packages 数组、priceMap 或单价配置
   */
  private BigDecimal resolveBasePrice(Integer packageId, JSONObject config) {
    if (config != null) {
      JSONArray packages = config.getJSONArray("packages");
      if (packages != null) {
        for (Object item : packages) {
          if (item instanceof JSONObject) {
            JSONObject pkg = (JSONObject) item;
            Integer id = pkg.getInteger("id");
            if (id == null) {
              id = pkg.getInteger("packageId");
            }
            if (packageId.equals(id)) {
              BigDecimal price = pkg.getBigDecimal("price");
              if (price != null) {
                return price;
              }
            }
          }
        }
      }

      JSONObject priceMap = config.getJSONObject("priceMap");
      if (priceMap != null) {
        BigDecimal price = priceMap.getBigDecimal(packageId.toString());
        if (price != null) {
          return price;
        }
      }

      BigDecimal fallbackPrice = config.getBigDecimal("price");
      if (fallbackPrice != null) {
        return fallbackPrice;
      }
    }
    return BigDecimal.ZERO;
  }

  /**
   * 获取折扣系数，默认 1
   */
  private BigDecimal resolveFactor(JSONObject config, String key) {
    if (config != null) {
      BigDecimal factor = config.getBigDecimal(key);
      if (factor != null) {
        return factor;
      }
    }
    return BigDecimal.ONE;
  }

  /**
   * 支付方式系数，可在配置中通过 payTypeDiscount 或 payTypeAdjustments 定义
   */
  private BigDecimal resolvePayTypeFactor(JSONObject config, Integer payType) {
    if (config != null && payType != null) {
      JSONObject payTypeDiscount = config.getJSONObject("payTypeDiscount");
      if (payTypeDiscount == null) {
        payTypeDiscount = config.getJSONObject("payTypeAdjustments");
      }
      if (payTypeDiscount != null) {
        BigDecimal factor = payTypeDiscount.getBigDecimal(payType.toString());
        if (factor != null) {
          return factor;
        }
      }
    }
    return BigDecimal.ONE;
  }

  /**
   * 默认订阅配置（避免价格为0，可按需改成真实价格）
   */
  private JSONObject getDefaultSubscriptionConfig() {
    JSONObject config = new JSONObject();
    config.put("defaultConfig", true);

    // 默认套餐价格，按需调整
    JSONArray packages = new JSONArray();
    JSONObject pkg = new JSONObject();
    pkg.put("id", 2);
    pkg.put("price", new BigDecimal("1.00"));
    packages.add(pkg);
    config.put("packages", packages);

    // 默认系数
    config.put("renewalDiscount", BigDecimal.ONE);
    config.put("upgradeDiscount", BigDecimal.ONE);
    JSONObject payTypeDiscount = new JSONObject();
    payTypeDiscount.put("12", BigDecimal.ONE);
    config.put("payTypeDiscount", payTypeDiscount);
    return config;
  }
}
