-- Portal roles, league masters, team extras, support issues

CREATE TYPE portal_role AS ENUM ('league_master', 'manager');

ALTER TABLE profiles
  ADD COLUMN IF NOT EXISTS portal_role portal_role NOT NULL DEFAULT 'manager';

ALTER TABLE teams
  ADD COLUMN IF NOT EXISTS nickname TEXT,
  ADD COLUMN IF NOT EXISTS icon TEXT NOT NULL DEFAULT 'shield';

CREATE TABLE IF NOT EXISTS league_masters (
  league_id UUID NOT NULL REFERENCES leagues(id) ON DELETE CASCADE,
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  assigned_by UUID REFERENCES auth.users(id) ON DELETE SET NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  PRIMARY KEY (league_id, user_id)
);

CREATE TABLE IF NOT EXISTS support_issues (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  league_id UUID NOT NULL REFERENCES leagues(id) ON DELETE CASCADE,
  competition_id UUID REFERENCES competitions(id) ON DELETE SET NULL,
  submitted_by UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  subject TEXT NOT NULL,
  body TEXT NOT NULL,
  status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'in_progress', 'resolved')),
  master_reply TEXT,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TRIGGER support_issues_updated_at
  BEFORE UPDATE ON support_issues
  FOR EACH ROW EXECUTE FUNCTION update_updated_at();

-- Helpers
CREATE OR REPLACE FUNCTION is_global_league_master()
RETURNS BOOLEAN AS $$
  SELECT EXISTS (
    SELECT 1 FROM profiles WHERE id = auth.uid() AND portal_role = 'league_master'
  );
$$ LANGUAGE sql SECURITY DEFINER STABLE;

CREATE OR REPLACE FUNCTION is_league_master(p_league_id UUID)
RETURNS BOOLEAN AS $$
  SELECT is_global_league_master()
  OR EXISTS (SELECT 1 FROM leagues WHERE id = p_league_id AND created_by = auth.uid())
  OR EXISTS (
    SELECT 1 FROM league_masters WHERE league_id = p_league_id AND user_id = auth.uid()
  );
$$ LANGUAGE sql SECURITY DEFINER STABLE;

-- Extend organizer check to include assigned masters
CREATE OR REPLACE FUNCTION is_league_organizer(p_league_id UUID)
RETURNS BOOLEAN AS $$
  SELECT is_league_master(p_league_id);
$$ LANGUAGE sql SECURITY DEFINER STABLE;

-- Profile trigger: portal role from signup metadata
CREATE OR REPLACE FUNCTION handle_new_user()
RETURNS TRIGGER AS $$
DECLARE
  v_role portal_role;
BEGIN
  BEGIN
    v_role := COALESCE(
      (NEW.raw_user_meta_data->>'portal_role')::portal_role,
      'manager'::portal_role
    );
  EXCEPTION WHEN OTHERS THEN
    v_role := 'manager';
  END;

  INSERT INTO public.profiles (id, display_name, portal_role)
  VALUES (
    NEW.id,
    COALESCE(NEW.raw_user_meta_data->>'display_name', split_part(NEW.email, '@', 1)),
    v_role
  )
  ON CONFLICT (id) DO UPDATE SET
    display_name = COALESCE(EXCLUDED.display_name, profiles.display_name),
    portal_role = COALESCE(EXCLUDED.portal_role, profiles.portal_role);

  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- RLS new tables
ALTER TABLE league_masters ENABLE ROW LEVEL SECURITY;
ALTER TABLE support_issues ENABLE ROW LEVEL SECURITY;

CREATE POLICY league_masters_select ON league_masters FOR SELECT TO authenticated
  USING (is_league_master(league_id) OR user_id = auth.uid());

CREATE POLICY league_masters_insert ON league_masters FOR INSERT TO authenticated
  WITH CHECK (is_league_master(league_id));

CREATE POLICY league_masters_delete ON league_masters FOR DELETE TO authenticated
  USING (is_league_master(league_id));

CREATE POLICY support_issues_select ON support_issues FOR SELECT TO authenticated
  USING (
    submitted_by = auth.uid()
    OR is_league_master(league_id)
  );

CREATE POLICY support_issues_insert ON support_issues FOR INSERT TO authenticated
  WITH CHECK (submitted_by = auth.uid());

CREATE POLICY support_issues_update ON support_issues FOR UPDATE TO authenticated
  USING (is_league_master(league_id));

-- League delete (masters only)
CREATE POLICY leagues_delete ON leagues FOR DELETE TO authenticated
  USING (is_league_master(id));

-- Team delete in draft competitions
CREATE POLICY teams_delete ON teams FOR DELETE TO authenticated
  USING (
    EXISTS (
      SELECT 1 FROM competitions c
      WHERE c.id = competition_id
        AND c.status = 'draft'
        AND is_league_master(c.league_id)
    )
  );

-- Recreate standings view with nickname/icon (must DROP first: REPLACE cannot reorder columns)
DROP VIEW IF EXISTS competition_standings;
CREATE VIEW competition_standings AS
SELECT
  t.competition_id,
  t.id AS team_id,
  t.name AS team_name,
  t.nickname AS team_nickname,
  t.icon AS team_icon,
  t.logo_path,
  COUNT(m.id) FILTER (WHERE m.status = 'completed') AS played,
  COUNT(m.id) FILTER (
    WHERE m.status = 'completed'
    AND (
      (m.home_team_id = t.id AND m.home_score > m.away_score)
      OR (m.away_team_id = t.id AND m.away_score > m.home_score)
    )
  ) AS won,
  COUNT(m.id) FILTER (
    WHERE m.status = 'completed' AND m.home_score = m.away_score
  ) AS drawn,
  COUNT(m.id) FILTER (
    WHERE m.status = 'completed'
    AND (
      (m.home_team_id = t.id AND m.home_score < m.away_score)
      OR (m.away_team_id = t.id AND m.away_score < m.home_score)
    )
  ) AS lost,
  COALESCE(SUM(
    CASE
      WHEN m.status = 'completed' AND m.home_team_id = t.id THEN m.home_score
      WHEN m.status = 'completed' AND m.away_team_id = t.id THEN m.away_score
      ELSE 0
    END
  ), 0)::INT AS goals_for,
  COALESCE(SUM(
    CASE
      WHEN m.status = 'completed' AND m.home_team_id = t.id THEN m.away_score
      WHEN m.status = 'completed' AND m.away_team_id = t.id THEN m.home_score
      ELSE 0
    END
  ), 0)::INT AS goals_against,
  COALESCE(SUM(
    CASE
      WHEN m.status = 'completed' AND m.home_team_id = t.id THEN m.home_score - m.away_score
      WHEN m.status = 'completed' AND m.away_team_id = t.id THEN m.away_score - m.home_score
      ELSE 0
    END
  ), 0)::INT AS goal_difference,
  COALESCE(SUM(
    CASE
      WHEN m.status <> 'completed' THEN 0
      WHEN m.home_score = m.away_score THEN 1
      WHEN m.home_team_id = t.id AND m.home_score > m.away_score THEN 3
      WHEN m.away_team_id = t.id AND m.away_score > m.home_score THEN 3
      ELSE 0
    END
  ), 0)::INT AS points
FROM teams t
LEFT JOIN matches m ON m.competition_id = t.competition_id
  AND (m.home_team_id = t.id OR m.away_team_id = t.id)
GROUP BY t.competition_id, t.id, t.name, t.nickname, t.icon, t.logo_path;

CREATE OR REPLACE FUNCTION get_user_id_by_email(p_email TEXT)
RETURNS UUID AS $$
  SELECT id FROM auth.users WHERE email = lower(trim(p_email)) LIMIT 1;
$$ LANGUAGE sql SECURITY DEFINER STABLE;
