-- =====================================================================================
-- 数据分析模块（正式RPC，主库 ml_* 口径）
-- 文件: 02_ml_analytics_rpcs_sales.sql
-- 主题: 仪表盘/销售报表（KPI/趋势/TOP）
-- 口径约定:
--   - GMV: paid_amount 汇总（若为 0 则用 total_amount 兜底）
--   - 订单量: ml_orders created_at 期间内订单数（可按需要切换为支付订单数）
--   - 支付用户数: payment_status=2 的 distinct user_id
--   - 活跃用户数: ml_browse_history created_at 期间内 distinct user_id（弱口径）
--   - 转化率(A): 支付用户数 / 活跃用户数（*100）
-- =====================================================================================

-- 1) 销售核心 KPI（含上期对比）
CREATE OR REPLACE FUNCTION public.rpc_analytics_sales_kpis(
    p_start_date DATE,
    p_end_date DATE
)
RETURNS TABLE (
    gmv NUMERIC,
    gmv_growth FLOAT,
    orders BIGINT,
    order_growth FLOAT,
    conversion_rate FLOAT,
    conversion_growth FLOAT,
    avg_order_amount NUMERIC,
    avg_order_growth FLOAT
)
LANGUAGE plpgsql
AS $$
DECLARE
    prev_start_date DATE;
    prev_end_date DATE;
    period_days INT;
BEGIN
    period_days := p_end_date - p_start_date + 1;
    prev_start_date := p_start_date - period_days;
    prev_end_date := p_start_date - 1;

    RETURN QUERY
    WITH
    -- 当前周期
    cur AS (
        SELECT
            COALESCE(
              SUM(CASE WHEN o.payment_status = 2 THEN COALESCE(NULLIF(o.paid_amount, 0), o.total_amount) ELSE 0 END),
              0
            ) AS gmv,
            COUNT(*)::BIGINT AS orders,
            COUNT(DISTINCT CASE WHEN o.payment_status = 2 THEN o.user_id END)::BIGINT AS paid_users,
            (SELECT COUNT(DISTINCT bh.user_id) FROM public.ml_browse_history bh WHERE bh.created_at::DATE BETWEEN p_start_date AND p_end_date)::BIGINT AS active_users
        FROM public.ml_orders o
        WHERE o.created_at::DATE BETWEEN p_start_date AND p_end_date
    ),
    -- 上一周期
    prev AS (
        SELECT
            COALESCE(
              SUM(CASE WHEN o.payment_status = 2 THEN COALESCE(NULLIF(o.paid_amount, 0), o.total_amount) ELSE 0 END),
              0
            ) AS gmv,
            COUNT(*)::BIGINT AS orders,
            COUNT(DISTINCT CASE WHEN o.payment_status = 2 THEN o.user_id END)::BIGINT AS paid_users,
            (SELECT COUNT(DISTINCT bh.user_id) FROM public.ml_browse_history bh WHERE bh.created_at::DATE BETWEEN prev_start_date AND prev_end_date)::BIGINT AS active_users
        FROM public.ml_orders o
        WHERE o.created_at::DATE BETWEEN prev_start_date AND prev_end_date
    ),
    calc AS (
        SELECT
            cur.gmv AS gmv,
            cur.orders AS orders,
            CASE WHEN cur.active_users > 0 THEN (cur.paid_users::NUMERIC / cur.active_users::NUMERIC) * 100 ELSE 0 END AS conversion_rate,
            CASE WHEN cur.orders > 0 THEN cur.gmv / cur.orders ELSE 0 END AS avg_order_amount,

            prev.gmv AS prev_gmv,
            prev.orders AS prev_orders,
            CASE WHEN prev.active_users > 0 THEN (prev.paid_users::NUMERIC / prev.active_users::NUMERIC) * 100 ELSE 0 END AS prev_conversion_rate,
            CASE WHEN prev.orders > 0 THEN prev.gmv / prev.orders ELSE 0 END AS prev_avg_order_amount
        FROM cur, prev
    )
    SELECT
        ROUND(calc.gmv, 2) AS gmv,
        ROUND(((calc.gmv - calc.prev_gmv) * 100.0 / NULLIF(calc.prev_gmv, 0))::numeric, 2)::FLOAT AS gmv_growth,
        calc.orders,
        ROUND(((calc.orders - calc.prev_orders) * 100.0 / NULLIF(calc.prev_orders, 0))::numeric, 2)::FLOAT AS order_growth,
        ROUND(calc.conversion_rate::numeric, 2)::FLOAT AS conversion_rate,
        ROUND((calc.conversion_rate - calc.prev_conversion_rate)::numeric, 2)::FLOAT AS conversion_growth,
        ROUND(calc.avg_order_amount, 2) AS avg_order_amount,
        ROUND(((calc.avg_order_amount - calc.prev_avg_order_amount) * 100.0 / NULLIF(calc.prev_avg_order_amount, 0))::numeric, 2)::FLOAT AS avg_order_growth
    FROM calc;
END;
$$;


-- 2) 销售趋势（日维度：GMV + 订单数）
CREATE OR REPLACE FUNCTION public.rpc_analytics_sales_trend(
    p_start_date DATE,
    p_end_date DATE
)
RETURNS TABLE (
    date DATE,
    gmv NUMERIC,
    orders BIGINT
)
LANGUAGE sql
AS $$
    WITH date_series AS (
        SELECT generate_series(p_start_date, p_end_date, '1 day'::interval)::DATE AS date
    )
    SELECT
        ds.date,
        COALESCE(
          SUM(CASE WHEN o.payment_status = 2 THEN COALESCE(NULLIF(o.paid_amount, 0), o.total_amount) ELSE 0 END),
          0
        ) AS gmv,
        COUNT(o.id)::BIGINT AS orders
    FROM date_series ds
    LEFT JOIN public.ml_orders o
      ON o.created_at::DATE = ds.date
    GROUP BY ds.date
    ORDER BY ds.date;
$$;


-- 3) 热销商品 TOP（按销量：sum(quantity)）
CREATE OR REPLACE FUNCTION public.rpc_analytics_top_products(
    p_start_date DATE,
    p_end_date DATE,
    p_limit INT DEFAULT 50
)
RETURNS TABLE (
    id UUID,
    name TEXT,
    sales BIGINT
)
LANGUAGE sql
AS $$
    SELECT
        p.id,
        p.name::TEXT,
        COALESCE(SUM(oi.quantity), 0)::BIGINT AS sales
    FROM public.ml_order_items oi
    JOIN public.ml_orders o ON o.id = oi.order_id
    JOIN public.ml_products p ON p.id = oi.product_id
    WHERE o.created_at::DATE BETWEEN p_start_date AND p_end_date
      AND o.payment_status = 2
    GROUP BY p.id, p.name
    ORDER BY sales DESC
    LIMIT p_limit;
$$;


-- 4) 商家排行 TOP（按 GMV：支付 GMV）
CREATE OR REPLACE FUNCTION public.rpc_analytics_top_merchants(
    p_start_date DATE,
    p_end_date DATE,
    p_limit INT DEFAULT 50
)
RETURNS TABLE (
    id UUID,
    name TEXT,
    sales NUMERIC
)
LANGUAGE sql
AS $$
    SELECT
        m.id,
        COALESCE(NULLIF(m.username, ''), '未知商家')::TEXT AS name,
        COALESCE(SUM(COALESCE(NULLIF(o.paid_amount, 0), o.total_amount)), 0) AS sales
    FROM public.ml_orders o
    JOIN public.ak_users m ON m.id = o.merchant_id
    WHERE o.created_at::DATE BETWEEN p_start_date AND p_end_date
      AND o.payment_status = 2
    GROUP BY m.id, m.username
    ORDER BY sales DESC
    LIMIT p_limit;
$$;
