-- ============================================
-- 07_custom_report_rpcs.sql
-- 自定义报表创建与管理 RPC 定义
-- ============================================
-- 目标：
--  1) 为 `pages/mall/analytics/custom-report.uvue` 提供安全的数据服务
--  2) 确保用户记录存在，解决外键约束问题
--  3) 创建自定义报表并生成初始数据（metrics + rows）
--
-- 依赖前置脚本：
--  - 01_create_tables.sql（users 表）
--  - ANALYTICS_DB_SCHEMA.sql（analytics_reports / analytics_report_metrics / analytics_report_rows）
--
-- 使用说明：
--  - 前端通过 supabase-js / UTS 调用 `rpc()` 访问本文件中的函数
--  - 所有函数仅对 `authenticated` 角色开放执行权限
-- ============================================

-- --------------------------------------------
-- 1. 确保用户记录存在（Upsert User）
-- --------------------------------------------
-- 说明：
--  - 如果 users 表中不存在当前用户记录，则插入
--  - 如果已存在，则更新最后登录时间等信息
--  - 解决 analytics_reports.owner_user_id 外键约束问题
CREATE OR REPLACE FUNCTION public.rpc_ensure_user_record(
  p_user_id uuid,
  p_email text DEFAULT NULL,
  p_phone text DEFAULT NULL,
  p_nickname text DEFAULT NULL
)
RETURNS uuid
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
  v_user_id uuid;
BEGIN
  -- 检查用户是否存在
  SELECT id INTO v_user_id
  FROM public.users
  WHERE id = p_user_id;
  
  IF v_user_id IS NULL THEN
    -- 用户不存在，插入新记录
    INSERT INTO public.users (
      id,
      email,
      phone,
      nickname,
      last_login_at,
      created_at,
      updated_at
    ) VALUES (
      p_user_id,
      p_email,
      p_phone,
      COALESCE(p_nickname, COALESCE(split_part(p_email, '@', 1), '用户')),
      NOW(),
      NOW(),
      NOW()
    )
    RETURNING id INTO v_user_id;
  ELSE
    -- 用户已存在，更新信息
    UPDATE public.users
    SET 
      email = COALESCE(p_email, email),
      phone = COALESCE(p_phone, phone),
      nickname = COALESCE(p_nickname, nickname),
      last_login_at = NOW(),
      updated_at = NOW()
    WHERE id = p_user_id;
    
    v_user_id := p_user_id;
  END IF;
  
  RETURN v_user_id;
END;
$$;

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

-- --------------------------------------------
-- 2. 创建自定义报表（含初始数据生成）
-- --------------------------------------------
-- 说明：
--  - 创建 analytics_reports 记录
--  - 根据 period 和选中的指标，生成 analytics_report_metrics
--  - 根据 period 聚合 orders 数据，生成 analytics_report_rows
CREATE OR REPLACE FUNCTION public.rpc_create_custom_report(
  p_title text,
  p_description text DEFAULT '',
  p_period text DEFAULT '30d', -- 7d/30d/90d/1y
  p_metrics text[] DEFAULT ARRAY['gmv', 'orders', 'users'], -- 选中的指标列表
  p_chart_type text DEFAULT 'line' -- 图表类型（暂不存储，仅用于后续扩展）
)
RETURNS uuid
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
  v_user_id uuid;
  v_report_id uuid;
  v_start_date date;
  v_end_date date;
  v_metric_key text;
  v_metric_label text;
  v_metric_value numeric;
  v_total_gmv numeric := 0;
  v_total_orders integer := 0;
  v_total_users integer := 0;
  v_avg_order_amount numeric := 0;
BEGIN
  -- 1. 获取当前用户 ID
  v_user_id := auth.uid();
  IF v_user_id IS NULL THEN
    RAISE EXCEPTION '用户未登录';
  END IF;
  
  -- 2. 确保用户记录存在
  PERFORM public.rpc_ensure_user_record(
    v_user_id,
    NULL, -- email 从 auth.users 获取，这里不传
    NULL, -- phone 从 auth.users 获取，这里不传
    NULL  -- nickname 从 auth.users 获取，这里不传
  );
  
  -- 3. 计算时间范围
  v_end_date := CURRENT_DATE;
  CASE p_period
    WHEN '7d' THEN v_start_date := v_end_date - INTERVAL '7 days';
    WHEN '30d' THEN v_start_date := v_end_date - INTERVAL '30 days';
    WHEN '90d' THEN v_start_date := v_end_date - INTERVAL '90 days';
    WHEN '1y' THEN v_start_date := v_end_date - INTERVAL '1 year';
    ELSE v_start_date := v_end_date - INTERVAL '30 days'; -- 默认 30 天
  END CASE;
  
  -- 4. 创建报表记录
  INSERT INTO public.analytics_reports (
    owner_user_id,
    title,
    description,
    type,
    period,
    date_start,
    date_end,
    status,
    generated_at,
    created_at,
    updated_at
  ) VALUES (
    v_user_id,
    p_title,
    p_description,
    'custom',
    p_period,
    v_start_date,
    v_end_date,
    'ready',
    NOW(),
    NOW(),
    NOW()
  )
  RETURNING id INTO v_report_id;
  
  -- 5. 聚合订单数据，计算总指标
  SELECT 
    COALESCE(SUM(o.total_amount), 0),
    COUNT(DISTINCT o.id),
    COUNT(DISTINCT o.user_id),
    CASE 
      WHEN COUNT(DISTINCT o.id) > 0 
      THEN COALESCE(SUM(o.total_amount), 0) / COUNT(DISTINCT o.id)
      ELSE 0
    END
  INTO v_total_gmv, v_total_orders, v_total_users, v_avg_order_amount
  FROM public.orders o
  WHERE o.created_at >= v_start_date
    AND o.created_at <= v_end_date
    AND o.status = 2; -- 已完成订单
  
  -- 6. 生成核心指标（analytics_report_metrics）
  -- GMV
  IF 'gmv' = ANY(p_metrics) THEN
    INSERT INTO public.analytics_report_metrics (
      report_id,
      metric_key,
      metric_label,
      metric_value_num,
      format,
      icon,
      color
    ) VALUES (
      v_report_id,
      'gmv_total',
      '总GMV',
      v_total_gmv,
      'currency',
      '💰',
      '#4caf50'
    );
  END IF;
  
  -- 订单数
  IF 'orders' = ANY(p_metrics) THEN
    INSERT INTO public.analytics_report_metrics (
      report_id,
      metric_key,
      metric_label,
      metric_value_num,
      format,
      icon,
      color
    ) VALUES (
      v_report_id,
      'orders_total',
      '总订单数',
      v_total_orders,
      'number',
      '📦',
      '#2196f3'
    );
  END IF;
  
  -- 用户数
  IF 'users' = ANY(p_metrics) THEN
    INSERT INTO public.analytics_report_metrics (
      report_id,
      metric_key,
      metric_label,
      metric_value_num,
      format,
      icon,
      color
    ) VALUES (
      v_report_id,
      'users_total',
      '下单用户数',
      v_total_users,
      'number',
      '👥',
      '#ff9800'
    );
  END IF;
  
  -- 客单价
  IF 'avg_order' = ANY(p_metrics) THEN
    INSERT INTO public.analytics_report_metrics (
      report_id,
      metric_key,
      metric_label,
      metric_value_num,
      format,
      icon,
      color
    ) VALUES (
      v_report_id,
      'avg_order_amount',
      '客单价',
      v_avg_order_amount,
      'currency',
      '💵',
      '#9c27b0'
    );
  END IF;
  
  -- 7. 生成明细行（analytics_report_rows）- 按天聚合
  INSERT INTO public.analytics_report_rows (
    report_id,
    row_date,
    gmv,
    orders,
    users,
    avg_order_amount
  )
  SELECT 
    v_report_id,
    o.created_at::date AS row_date,
    COALESCE(SUM(o.total_amount), 0) AS gmv,
    COUNT(DISTINCT o.id) AS orders,
    COUNT(DISTINCT o.user_id) AS users,
    CASE 
      WHEN COUNT(DISTINCT o.id) > 0 
      THEN COALESCE(SUM(o.total_amount), 0) / COUNT(DISTINCT o.id)
      ELSE 0
    END AS avg_order_amount
  FROM public.orders o
  WHERE o.created_at >= v_start_date
    AND o.created_at <= v_end_date
    AND o.status = 2
  GROUP BY o.created_at::date
  ORDER BY o.created_at::date;
  
  RETURN v_report_id;
END;
$$;

REVOKE ALL ON FUNCTION public.rpc_create_custom_report(text,text,text,text[],text) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_create_custom_report(text,text,text,text[],text) TO authenticated;

-- --------------------------------------------
-- 3. 更新自定义报表（仅更新基本信息）
-- --------------------------------------------
-- 说明：
--  - 更新报表的标题、描述、周期
--  - 不重新生成数据（如需重新生成，删除后重建）
CREATE OR REPLACE FUNCTION public.rpc_update_custom_report(
  p_report_id uuid,
  p_title text,
  p_description text DEFAULT NULL,
  p_period text DEFAULT NULL
)
RETURNS boolean
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
  v_user_id uuid;
BEGIN
  -- 1. 获取当前用户 ID
  v_user_id := auth.uid();
  IF v_user_id IS NULL THEN
    RAISE EXCEPTION '用户未登录';
  END IF;
  
  -- 2. 更新报表（仅限所有者）
  UPDATE public.analytics_reports
  SET 
    title = p_title,
    description = COALESCE(p_description, description),
    period = COALESCE(p_period, period),
    updated_at = NOW()
  WHERE id = p_report_id
    AND owner_user_id = v_user_id;
  
  -- FOUND 是 PostgreSQL 的特殊变量，UPDATE 后自动设置
  IF NOT FOUND THEN
    RAISE EXCEPTION '报表不存在或无权限修改';
  END IF;
  
  RETURN true;
END;
$$;

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

-- --------------------------------------------
-- 4. 删除自定义报表（级联删除相关数据）
-- --------------------------------------------
-- 说明：
--  - 删除报表记录（CASCADE 会自动删除 metrics 和 rows）
--  - 仅允许所有者删除
CREATE OR REPLACE FUNCTION public.rpc_delete_custom_report(
  p_report_id uuid
)
RETURNS boolean
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
  v_user_id uuid;
BEGIN
  -- 1. 获取当前用户 ID
  v_user_id := auth.uid();
  IF v_user_id IS NULL THEN
    RAISE EXCEPTION '用户未登录';
  END IF;
  
  -- 2. 删除报表（仅限所有者，CASCADE 会自动删除 metrics 和 rows）
  DELETE FROM public.analytics_reports
  WHERE id = p_report_id
    AND owner_user_id = v_user_id
    AND type = 'custom';
  
  -- FOUND 是 PostgreSQL 的特殊变量，DELETE 后自动设置
  IF NOT FOUND THEN
    RAISE EXCEPTION '报表不存在或无权限删除';
  END IF;
  
  RETURN true;
END;
$$;

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

-- ============================================
-- 完成提示
-- ============================================
DO $$
BEGIN
  RAISE NOTICE 'Custom report RPCs created successfully.';
  RAISE NOTICE 'Functions:';
  RAISE NOTICE '  - rpc_ensure_user_record(uuid, text, text, text)';
  RAISE NOTICE '  - rpc_create_custom_report(text, text, text, text[], text)';
  RAISE NOTICE '  - rpc_update_custom_report(uuid, text, text, text)';
  RAISE NOTICE '  - rpc_delete_custom_report(uuid)';
END $$;
