-- =====================================================================================
-- 数据分析模块（正式RPC，主库 ml_* 口径）
-- 文件: 09_ml_analytics_rpcs_data_detail.sql
-- 主题: data-detail 动态报表执行引擎（MVP：sales + users）
-- 依赖: public.analytics_reports, public.ml_orders, public.ml_order_items, public.ml_products, public.ml_categories,
--       public.ml_browse_history, public.ak_users
--
-- 设计原则：
-- - 不允许自由 SQL；使用 dataset/dimensions/metrics 的白名单解析。
-- - definition JSONB 结构（建议）:
--   {
--     "dataset": "sales" | "users",
--     "dimensions": ["date"|"category"|"merchant"|"source"],
--     "metrics": ["gmv"|"orders"|"paid_users"|"new_users"|"active_users"],
--     "limit": 200
--   }
-- - 请求参数 p_params JSONB 可覆盖时间范围等：
--   {
--     "start_date": "YYYY-MM-DD",
--     "end_date": "YYYY-MM-DD"
--   }
-- =====================================================================================

-- 1) 报表信息（返回 definition）
CREATE OR REPLACE FUNCTION public.rpc_data_detail_report_info(
  p_report_id UUID
)
RETURNS TABLE (
  id UUID,
  title TEXT,
  description TEXT,
  definition JSONB,
  updated_at TIMESTAMPTZ
)
LANGUAGE sql
SECURITY DEFINER
AS $$
  SELECT r.id, r.title, r.description, r.definition, r.updated_at
  FROM public.analytics_reports r
  WHERE r.id = p_report_id
    AND r.owner_user_id = (SELECT id FROM public.ak_users WHERE auth_id = auth.uid() LIMIT 1);
$$;


-- 2) 明细数据行（动态执行，返回 JSONB 行数组）
CREATE OR REPLACE FUNCTION public.rpc_data_detail_rows(
  p_report_id UUID,
  p_params JSONB DEFAULT '{}'::jsonb
)
RETURNS JSONB
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
  v_owner_user_id UUID;
  v_def JSONB;
  v_dataset TEXT;
  v_dims JSONB;
  v_metrics JSONB;
  v_limit INT;
  v_start_date DATE;
  v_end_date DATE;
  v_sql TEXT;
  v_result JSONB;
BEGIN
  SELECT id INTO v_owner_user_id
  FROM public.ak_users
  WHERE auth_id = auth.uid()
  LIMIT 1;

  IF v_owner_user_id IS NULL THEN
    RAISE EXCEPTION 'No matching ak_users row for auth.uid()';
  END IF;

  SELECT definition INTO v_def
  FROM public.analytics_reports
  WHERE id = p_report_id AND owner_user_id = v_owner_user_id;

  IF v_def IS NULL THEN
    RAISE EXCEPTION 'Report not found or forbidden';
  END IF;

  v_dataset := COALESCE(v_def->>'dataset', 'sales');
  v_dims := COALESCE(v_def->'dimensions', '[]'::jsonb);
  v_metrics := COALESCE(v_def->'metrics', '[]'::jsonb);
  v_limit := COALESCE(NULLIF((v_def->>'limit')::int, 0), 200);

  v_start_date := COALESCE((p_params->>'start_date')::date, (CURRENT_DATE - INTERVAL '29 days')::date);
  v_end_date := COALESCE((p_params->>'end_date')::date, CURRENT_DATE);

  -- ==========================
  -- dataset: sales
  -- dims: date, category, merchant
  -- metrics: gmv, orders, paid_users
  -- ==========================
  IF v_dataset = 'sales' THEN
    -- 构造 SELECT 维度字段
    v_sql := 'WITH base AS ( ' ||
             '  SELECT ' ||
             '    o.id as order_id, ' ||
             '    o.user_id, ' ||
             '    o.merchant_id, ' ||
             '    o.created_at::date as date_key, ' ||
             '    COALESCE(NULLIF(o.paid_amount,0), o.total_amount) as paid_gmv ' ||
             '  FROM public.ml_orders o ' ||
             '  WHERE o.payment_status = 2 ' ||
             '    AND o.created_at::date BETWEEN $1 AND $2 ' ||
             ') ' ||
             'SELECT jsonb_agg(row_to_json(t)::jsonb) FROM ( SELECT ';

    -- dimensions
    IF v_dims ? 'date' THEN
      v_sql := v_sql || ' date_key as date, ';
    END IF;

    IF v_dims ? 'merchant' THEN
      v_sql := v_sql || ' merchant_id, ';
    END IF;

    IF v_dims ? 'category' THEN
      v_sql := v_sql ||
        ' (SELECT c.name FROM public.ml_order_items oi ' ||
        '   JOIN public.ml_products p ON p.id = oi.product_id ' ||
        '   JOIN public.ml_categories c ON c.id = p.category_id ' ||
        '   WHERE oi.order_id = base.order_id ' ||
        '   LIMIT 1) as category_name, ';
    END IF;

    -- metrics
    IF v_metrics ? 'gmv' THEN
      v_sql := v_sql || ' SUM(base.paid_gmv) as gmv, ';
    END IF;

    IF v_metrics ? 'orders' THEN
      v_sql := v_sql || ' COUNT(DISTINCT base.order_id) as orders, ';
    END IF;

    IF v_metrics ? 'paid_users' THEN
      v_sql := v_sql || ' COUNT(DISTINCT base.user_id) as paid_users, ';
    END IF;

    -- 去掉末尾多余逗号
    v_sql := regexp_replace(v_sql, ',\s*$', ' ');

    v_sql := v_sql || ' FROM base ';

    -- group by
    v_sql := v_sql || ' GROUP BY ';
    IF v_dims ? 'date' THEN v_sql := v_sql || ' date_key, '; END IF;
    IF v_dims ? 'merchant' THEN v_sql := v_sql || ' merchant_id, '; END IF;
    IF v_dims ? 'category' THEN v_sql := v_sql || ' category_name, '; END IF;
    v_sql := regexp_replace(v_sql, ',\s*$', ' ');

    v_sql := v_sql || ' ORDER BY ';
    IF v_dims ? 'date' THEN v_sql := v_sql || ' date_key DESC, '; END IF;
    v_sql := regexp_replace(v_sql, ',\s*$', ' ');

    v_sql := v_sql || ' LIMIT ' || v_limit::text || ' ) t';

    EXECUTE v_sql USING v_start_date, v_end_date INTO v_result;
    RETURN COALESCE(v_result, '[]'::jsonb);
  END IF;

  -- ==========================
  -- dataset: users
  -- dims: date, source
  -- metrics: new_users, active_users, paid_users
  -- ==========================
  IF v_dataset = 'users' THEN
    v_sql := 'WITH date_series AS ( ' ||
             '  SELECT generate_series($1, $2, interval ''1 day'')::date as date_key ' ||
             '), new_u AS ( ' ||
             '  SELECT created_at::date as date_key, registration_source as source, COUNT(id) as new_users ' ||
             '  FROM public.ak_users ' ||
             '  WHERE created_at::date BETWEEN $1 AND $2 ' ||
             '  GROUP BY created_at::date, registration_source ' ||
             '), active_u AS ( ' ||
             '  SELECT created_at::date as date_key, COUNT(DISTINCT user_id) as active_users ' ||
             '  FROM public.ml_browse_history ' ||
             '  WHERE created_at::date BETWEEN $1 AND $2 ' ||
             '  GROUP BY created_at::date ' ||
             '), paid_u AS ( ' ||
             '  SELECT created_at::date as date_key, COUNT(DISTINCT user_id) as paid_users ' ||
             '  FROM public.ml_orders ' ||
             '  WHERE payment_status = 2 AND created_at::date BETWEEN $1 AND $2 ' ||
             '  GROUP BY created_at::date ' ||
             ') ' ||
             'SELECT jsonb_agg(row_to_json(t)::jsonb) FROM ( SELECT ';

    IF v_dims ? 'date' THEN
      v_sql := v_sql || ' ds.date_key as date, ';
    END IF;

    IF v_dims ? 'source' THEN
      v_sql := v_sql || ' COALESCE(nu.source, ''未知'') as source, ';
    END IF;

    IF v_metrics ? 'new_users' THEN
      v_sql := v_sql || ' COALESCE(nu.new_users, 0) as new_users, ';
    END IF;

    IF v_metrics ? 'active_users' THEN
      v_sql := v_sql || ' COALESCE(au.active_users, 0) as active_users, ';
    END IF;

    IF v_metrics ? 'paid_users' THEN
      v_sql := v_sql || ' COALESCE(pu.paid_users, 0) as paid_users, ';
    END IF;

    v_sql := regexp_replace(v_sql, ',\s*$', ' ');

    v_sql := v_sql || ' FROM date_series ds ';
    v_sql := v_sql || ' LEFT JOIN active_u au ON au.date_key = ds.date_key ';
    v_sql := v_sql || ' LEFT JOIN paid_u pu ON pu.date_key = ds.date_key ';

    IF v_dims ? 'source' THEN
      v_sql := v_sql || ' LEFT JOIN new_u nu ON nu.date_key = ds.date_key ';
    ELSE
      -- 不按 source 维度时，把 new_u 聚合为按日
      v_sql := v_sql || ' LEFT JOIN (SELECT date_key, SUM(new_users)::bigint as new_users FROM new_u GROUP BY date_key) nu ON nu.date_key = ds.date_key ';
    END IF;

    -- group by
    IF v_dims ? 'source' THEN
      v_sql := v_sql || ' GROUP BY ds.date_key, nu.source, nu.new_users, au.active_users, pu.paid_users ';
    ELSE
      v_sql := v_sql || ' GROUP BY ds.date_key, nu.new_users, au.active_users, pu.paid_users ';
    END IF;

    v_sql := v_sql || ' ORDER BY ds.date_key DESC ';
    v_sql := v_sql || ' LIMIT ' || v_limit::text || ' ) t';

    EXECUTE v_sql USING v_start_date, v_end_date INTO v_result;
    RETURN COALESCE(v_result, '[]'::jsonb);
  END IF;

  RAISE EXCEPTION 'Unsupported dataset: %', v_dataset;
END;
$$;
