-- 历史订单价格语义修复
--
-- 背景：旧版代码将 order.total_amount 错误地设置为成本价（买家实付金额），
--       而非零售价（客户端展示价格）。order_item.unit_price 同理。
--       本迁移通过 tb_shop_package_allocation.retail_price 修复历史记录。
--
-- 识别条件：order_item.unit_price = 该代理商对该套餐的当前成本价（spa.cost_price）
--            且 order_item.cost_price = 0（尚未修复）
--
-- 注意：使用"当前"代理商零售价修复历史数据，若价格自下单以来已调整，
--       修复后的价格为当前价格而非历史价格，属已知局限。

BEGIN;

-- Step 1: 同步修复 order_item 三个字段
--   cost_price ← 旧 unit_price（成本价备份）
--   unit_price ← 代理商当前零售价（优先）或套餐建议零售价（兜底）
--   amount     ← 重算小计
WITH correct_item_prices AS (
    SELECT
        oi.id                                                   AS item_id,
        oi.unit_price                                           AS old_cost_price,
        COALESCE(
            NULLIF(spa.retail_price, 0),
            NULLIF(p.suggested_retail_price, 0),
            oi.unit_price
        )                                                       AS new_unit_price,
        oi.quantity
    FROM tb_order_item oi
    JOIN tb_order o
        ON o.id = oi.order_id
        AND o.deleted_at IS NULL
    JOIN tb_shop_package_allocation spa
        ON spa.shop_id    = o.seller_shop_id
        AND spa.package_id = oi.package_id
        AND spa.deleted_at IS NULL
    JOIN tb_package p
        ON p.id = oi.package_id
    WHERE oi.deleted_at IS NULL
      AND oi.cost_price = 0              -- 尚未修复的记录
      AND oi.unit_price > 0             -- 排除赠送套餐（unit_price=0）
      AND oi.unit_price = spa.cost_price -- 旧语义标识：unit_price 存的是代理成本价
)
UPDATE tb_order_item oi
SET
    cost_price = c.old_cost_price,
    unit_price = c.new_unit_price,
    amount     = c.new_unit_price * c.quantity
FROM correct_item_prices c
WHERE oi.id = c.item_id;

-- Step 2: 将 order.total_amount 更新为零售价合计
UPDATE tb_order o
SET total_amount = sub.new_total
FROM (
    SELECT
        oi.order_id,
        SUM(oi.unit_price * oi.quantity) AS new_total
    FROM tb_order_item oi
    WHERE oi.deleted_at IS NULL
    GROUP BY oi.order_id
) sub
WHERE o.id          = sub.order_id
  AND o.deleted_at IS NULL
  AND o.total_amount != sub.new_total;  -- 只更新实际需要变动的

-- Step 3: 回填 package_usage.retail_amount（修复后的零售价快照）
UPDATE tb_package_usage pu
SET retail_amount = o.total_amount
FROM tb_order o
WHERE pu.order_id     = o.id
  AND pu.order_id    != 0
  AND pu.retail_amount IS NULL
  AND o.deleted_at   IS NULL;

COMMIT;
