-- =====================================================================================
-- 数据分析模块（正式RPC，主库 ml_* 口径）
-- 文件: 05_ml_analytics_rpcs_product.sql
-- 主题: 商品洞察 (概览/趋势/排行/库存/价格/评价)
-- =====================================================================================

-- 1) 商品洞察核心 KPI
CREATE OR REPLACE FUNCTION public.rpc_product_insights_overview(
  p_start DATE,
  p_end DATE
)
RETURNS TABLE (
  total_products BIGINT,
  product_growth FLOAT,
  hot_products BIGINT,
  turnover_rate FLOAT,
  turnover_growth FLOAT,
  avg_stock NUMERIC,
  stock_growth FLOAT
)
LANGUAGE plpgsql
AS $$
DECLARE
    prev_start_date DATE;
    prev_end_date DATE;
    period_days INT;
BEGIN
    period_days := p_end - p_start + 1;
    prev_start_date := p_start - period_days;
    prev_end_date := p_start - 1;

    RETURN QUERY
    WITH
    cur AS (
        SELECT
            (SELECT COUNT(*) FROM public.ml_products WHERE status = 1 AND published_at <= p_end::timestamp) AS total_products,
            (SELECT COUNT(*) FROM public.ml_products WHERE status = 1 AND sale_count > 100) AS hot_products,
            (SELECT SUM(oi.quantity) FROM public.ml_order_items oi JOIN public.ml_orders o ON oi.order_id = o.id WHERE o.payment_status=2 AND o.created_at::date BETWEEN p_start AND p_end) AS total_sales_qty,
            (SELECT AVG(p.available_stock) FROM public.ml_products p WHERE p.status=1) AS avg_stock
    ),
    prev AS (
        SELECT
            (SELECT COUNT(*) FROM public.ml_products WHERE status = 1 AND published_at <= prev_end_date::timestamp) AS total_products,
            (SELECT SUM(oi.quantity) FROM public.ml_order_items oi JOIN public.ml_orders o ON oi.order_id = o.id WHERE o.payment_status=2 AND o.created_at::date BETWEEN prev_start_date AND prev_end_date) AS total_sales_qty,
            (SELECT AVG(p.available_stock) FROM public.ml_products p WHERE p.status=1) AS avg_stock
    )
    SELECT
        c.total_products,
        ROUND(((c.total_products - p.total_products) * 100.0 / NULLIF(p.total_products, 0))::numeric, 2)::FLOAT AS product_growth,
        c.hot_products,
        ROUND((c.total_sales_qty / NULLIF(c.avg_stock, 0))::numeric, 2)::FLOAT AS turnover_rate,
        ROUND(((c.total_sales_qty / NULLIF(c.avg_stock, 0)) - (p.total_sales_qty / NULLIF(p.avg_stock, 0)))::numeric, 2)::FLOAT AS turnover_growth,
        ROUND(c.avg_stock::numeric, 0) AS avg_stock,
        ROUND(((c.avg_stock - p.avg_stock) * 100.0 / NULLIF(p.avg_stock, 0))::numeric, 2)::FLOAT AS stock_growth
    FROM cur c, prev p;
END;
$$;


-- 2) 热销商品 TOP (带增长率)
-- 注意: growth 是与上一个同等时间周期的销量对比
CREATE OR REPLACE FUNCTION public.rpc_analytics_top_products(
    p_start_date DATE,
    p_end_date DATE,
    p_limit INT DEFAULT 10
)
RETURNS TABLE (
    id UUID,
    name TEXT,
    sales BIGINT,
    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
    current_sales AS (
        SELECT
            oi.product_id,
            SUM(oi.quantity)::BIGINT AS current_qty
        FROM public.ml_order_items oi
        JOIN public.ml_orders o ON o.id = oi.order_id
        WHERE o.payment_status = 2 AND o.created_at::DATE BETWEEN p_start_date AND p_end_date
        GROUP BY oi.product_id
    ),
    previous_sales AS (
        SELECT
            oi.product_id,
            SUM(oi.quantity)::BIGINT AS previous_qty
        FROM public.ml_order_items oi
        JOIN public.ml_orders o ON o.id = oi.order_id
        WHERE o.payment_status = 2 AND o.created_at::DATE BETWEEN prev_start_date AND prev_end_date
        GROUP BY oi.product_id
    )
    SELECT
        p.id,
        p.name::TEXT,
        cs.current_qty AS sales,
        ROUND(((cs.current_qty - COALESCE(ps.previous_qty, 0)) * 100.0 / NULLIF(COALESCE(ps.previous_qty, 0), 0))::numeric, 2)::FLOAT AS growth
    FROM current_sales cs
    JOIN public.ml_products p ON p.id = cs.product_id
    LEFT JOIN previous_sales ps ON ps.product_id = cs.product_id
    ORDER BY sales DESC
    LIMIT p_limit;
END;
$$;


-- 3) 单个商品销售趋势
CREATE OR REPLACE FUNCTION public.rpc_analytics_product_trend(
  p_start_date DATE,
  p_end_date DATE,
  p_product_id UUID
)
RETURNS TABLE (
  date TEXT,
  gmv NUMERIC,
  qty BIGINT,
  orders BIGINT
)
LANGUAGE sql
AS $$
  WITH date_series AS (
    SELECT generate_series(p_start_date, p_end_date, '1 day'::interval)::date AS d
  )
  SELECT
    to_char(ds.d, 'YYYY-MM-DD') AS date,
    COALESCE(SUM(oi.total_amount), 0) AS gmv,
    COALESCE(SUM(oi.quantity), 0)::BIGINT AS qty,
    COUNT(DISTINCT o.id)::BIGINT AS orders
  FROM date_series ds
  LEFT JOIN public.ml_orders o ON o.created_at::date = ds.d AND o.payment_status = 2
  LEFT JOIN public.ml_order_items oi ON oi.order_id = o.id AND oi.product_id = p_product_id
  GROUP BY ds.d
  ORDER BY ds.d;
$$;


-- 4) 商品库存分析 (按库存水平分箱)
CREATE OR REPLACE FUNCTION public.rpc_product_insights_stock()
RETURNS TABLE (
  stock_level TEXT,
  product_count BIGINT
)
LANGUAGE sql
AS $$
  SELECT
    CASE
      WHEN available_stock = 0 THEN '缺货'
      WHEN available_stock BETWEEN 1 AND 10 THEN '库存紧张 (1-10)'
      WHEN available_stock BETWEEN 11 AND 50 THEN '库存充足 (11-50)'
      WHEN available_stock BETWEEN 51 AND 100 THEN '库存充裕 (51-100)'
      ELSE '库存过剩 (>100)'
    END AS stock_level,
    COUNT(id)::BIGINT AS product_count
  FROM public.ml_products
  WHERE status = 1
  GROUP BY stock_level
  ORDER BY
    CASE stock_level
      WHEN '缺货' THEN 1
      WHEN '库存紧张 (1-10)' THEN 2
      WHEN '库存充足 (11-50)' THEN 3
      WHEN '库存充裕 (51-100)' THEN 4
      ELSE 5
    END;
$$;


-- 5) 商品评价分析 (按评分分箱)
CREATE OR REPLACE FUNCTION public.rpc_product_insights_reviews()
RETURNS TABLE (
  rating_level TEXT,
  review_count BIGINT
)
LANGUAGE sql
AS $$
  SELECT
    rating || ' 星' AS rating_level,
    COUNT(id)::BIGINT AS review_count
  FROM public.ml_product_reviews
  WHERE status = 1
  GROUP BY rating
  ORDER BY rating DESC;
$$;
