-- =====================================================================
--  TeeCup — individuelle/flerrunde-turneringer: grunnstruktur (migrasjon
--  040, ADR-037)
-- =====================================================================
--  Realiserer ADR-037 sine fire beslutninger. Rent additivt — ingen
--  eksisterende tabell/rad endres i betydning, kun `tournament` som får
--  to nye, nullable-med-trygg-default kolonner.
--
--  Beslutning A: NY, parallell org-scopet tabellstruktur — IKKE en
--    utvidelse av de frittstående rundetabellene (round/round_participant/
--    round_hole, ADR-033). Disse nye tabellene er RLS-beskyttet på
--    organization_id, som alt annet turnering-relatert.
--  Beslutning B: SAMME `tournament`-tabell, ny `format_type`-diskriminator
--    ('team' | 'individual', default 'team' — alle eksisterende rader
--    forblir 'team' uendret). `team`/`team_roster` blir ganske enkelt
--    ubrukte for format_type='individual', håndhevet i app-laget (samme
--    mønster som ADR-011s to-lags-grense), ikke en tabellomfattende CHECK.
--  Beslutning C: Flerrunde via ny `tournament_round`-tabell (samme rolle
--    som `session` har for lagturneringer), pekende til EKSISTERENDE
--    org-scopet `course` (ingen snapshot — se ADR-037s egen begrunnelse:
--    snapshot-behovet i ADR-033 kom av at frittstående runder leser en
--    ekstern, ikke-org-kontrollert kilde, det gjelder ikke her). Ny
--    `tournament_participant` (samme rolle som `team_roster`, fryser
--    handicap_index_snapshot ved uttak — ADR-007-prinsippet).
--  Beslutning D: Rå brutto slag lagres (`tournament_round_hole`,
--    individuell ball — samme grunnform som hole_score for singles/
--    fourball), OG et ferdig utregnet resultat caches per runde per
--    deltaker (`tournament_round_score` — samme mønster som
--    match.status_text/points_side_a/b). Sammenlagt resultat over flere
--    runder summeres VED LESING (samme prinsipp som
--    tournament_standings-viewet for lagturneringer), ikke en egen
--    tredje cache-tabell.
--
--  BEVISST UTENFOR DENNE MIGRASJONEN (se ADR-037 "hva denne ADR-en IKKE
--  avgjør ennå"): de fem konkrete formatenes egne poengregler
--  (Københavner/High-low-high/Robbins/Try all/Flaggturnering) og Order of
--  Merit (sesong-sammenlagt på tvers av FLERE turneringer). Dette
--  skjemaet dekker kun rene, per-spiller-uavhengige scoringsmetoder
--  (bruttoslagspill/nettoslagspill/Stableford) — formater som krever
--  paring PÅ TVERS av spillere per hull (Københavner m.fl.) trenger sin
--  egen, senere design-runde oppå denne grunnstrukturen.
-- =====================================================================
\set ON_ERROR_STOP on

-- ---------------------------------------------------------------------
-- 1. tournament: type-diskriminator + scoringsmetode (Beslutning B)
-- ---------------------------------------------------------------------
ALTER TABLE tournament ADD COLUMN format_type text NOT NULL DEFAULT 'team'
    CHECK (format_type IN ('team', 'individual'));

-- Hvilken motorfunksjon (handicap_engine.py) som regner cachet poeng fra
-- de rå slagene i tournament_round_hole. Nullable -- en individuell
-- turnering kan opprettes som 'draft' før scoringsmetoden er bestemt;
-- app-laget krever den satt før en runde kan ta imot score (samme
-- "krev X før Y virker, håndhevet i app-laget"-mønster som f.eks. hull-
-- data for egendefinerte baner andre steder i skjemaet).
ALTER TABLE tournament ADD COLUMN scoring_method text
    CHECK (scoring_method IS NULL OR scoring_method IN ('stroke_gross', 'stroke_net', 'stableford'));

-- ---------------------------------------------------------------------
-- 2. tournament_round: én runde/dag i en individuell turnering
--    (samme rolle som `session` har for lagturneringer)
-- ---------------------------------------------------------------------
CREATE TABLE tournament_round (
    id                   uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id      uuid NOT NULL,
    tournament_id        uuid NOT NULL,
    sequence             smallint NOT NULL,       -- rekkefølge i turneringen (1,2,3...)
    name                 text,                    -- f.eks. "Runde 1 — fredag"
    hole_config          hole_scope NOT NULL DEFAULT 'full_18',
    course_id            uuid NOT NULL,            -- org-ens EGEN banedata, ingen snapshot
    scheduled_at         timestamptz,
    tee_interval_minutes smallint CHECK (tee_interval_minutes IS NULL OR tee_interval_minutes > 0),
    start_hole           smallint NOT NULL DEFAULT 1 CHECK (start_hole BETWEEN 1 AND 18),
    created_at           timestamptz NOT NULL DEFAULT now(),
    updated_at           timestamptz NOT NULL DEFAULT now(),
    FOREIGN KEY (organization_id, tournament_id)
        REFERENCES tournament(organization_id, id) ON DELETE CASCADE,
    FOREIGN KEY (organization_id, course_id)
        REFERENCES course(organization_id, id) ON DELETE RESTRICT,
    UNIQUE (organization_id, id),
    UNIQUE (tournament_id, sequence)
);

-- ---------------------------------------------------------------------
-- 3. tournament_participant: spiller-pool for EN individuell turnering
--    (samme rolle som `team_roster`, men uten noe lag)
-- ---------------------------------------------------------------------
CREATE TABLE tournament_participant (
    id                      uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id         uuid NOT NULL,
    tournament_id           uuid NOT NULL,
    player_id               uuid NOT NULL,
    handicap_index_snapshot numeric(4,1),          -- fryst ved uttak, ADR-007-prinsippet
    created_at              timestamptz NOT NULL DEFAULT now(),
    FOREIGN KEY (organization_id, tournament_id)
        REFERENCES tournament(organization_id, id) ON DELETE CASCADE,
    FOREIGN KEY (organization_id, player_id)
        REFERENCES player(organization_id, id) ON DELETE RESTRICT,
    UNIQUE (organization_id, id),
    UNIQUE (tournament_id, player_id)              -- én spiller én gang i feltet
);

-- ---------------------------------------------------------------------
-- 4. tournament_round_participant: hvilken tee + hvilket beregnet
--    handicap en deltaker har for ÉN GITT runde (banen/tee kan variere
--    runde til runde selv om spilleren er den samme -- samme rolle som
--    match_participant sin tee_id/course_handicap/playing_handicap)
-- ---------------------------------------------------------------------
CREATE TABLE tournament_round_participant (
    id                         uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id            uuid NOT NULL,
    tournament_round_id        uuid NOT NULL,
    tournament_participant_id  uuid NOT NULL,
    tee_id                     uuid NOT NULL,
    -- Cachede handicap-felt (kilde: motoren, ut fra indeks-snapshot + tee-rating).
    course_handicap            smallint,
    playing_handicap           smallint,           -- kun relevant for scoring_method='stroke_net'/'stableford'
    created_at                 timestamptz NOT NULL DEFAULT now(),
    FOREIGN KEY (organization_id, tournament_round_id)
        REFERENCES tournament_round(organization_id, id) ON DELETE CASCADE,
    FOREIGN KEY (organization_id, tournament_participant_id)
        REFERENCES tournament_participant(organization_id, id) ON DELETE RESTRICT,
    FOREIGN KEY (organization_id, tee_id)
        REFERENCES tee(organization_id, id) ON DELETE RESTRICT,
    UNIQUE (organization_id, id),
    UNIQUE (tournament_round_id, tournament_participant_id)
);

-- ---------------------------------------------------------------------
-- 5. tournament_round_hole: rå brutto slag per hull (kilde-sannhet,
--    samme prinsipp som hole_score/round_hole -- netto/Stableford er
--    ALLTID avledet, aldri lagret som kilde)
-- ---------------------------------------------------------------------
CREATE TABLE tournament_round_hole (
    id                                uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id                   uuid NOT NULL,
    tournament_round_participant_id   uuid NOT NULL,
    hole_number                       smallint NOT NULL CHECK (hole_number BETWEEN 1 AND 18),
    gross_strokes                     smallint NOT NULL CHECK (gross_strokes BETWEEN 1 AND 20),
    created_at                        timestamptz NOT NULL DEFAULT now(),
    updated_at                        timestamptz NOT NULL DEFAULT now(),
    FOREIGN KEY (organization_id, tournament_round_participant_id)
        REFERENCES tournament_round_participant(organization_id, id) ON DELETE CASCADE,
    UNIQUE (tournament_round_participant_id, hole_number)
);

-- ---------------------------------------------------------------------
-- 6. tournament_round_score: FERDIG UTREGNET resultat, cachet per runde
--    per deltaker (samme mønster som match.status_text/points_side_a/b
--    -- motoren regner på nytt ved hver hull-innsending, SQL summerer
--    bare de cachede tallene ved lesing). Alle tre kolonner fylles
--    uansett scoring_method (billig å ha alle tre klare -- lar
--    leaderboardet bytte visning uten omregning).
-- ---------------------------------------------------------------------
CREATE TABLE tournament_round_score (
    id                          uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id             uuid NOT NULL,
    tournament_round_id         uuid NOT NULL,
    tournament_participant_id   uuid NOT NULL,
    holes_played                smallint NOT NULL DEFAULT 0,
    gross_total                 smallint,
    net_total                   smallint,
    stableford_points           smallint,
    updated_at                  timestamptz NOT NULL DEFAULT now(),
    FOREIGN KEY (organization_id, tournament_round_id)
        REFERENCES tournament_round(organization_id, id) ON DELETE CASCADE,
    FOREIGN KEY (organization_id, tournament_participant_id)
        REFERENCES tournament_participant(organization_id, id) ON DELETE CASCADE,
    UNIQUE (tournament_round_id, tournament_participant_id)
);

-- ---------------------------------------------------------------------
-- 7. Indekser (RLS-predikat og FK-oppslag, samme konvensjon som 001)
-- ---------------------------------------------------------------------
CREATE INDEX ON tournament_round             (organization_id, tournament_id);
CREATE INDEX ON tournament_participant       (organization_id, tournament_id);
CREATE INDEX ON tournament_round_participant (organization_id, tournament_round_id);
CREATE INDEX ON tournament_round_participant (organization_id, tournament_participant_id);
CREATE INDEX ON tournament_round_hole        (organization_id, tournament_round_participant_id);
CREATE INDEX ON tournament_round_score       (organization_id, tournament_round_id);
CREATE INDEX ON tournament_round_score       (organization_id, tournament_participant_id);

-- ---------------------------------------------------------------------
-- 8. Row-Level Security (samme org_isolation-policy-mønster som 001)
-- ---------------------------------------------------------------------
DO $$
DECLARE t text;
BEGIN
    FOREACH t IN ARRAY ARRAY[
        'tournament_round', 'tournament_participant',
        'tournament_round_participant', 'tournament_round_hole',
        'tournament_round_score'
    ]
    LOOP
        EXECUTE format('ALTER TABLE %I ENABLE ROW LEVEL SECURITY;', t);
        EXECUTE format('ALTER TABLE %I FORCE  ROW LEVEL SECURITY;', t);
        EXECUTE format($p$
            CREATE POLICY org_isolation ON %I
                USING       (organization_id = current_setting('app.current_org', true)::uuid)
                WITH CHECK  (organization_id = current_setting('app.current_org', true)::uuid);
        $p$, t);
    END LOOP;
END $$;
