-- =====================================================================
--  TeeCup — Order of Merit: sesong-sammenlagt rangering på tvers av
--  flere individuelle turneringer (migrasjon 055, ADR-043 [OOM])
-- =====================================================================
--  Bygges i seks stadier (se plan-loggen 2026-08-04) -- denne migrasjonen
--  dekker skjemaet for ALLE stadier på én gang (billig å legge til
--  kolonner nå, dyrere å migrere skjema seks ganger), men selve
--  BACKEND-logikken bygges stadium for stadium, scratch-verifisert
--  mellom hvert.
--
--  order_of_merit: selve OOM-en. `kind` ('player'|'team') låses etter
--    opprettelse i app-laget, som GolfBox sin egen tilsvarende låsing.
--    `result_type` (poeng/stableford/brutto/netto/pengeliste) og
--    `aggregation_mode` (sum/snitt/eclectic) er de to uavhengige aksene
--    GolfBox sitt gode mønster besto av -- HVA telles vs. HVORDAN det
--    summeres. `count_best_n`/`min_results_required`/`birth_year_from/to`
--    er alle valgfrie grenser (NULL = ingen grense), lagt til fra
--    stadium 3, men kolonnene finnes fra start.
--  order_of_merit_link: hvilke individuelle turneringer (ADR-037) som
--    teller mot en gitt OOM, pluss per-lenke-konfig for resultattyper
--    som trenger det (poeng-tabell, pengepremie-tabell) -- disse to
--    JSONB-feltene er NULL med mindre `result_type` faktisk krever dem
--    (håndhevet i app-laget, ikke en CHECK, siden reglene er
--    resultattype-avhengige).
--  order_of_merit_team/_team_member: KUN for kind='team' -- et
--    sesong-lag satt opp DIREKTE i OOM-en (ikke hentet fra noen
--    turnering), som summerer/velger-beste-N-av medlemmenes ALLEREDE
--    beregnede individuelle OOM-resultater. Bevisst IKKE koblet til
--    `team`/`team_roster` (ADR-011s lagturneringer) -- disse er
--    strukturelt urelaterte konsepter (ett er en enkelt-turnering-
--    kamp-side, det andre er en sesong-lang gruppering av spillere).
--
--  Bevisst forenklet vs. GolfBox (ikke glemt, kan utvides senere uten
--  brudd): ingen gjenbrukbart "grense-mal"-system på tvers av flere OOM
--  (hver OOM har sine egne grenser direkte på raden); ingen "verst N"
--  eller kombinert beste+verst, kun "behold de N beste".
-- =====================================================================
\set ON_ERROR_STOP on

CREATE TABLE order_of_merit (
    id                    uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id       uuid NOT NULL REFERENCES organization (id) ON DELETE CASCADE,
    name                  text NOT NULL,
    kind                  text NOT NULL CHECK (kind IN ('player', 'team')),
    result_type           text NOT NULL CHECK (result_type IN ('points', 'stableford', 'gross', 'net', 'money')),
    aggregation_mode      text NOT NULL DEFAULT 'sum' CHECK (aggregation_mode IN ('sum', 'average', 'eclectic')),
    count_best_n          smallint CHECK (count_best_n IS NULL OR count_best_n >= 1),
    min_results_required  smallint CHECK (min_results_required IS NULL OR min_results_required >= 1),
    birth_year_from       smallint,
    birth_year_to         smallint,
    public_visible        boolean NOT NULL DEFAULT false,
    created_at            timestamptz NOT NULL DEFAULT now(),
    updated_at            timestamptz NOT NULL DEFAULT now(),
    UNIQUE (organization_id, id),
    -- Eclectic krever per-hull-granularitet -- poeng/pengeliste har ingen
    -- "beste hull" å hente (samme begrensning GolfBox selv håndhever).
    CHECK (aggregation_mode <> 'eclectic' OR result_type IN ('stableford', 'gross', 'net'))
);
CREATE INDEX ON order_of_merit (organization_id);

CREATE TABLE order_of_merit_link (
    id                  uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id     uuid NOT NULL,
    order_of_merit_id   uuid NOT NULL REFERENCES order_of_merit (id) ON DELETE CASCADE,
    tournament_id       uuid NOT NULL,
    -- Kun result_type='points': liste av heltall, indeks 0 = poeng for
    -- 1. plass, indeks 1 = 2. plass, osv.
    points_table         jsonb,
    -- Kun result_type='money': premiepott + utbetaling per plassering.
    money_pool_total      numeric(10, 2),
    money_payout_table    jsonb,
    created_at            timestamptz NOT NULL DEFAULT now(),
    FOREIGN KEY (organization_id, tournament_id) REFERENCES tournament (organization_id, id) ON DELETE CASCADE,
    UNIQUE (order_of_merit_id, tournament_id)
);
CREATE INDEX ON order_of_merit_link (organization_id, order_of_merit_id);

CREATE TABLE order_of_merit_team (
    id                  uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id     uuid NOT NULL,
    order_of_merit_id   uuid NOT NULL REFERENCES order_of_merit (id) ON DELETE CASCADE,
    name                text NOT NULL,
    created_at          timestamptz NOT NULL DEFAULT now(),
    UNIQUE (order_of_merit_id, name)
);
CREATE INDEX ON order_of_merit_team (organization_id, order_of_merit_id);

CREATE TABLE order_of_merit_team_member (
    id                       uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    organization_id          uuid NOT NULL,
    order_of_merit_team_id   uuid NOT NULL REFERENCES order_of_merit_team (id) ON DELETE CASCADE,
    player_id                uuid NOT NULL REFERENCES player (id) ON DELETE CASCADE,
    created_at               timestamptz NOT NULL DEFAULT now(),
    UNIQUE (order_of_merit_team_id, player_id)
);
CREATE INDEX ON order_of_merit_team_member (organization_id, order_of_merit_team_id);

-- ---------------------------------------------------------------------
-- Row-Level Security (samme org_isolation-policy-mønster som 040/053)
-- ---------------------------------------------------------------------
DO $$
DECLARE t text;
BEGIN
    FOREACH t IN ARRAY ARRAY[
        'order_of_merit', 'order_of_merit_link',
        'order_of_merit_team', 'order_of_merit_team_member'
    ]
    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 $$;
