-- ============================================================
-- Phase 8: mv_store_risk_rating 参数化函数
-- 替换普通表 mv_store_risk_rating（4月快照）为参数化函数
-- 依赖: bill_fact, v_anomaly_bills
-- ============================================================

CREATE OR REPLACE FUNCTION analytics.fn_store_risk_rating(p_month date)
RETURNS TABLE (
  store_code text,
  store_name text,
  bill_count bigint,
  active_days bigint,
  received numeric,
  avg_daily_received numeric,
  avg_bill_value numeric,
  avg_guest_value numeric,
  discount_rate_pct numeric,
  theoretical_margin_pct numeric,
  member_bill_share_pct numeric,
  anomaly_rate_pct numeric,
  risk_level text,
  primary_issue text
) AS $$
  WITH base AS (
    SELECT
      b.store_code,
      b.store_name,
      count(*) AS bill_count,
      count(DISTINCT b.closed_at::date) AS active_days,
      sum(b.received_total) AS received,
      round(sum(b.received_total) / NULLIF(count(DISTINCT b.closed_at::date), 0), 2) AS avg_daily_received,
      round(sum(b.received_total) / count(*), 2) AS avg_bill_value,
      round(sum(b.received_total) / NULLIF(sum(b.guest_count), 0), 2) AS avg_guest_value,
      round(sum(b.discount_total) / NULLIF(sum(b.consumption), 0) * 100, 2) AS discount_rate_pct,
      round(sum(b.theoretical_profit) / NULLIF(sum(b.received_total), 0) * 100, 2) AS theoretical_margin_pct,
      round(count(*) FILTER (WHERE b.member_id IS NOT NULL)::numeric / count(*) * 100, 2) AS member_bill_share_pct
    FROM analytics.bill_fact b
    WHERE b.closed_at >= analytics.fn_month_start_ts(p_month)
      AND b.closed_at < analytics.fn_next_month_start_ts(p_month)
    GROUP BY b.store_code, b.store_name
  ),
  anomaly AS (
    SELECT
      a.store_code,
      round(count(*)::numeric / NULLIF(bc.bill_count, 0) * 100, 2) AS anomaly_rate_pct
    FROM analytics.v_anomaly_bills a
    JOIN (SELECT store_code, count(*) AS bill_count FROM analytics.bill_fact
          WHERE closed_at >= analytics.fn_month_start_ts(p_month)
            AND closed_at < analytics.fn_next_month_start_ts(p_month)
          GROUP BY store_code) bc ON a.store_code = bc.store_code
    WHERE a.closed_at >= analytics.fn_month_start_ts(p_month)
      AND a.closed_at < analytics.fn_next_month_start_ts(p_month)
    GROUP BY a.store_code, bc.bill_count
  ),
  combined AS (
    SELECT
      b.*,
      COALESCE(an.anomaly_rate_pct, 0) AS anomaly_rate_pct,
      CASE
        WHEN b.received IS NULL OR b.received = 0 THEN '绿色'
        WHEN b.theoretical_margin_pct < 68 OR b.discount_rate_pct > 25 OR COALESCE(an.anomaly_rate_pct, 0) > 3 THEN '红色'
        WHEN b.theoretical_margin_pct >= 70 AND b.discount_rate_pct <= 22 AND COALESCE(an.anomaly_rate_pct, 0) <= 1.5 THEN '绿色'
        ELSE '黄色'
      END AS risk_level,
      CASE
        WHEN b.theoretical_margin_pct < 68 AND b.discount_rate_pct > 25 AND COALESCE(an.anomaly_rate_pct, 0) > 3 THEN '毛利率低；优惠率高；异常率高'
        WHEN b.theoretical_margin_pct < 68 AND b.discount_rate_pct > 25 THEN '毛利率低；优惠率高'
        WHEN b.theoretical_margin_pct < 68 AND COALESCE(an.anomaly_rate_pct, 0) > 3 THEN '毛利率低；异常率高'
        WHEN b.discount_rate_pct > 25 AND COALESCE(an.anomaly_rate_pct, 0) > 3 THEN '优惠率高；异常率高'
        WHEN b.theoretical_margin_pct < 68 THEN '毛利率低'
        WHEN b.discount_rate_pct > 25 THEN '优惠率高'
        WHEN COALESCE(an.anomaly_rate_pct, 0) > 3 THEN '异常率高'
        ELSE ''
      END AS primary_issue
    FROM base b
    LEFT JOIN anomaly an ON b.store_code = an.store_code
  )
  SELECT
    store_code, store_name, bill_count, active_days, received,
    avg_daily_received, avg_bill_value, avg_guest_value,
    discount_rate_pct, theoretical_margin_pct, member_bill_share_pct,
    anomaly_rate_pct, risk_level, primary_issue
  FROM combined
$$ LANGUAGE SQL STABLE;
