-- 手工补录订单推荐人 + 与支付回调一致的分佣累计（pending_earnings、referral_bindings）
-- 逻辑对齐 soul-api/internal/handler/miniprogram.go processReferralCommission
--      与 referral_commission.go computeOrderCommission
--
-- 使用前填写下面两个变量，并在测试库先执行「第四节」预览佣金。
-- MySQL 5.7+ / 8.0+（需 JSON 函数）
--
-- 若报 1267 Illegal mix of collations：表字段与客户端/会话默认 collation 不一致（常见 unicode_ci vs general_ci）。
-- 下面 SET NAMES + 字符串比较处 COLLATE 已对齐；若库表统一为 general_ci，可把脚本中 utf8mb4_unicode_ci 全部改为 utf8mb4_general_ci。

SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;

-- ============ 1. 填写 ============
SET @order_sn = 'MP20260508082957878950';
SET @referrer_id = 'ogpTW5QBRQNUOm4-zvg8it2XySrI';
-- =================================

SET @cfg := (
  SELECT config_value FROM system_config
  WHERE config_key COLLATE utf8mb4_unicode_ci = CONVERT('referral_config' USING utf8mb4) COLLATE utf8mb4_unicode_ci
  LIMIT 1
);

SELECT id, user_id, amount, product_type, status, pay_time
INTO @order_id, @buyer_id, @amt, @ptype, @ostatus, @pay_time
FROM orders
WHERE order_sn COLLATE utf8mb4_unicode_ci = (@order_sn COLLATE utf8mb4_unicode_ci)
LIMIT 1;

SELECT COUNT(*) INTO @ref_exists FROM users
WHERE id COLLATE utf8mb4_unicode_ci = (@referrer_id COLLATE utf8mb4_unicode_ci);
SET @ref_code := NULL;
SELECT referral_code INTO @ref_code FROM users
WHERE id COLLATE utf8mb4_unicode_ci = (@referrer_id COLLATE utf8mb4_unicode_ci)
LIMIT 1;

SET @dist_pct := COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(@cfg, '$.distributorShare')) AS DECIMAL(18,6)), 90);
SET @disc_pct := COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(@cfg, '$.userDiscount')) AS DECIMAL(18,6)), 0);
SET @vip_vip_pct := COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(@cfg, '$.vipOrderShareVip')) AS DECIMAL(18,6)), 20);
SET @vip_non_pct := COALESCE(CAST(JSON_UNQUOTE(JSON_EXTRACT(@cfg, '$.vipOrderShareNonVip')) AS DECIMAL(18,6)), 10);

SET @disc := @disc_pct / 100;
SET @dist := @dist_pct / 100;

SET @ref_is_vip := IFNULL((
  SELECT (COALESCE(u.is_vip, 0) <> 0)
         AND (u.vip_expire_date IS NULL OR u.vip_expire_date > NOW())
  FROM users u
  WHERE u.id COLLATE utf8mb4_unicode_ci = (@referrer_id COLLATE utf8mb4_unicode_ci)
  LIMIT 1
), 0);

SET @commission := CASE
  WHEN @order_id IS NULL THEN NULL
  WHEN @ref_exists = 0 THEN NULL
  WHEN (@ostatus COLLATE utf8mb4_unicode_ci) <> (CONVERT('paid' USING utf8mb4) COLLATE utf8mb4_unicode_ci) THEN NULL
  WHEN (@buyer_id COLLATE utf8mb4_unicode_ci) = (@referrer_id COLLATE utf8mb4_unicode_ci) THEN 0
  WHEN @ptype COLLATE utf8mb4_unicode_ci IN (
    CONVERT('link_karuo_tip' USING utf8mb4) COLLATE utf8mb4_unicode_ci,
    CONVERT('mentor_consultation' USING utf8mb4) COLLATE utf8mb4_unicode_ci
  ) THEN 0
  WHEN (@ptype COLLATE utf8mb4_unicode_ci) = (CONVERT('vip' USING utf8mb4) COLLATE utf8mb4_unicode_ci) THEN @amt * IF(
    @ref_is_vip,
    @vip_vip_pct / 100,
    @vip_non_pct / 100
  )
  ELSE
    (
      CASE
        WHEN @disc > 0 THEN @amt / (1 - @disc)
        ELSE @amt
      END
    ) * @dist
END;

SET @commission := ROUND(IFNULL(@commission, 0), 2);

-- ============ 4. 预览（先单独执行到上一行，检查变量）============
SELECT
  @order_id AS order_id,
  @order_sn AS order_sn,
  @buyer_id AS buyer_user_id,
  @referrer_id AS referrer_user_id,
  @amt AS amount,
  @ptype AS product_type,
  @ostatus AS order_status,
  @commission AS commission_to_add,
  @ref_code AS referrer_code_for_order,
  @pay_time AS order_pay_time;

-- 若 @order_id / @ref_exists / status 异常，不要执行下面事务。

-- ============ 5. 执行变更（确认预览无误后执行）============
START TRANSACTION;

UPDATE orders
SET
  referrer_id = @referrer_id,
  referral_code = IFNULL(@ref_code, referral_code)
WHERE id = @order_id
  AND order_sn COLLATE utf8mb4_unicode_ci = (@order_sn COLLATE utf8mb4_unicode_ci)
  AND @ref_exists > 0
  AND (@buyer_id COLLATE utf8mb4_unicode_ci) <> (@referrer_id COLLATE utf8mb4_unicode_ci);

UPDATE users
SET pending_earnings = COALESCE(pending_earnings, 0) + @commission
WHERE id COLLATE utf8mb4_unicode_ci = (@referrer_id COLLATE utf8mb4_unicode_ci)
  AND @commission > 0;

UPDATE referral_bindings rb
INNER JOIN (
  SELECT id
  FROM referral_bindings
  WHERE referee_id COLLATE utf8mb4_unicode_ci = (@buyer_id COLLATE utf8mb4_unicode_ci)
    AND referrer_id COLLATE utf8mb4_unicode_ci = (@referrer_id COLLATE utf8mb4_unicode_ci)
    AND status COLLATE utf8mb4_unicode_ci = (CONVERT('active' USING utf8mb4) COLLATE utf8mb4_unicode_ci)
  ORDER BY binding_date DESC
  LIMIT 1
) t ON rb.id = t.id
SET
  last_purchase_date = COALESCE(@pay_time, NOW()),
  purchase_count = COALESCE(purchase_count, 0) + 1,
  total_commission = COALESCE(total_commission, 0) + @commission
WHERE @commission > 0;

COMMIT;

-- ============ 6. 备注 ============
-- · 若 referral_bindings 无对应 (买家,推荐人) 的 active 行，UPDATE 影响 0 行，属正常；
--   需业务上是否补插绑定记录另行处理。
-- · 若订单已有 referrer_id，本脚本会覆盖为 @referrer_id。
-- · commission 为 0 时仍会更新 orders 的推荐人字段，但不加 pending_earnings / 绑定累计。
