-- Migration 0041: Fix command-center RPCs against actual prod schema
--
-- Migration 0040 was written against an assumed schema and references columns
-- that don't exist in the prod `orders` table:
--   - `orders.created_at` does not exist  → use `orders.placed_at`
--   - `orders.subtotal` does not exist     → use `orders.total_cents / 100`
--   - `stops.date` is already DATE, not TEXT → drop the `~ '^\d{4}-...' ` regex
--
-- All three functions are fixed in place via CREATE OR REPLACE FUNCTION.
-- The action layer (src/actions/platform/command-center.ts) is updated
-- separately to use `SELECT * FROM fn()` for the two setof-returning functions.
--
-- Reference (prod schema as of 2026-06-17):
--   orders:        id, brand_id, customer_id, stop_id, total_cents INT,
--                  status TEXT, fulfillment TEXT, customer_*,
--                  idempotency_key, notes, placed_at TIMESTAMPTZ, updated_at
--   stops:         id, brand_id, name, location, address, city, state, zip,
--                  date DATE, time, cutoff_date, status, is_public, notes,
--                  created_at, updated_at
--   operational_events: id, brand_id, event_type, entity_type, entity_id,
--                  actor_type, actor_id, source, payload JSONB, created_at
--   brands:        (assumed present per CLAUDE.md)

-- ── Platform-wide metrics ──────────────────────────────────────────────────
CREATE OR REPLACE FUNCTION get_platform_command_center_metrics()
RETURNS JSONB
LANGUAGE plpgsql SECURITY DEFINER
AS $$
DECLARE
  result JSONB;
BEGIN
  result := jsonb_build_object(
    'active_brands', (
      SELECT COUNT(*) FROM brands WHERE slug IN ('tuxedo', 'indian-river-direct')
    ),
    'orders_today', (
      SELECT COUNT(*) FROM orders
      WHERE DATE(placed_at) = CURRENT_DATE
    ),
    'revenue_today', (
      SELECT COALESCE(SUM(total_cents), 0)::NUMERIC / 100
      FROM orders
      WHERE DATE(placed_at) = CURRENT_DATE
      AND status NOT IN ('cancelled', 'refunded')
    ),
    'active_routes', (
      SELECT COUNT(DISTINCT s.id)
      FROM stops s
      WHERE s.date >= CURRENT_DATE
      AND s.status = 'active'
    ),
    'failed_orders_today', (
      SELECT COUNT(*)
      FROM orders
      WHERE DATE(placed_at) = CURRENT_DATE
      AND status IN ('payment_failed', 'failed')
    ),
    'pending_orders_today', (
      SELECT COUNT(*)
      FROM orders
      WHERE DATE(placed_at) = CURRENT_DATE
      AND status = 'pending'
    )
  );

  RETURN result;
END;
$$;

-- ── Per-brand health snapshot ──────────────────────────────────────────────
CREATE OR REPLACE FUNCTION get_brand_health_snapshot()
RETURNS TABLE (
  brand_id UUID,
  brand_name TEXT,
  brand_slug TEXT,
  plan_tier TEXT,
  orders_today INT,
  revenue_today NUMERIC,
  active_stops INT,
  failed_orders INT,
  pending_orders INT,
  last_activity TIMESTAMPTZ,
  open_pain_items INT,
  health_status TEXT
)
LANGUAGE plpgsql SECURITY DEFINER
AS $$
BEGIN
  RETURN QUERY
  WITH bm AS (
    SELECT
      b.id AS bid,
      b.name AS bname,
      b.slug AS bslug,
      COUNT(DISTINCT o.id) FILTER (WHERE DATE(o.placed_at) = CURRENT_DATE) AS ords_today,
      (COALESCE(SUM(o.total_cents) FILTER (
        WHERE DATE(o.placed_at) = CURRENT_DATE
        AND o.status NOT IN ('cancelled', 'refunded')
      ), 0)::NUMERIC / 100) AS rev_today,
      COUNT(DISTINCT s.id) FILTER (
        WHERE s.date >= CURRENT_DATE AND s.status = 'active'
      ) AS act_stops,
      COUNT(DISTINCT o.id) FILTER (WHERE DATE(o.placed_at) = CURRENT_DATE AND o.status IN ('payment_failed', 'failed')) AS fail_ords,
      COUNT(DISTINCT o.id) FILTER (WHERE DATE(o.placed_at) = CURRENT_DATE AND o.status = 'pending') AS pend_ords,
      MAX(oe.created_at) AS last_act
    FROM brands b
    LEFT JOIN orders o ON o.brand_id = b.id
    LEFT JOIN stops s ON s.brand_id = b.id
    LEFT JOIN operational_events oe
      ON oe.payload->>'brand_id' = b.id::TEXT
      AND oe.payload->>'brand_id' ~ '^[0-9a-fA-F-]{36}$'
    WHERE b.slug IN ('tuxedo', 'indian-river-direct')
    GROUP BY b.id, b.name, b.slug
  ),
  pc AS (
    SELECT f.brand_id AS pc_bid, COUNT(*) AS open_cnt
    FROM founder_pain_log f
    WHERE f.status = 'open'
    GROUP BY f.brand_id
  )
  SELECT
    bm.bid,
    bm.bname,
    bm.bslug,
    NULL::TEXT,
    COALESCE(bm.ords_today, 0)::INT,
    COALESCE(bm.rev_today, 0)::NUMERIC,
    COALESCE(bm.act_stops, 0)::INT,
    COALESCE(bm.fail_ords, 0)::INT,
    COALESCE(bm.pend_ords, 0)::INT,
    bm.last_act,
    COALESCE(pc.open_cnt, 0)::INT,
    CASE
      WHEN COALESCE(bm.fail_ords, 0) > 0 THEN 'critical'
      WHEN COALESCE(bm.pend_ords, 0) > 5 THEN 'warning'
      WHEN COALESCE(pc.open_cnt, 0) > 0 THEN 'warning'
      WHEN bm.last_act IS NULL OR bm.last_act < (NOW() - INTERVAL '24 hours') THEN 'warning'
      ELSE 'healthy'
    END
  FROM bm
  LEFT JOIN pc ON pc.pc_bid = bm.bid;
END;
$$;

-- get_platform_activity_feed from 0040 is already correct against the prod
-- schema (operational_events.payload->>'brand_id' is a text→UUID cast that
-- nulls out on missing keys). No body change required.
