-- ============================================
-- DATA_DETAIL_RPCS.sql
-- 数据分析详情页专用 RPC 定义
-- ============================================
-- 目标：
--  1) 为 `pages/mall/analytics/data-detail.uvue` 提供统一的数据服务
--  2) 仅复用现有 analytics_* 表与业务表，不新增物理表
--  3) 权限完全依赖各表自身的 RLS 策略，本文件只负责函数与 GRANT
--
-- 依赖前置脚本：
--  - 01_create_tables.sql
--  - ../../user/test/USER_AUTH_SCHEMA.sql
--  - ../../user/test/USER_AUTH_TRIGGER.sql
--  - ANALYTICS_DB_SCHEMA.sql
--
-- 使用说明：
--  - 前端通过 supabase-js / UTS 调用 `rpc()` 访问本文件中的函数
--  - 所有函数仅对 `authenticated` 角色开放执行权限
-- ============================================

-- --------------------------------------------
-- 1. 报表基础信息（用于初始化筛选器）
-- --------------------------------------------
-- 根据报表 ID 返回基础配置，包含标题、类型、时间范围等
CREATE OR REPLACE FUNCTION public.rpc_data_detail_report_info(
  p_report_id uuid
)
RETURNS TABLE (
  id uuid,
  title text,
  type text,
  period text,
  date_start date,
  date_end date,
  status text,
  merchant_id uuid
)
LANGUAGE sql
AS $$
  SELECT
    r.id,
    r.title,
    r.type,
    r.period,
    r.date_start,
    r.date_end,
    r.status,
    r.merchant_id
  FROM public.analytics_reports r
  WHERE r.id = p_report_id
$$;

REVOKE ALL ON FUNCTION public.rpc_data_detail_report_info(uuid) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_data_detail_report_info(uuid) TO authenticated;


-- --------------------------------------------
-- 2. 报表明细行（表格数据）
-- --------------------------------------------
-- 说明：
--  - 以 analytics_report_rows 作为数据源
--  - 可按日期 / GMV / 订单数 / 用户数排序
--  - 维度信息通过 extra(JSONB) 透出，前端可自由解析
CREATE OR REPLACE FUNCTION public.rpc_data_detail_rows(
  p_report_id uuid,
  p_sort_by   text DEFAULT 'row_date', -- row_date | gmv | orders | users
  p_sort_dir  text DEFAULT 'asc',      -- asc | desc
  p_limit     integer DEFAULT 200,
  p_offset    integer DEFAULT 0
)
RETURNS TABLE (
  row_date date,
  gmv numeric,
  orders integer,
  users integer,
  conversion numeric,
  avg_order_amount numeric,
  extra jsonb
)
LANGUAGE plpgsql
AS $$
BEGIN
  -- 统一的 LIMIT / OFFSET 处理
  IF lower(p_sort_by) = 'gmv' THEN
    IF lower(p_sort_dir) = 'desc' THEN
      RETURN QUERY
      SELECT
        r.row_date,
        r.gmv,
        r.orders,
        r.users,
        r.conversion,
        r.avg_order_amount,
        r.extra
      FROM public.analytics_report_rows r
      WHERE r.report_id = p_report_id
      ORDER BY r.gmv DESC, r.row_date DESC
      LIMIT GREATEST(p_limit, 0)
      OFFSET GREATEST(p_offset, 0);
    ELSE
      RETURN QUERY
      SELECT
        r.row_date,
        r.gmv,
        r.orders,
        r.users,
        r.conversion,
        r.avg_order_amount,
        r.extra
      FROM public.analytics_report_rows r
      WHERE r.report_id = p_report_id
      ORDER BY r.gmv ASC, r.row_date ASC
      LIMIT GREATEST(p_limit, 0)
      OFFSET GREATEST(p_offset, 0);
    END IF;

  ELSIF lower(p_sort_by) = 'orders' THEN
    IF lower(p_sort_dir) = 'desc' THEN
      RETURN QUERY
      SELECT
        r.row_date,
        r.gmv,
        r.orders,
        r.users,
        r.conversion,
        r.avg_order_amount,
        r.extra
      FROM public.analytics_report_rows r
      WHERE r.report_id = p_report_id
      ORDER BY r.orders DESC, r.row_date DESC
      LIMIT GREATEST(p_limit, 0)
      OFFSET GREATEST(p_offset, 0);
    ELSE
      RETURN QUERY
      SELECT
        r.row_date,
        r.gmv,
        r.orders,
        r.users,
        r.conversion,
        r.avg_order_amount,
        r.extra
      FROM public.analytics_report_rows r
      WHERE r.report_id = p_report_id
      ORDER BY r.orders ASC, r.row_date ASC
      LIMIT GREATEST(p_limit, 0)
      OFFSET GREATEST(p_offset, 0);
    END IF;

  ELSIF lower(p_sort_by) = 'users' THEN
    IF lower(p_sort_dir) = 'desc' THEN
      RETURN QUERY
      SELECT
        r.row_date,
        r.gmv,
        r.orders,
        r.users,
        r.conversion,
        r.avg_order_amount,
        r.extra
      FROM public.analytics_report_rows r
      WHERE r.report_id = p_report_id
      ORDER BY r.users DESC, r.row_date DESC
      LIMIT GREATEST(p_limit, 0)
      OFFSET GREATEST(p_offset, 0);
    ELSE
      RETURN QUERY
      SELECT
        r.row_date,
        r.gmv,
        r.orders,
        r.users,
        r.conversion,
        r.avg_order_amount,
        r.extra
      FROM public.analytics_report_rows r
      WHERE r.report_id = p_report_id
      ORDER BY r.users ASC, r.row_date ASC
      LIMIT GREATEST(p_limit, 0)
      OFFSET GREATEST(p_offset, 0);
    END IF;

  ELSE
    -- 默认按日期排序
    IF lower(p_sort_dir) = 'desc' THEN
      RETURN QUERY
      SELECT
        r.row_date,
        r.gmv,
        r.orders,
        r.users,
        r.conversion,
        r.avg_order_amount,
        r.extra
      FROM public.analytics_report_rows r
      WHERE r.report_id = p_report_id
      ORDER BY r.row_date DESC
      LIMIT GREATEST(p_limit, 0)
      OFFSET GREATEST(p_offset, 0);
    ELSE
      RETURN QUERY
      SELECT
        r.row_date,
        r.gmv,
        r.orders,
        r.users,
        r.conversion,
        r.avg_order_amount,
        r.extra
      FROM public.analytics_report_rows r
      WHERE r.report_id = p_report_id
      ORDER BY r.row_date ASC
      LIMIT GREATEST(p_limit, 0)
      OFFSET GREATEST(p_offset, 0);
    END IF;
  END IF;
END;
$$;

REVOKE ALL ON FUNCTION public.rpc_data_detail_rows(uuid,text,text,integer,integer) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_data_detail_rows(uuid,text,text,integer,integer) TO authenticated;


-- --------------------------------------------
-- 3. 钻取指标列表（KPI / 汇总卡片）
-- --------------------------------------------
-- 说明：
--  - 直接从 analytics_report_metrics 读取
--  - 前端可根据 format 字段决定展示方式（数字 / 金额 / 百分比）
CREATE OR REPLACE FUNCTION public.rpc_data_detail_drill_items(
  p_report_id uuid
)
RETURNS TABLE (
  metric_key text,
  metric_label text,
  metric_value_num numeric,
  metric_value_text text,
  format text,
  change_pct numeric,
  icon text,
  color text
)
LANGUAGE sql
AS $$
  SELECT
    m.metric_key,
    m.metric_label,
    m.metric_value_num,
    m.metric_value_text,
    m.format,
    m.change_pct,
    m.icon,
    m.color
  FROM public.analytics_report_metrics m
  WHERE m.report_id = p_report_id
  ORDER BY m.metric_key
$$;

REVOKE ALL ON FUNCTION public.rpc_data_detail_drill_items(uuid) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_data_detail_drill_items(uuid) TO authenticated;


-- --------------------------------------------
-- 4. GMV 对比数据（当前周期 vs 对比周期）
-- --------------------------------------------
-- 说明：
--  - 当前周期 = analytics_reports.period / date_start/date_end 所定义的范围
--  - 对比周期 = 与当前周期长度相同的上一段时间
--  - 聚合来源：orders
CREATE OR REPLACE FUNCTION public.rpc_data_detail_compare_gmv(
  p_report_id uuid
)
RETURNS TABLE (
  day date,
  gmv_current numeric,
  gmv_previous numeric
)
LANGUAGE plpgsql
AS $$
DECLARE
  v_date_start date;
  v_date_end   date;
  v_period_len integer;
BEGIN
  SELECT
    COALESCE(r.date_start, (now() - INTERVAL '7 days')::date),
    COALESCE(r.date_end, now()::date)
  INTO v_date_start, v_date_end
  FROM public.analytics_reports r
  WHERE r.id = p_report_id;

  IF v_date_start IS NULL OR v_date_end IS NULL THEN
    RETURN;
  END IF;

  v_period_len := (v_date_end - v_date_start) + 1;

  RETURN QUERY
  WITH cur AS (
    SELECT
      o.created_at::date AS day,
      SUM(o.total_amount) AS gmv
    FROM public.orders o
    WHERE o.created_at::date BETWEEN v_date_start AND v_date_end
      AND o.status = 2
    GROUP BY o.created_at::date
  ),
  prev_range AS (
    SELECT
      (v_date_start - v_period_len) AS start_date,
      (v_date_start - 1)            AS end_date
  ),
  prev AS (
    SELECT
      o.created_at::date AS day,
      SUM(o.total_amount) AS gmv
    FROM public.orders o, prev_range pr
    WHERE o.created_at::date BETWEEN pr.start_date AND pr.end_date
      AND o.status = 2
    GROUP BY o.created_at::date
  ),
  series AS (
    SELECT generate_series(v_date_start, v_date_end, INTERVAL '1 day')::date AS day
  )
  SELECT
    s.day,
    COALESCE(c.gmv, 0)  AS gmv_current,
    COALESCE(p.gmv, 0)  AS gmv_previous
  FROM series s
  LEFT JOIN cur  c ON c.day = s.day
  LEFT JOIN prev p ON p.day = (s.day - v_period_len);
END;
$$;

REVOKE ALL ON FUNCTION public.rpc_data_detail_compare_gmv(uuid) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_data_detail_compare_gmv(uuid) TO authenticated;


-- ============================================
-- 文件结束
-- ============================================

