CREATE TABLE score_categories (
    score_category_id smallint NOT NULL,
    league_id int NOT NULL,
    name text NOT NULL,
    value int NOT NULL,

    UNIQUE (league_id, name),
    CONSTRAINT score_categories_pk PRIMARY KEY (score_category_id)
);
SELECT league_id AS nfl_league_id FROM leagues where name = 'NFL' LIMIT 1 \gset

INSERT INTO score_categories (score_category_id, league_id, name, value) VALUES (1, :nfl_league_id, 'Win', 1);
INSERT INTO score_categories (score_category_id, league_id, name, value) VALUES (2, :nfl_league_id, 'Playoffs', 5);
INSERT INTO score_categories (score_category_id, league_id, name, value) VALUES (3, :nfl_league_id, 'Divisional', 5);
INSERT INTO score_categories (score_category_id, league_id, name, value) VALUES (4, :nfl_league_id, 'Conference', 10);
INSERT INTO score_categories (score_category_id, league_id, name, value) VALUES (5, :nfl_league_id, 'Superbowl', 10);
INSERT INTO score_categories (score_category_id, league_id, name, value) VALUES (6, :nfl_league_id, 'Champion', 5);

CREATE TABLE scores (
    score_id bigint NOT NULL GENERATED ALWAYS AS IDENTITY,
    season_id bigint NOT NULL,
    team_id integer NOT NULL,
    game int NOT NULL,
    score_category_id smallint NOT NULL DEFAULT 1,
    scored_at timestamptz NOT NULL DEFAULT now(),
    created_at timestamptz NOT NULL DEFAULT now(),
    modified_at timestamptz NOT NULL DEFAULT now(),

    UNIQUE (season_id, team_id, game, score_category_id),
    CONSTRAINT scores_pk PRIMARY KEY (score_id),
    CONSTRAINT scores_seasons_fk FOREIGN KEY (season_id) REFERENCES seasons(season_id) MATCH SIMPLE ON DELETE NO ACTION ON UPDATE NO ACTION,
    CONSTRAINT scores_teams_fk FOREIGN KEY (team_id) REFERENCES teams(team_id) MATCH SIMPLE ON DELETE NO ACTION ON UPDATE NO ACTION,
    CONSTRAINT scores_score_categories_fk FOREIGN KEY (score_category_id) REFERENCES score_categories(score_category_id) MATCH SIMPLE ON DELETE NO ACTION ON UPDATE NO ACTION
);

CREATE OR REPLACE FUNCTION record_score(team_id int, game int, season_id int, score_category_id int, scored_at timestamptz)
    RETURNS int
    LANGUAGE plpgsql
    SECURITY INVOKER
    AS $$
DECLARE
    new_score_id integer;
BEGIN
    INSERT INTO scores(season_id, team_id, game, score_category_id, scored_at)
        VALUES (season_id, team_id, game, score_category_id, scored_at)
    ON CONFLICT ON CONSTRAINT scores_season_id_team_id_game_score_category_id_key
        DO UPDATE SET modified_at = NOW(), scored_at = EXCLUDED.scored_at
    RETURNING
        score_id INTO new_score_id;
    RETURN new_score_id;
END;
$$;

CREATE OR REPLACE VIEW season_scores AS
WITH score_totals AS (
    SELECT
        scores.season_id,
        scores.team_id,
        sc.name,
        sum(value) AS total
    FROM
        scores
        JOIN score_categories sc USING(score_category_id)
    GROUP BY
        scores.season_id,
        scores.team_id,
        sc.name
)
SELECT
    st.season_id,
    teams.name,
    array_agg(st.name || ': ' || st.total ORDER BY st.total DESC) AS scores
FROM
    teams
    LEFT JOIN score_totals st USING(team_id)
GROUP BY
    st.season_id, teams.name;

-- CREATE OR REPLACE VIEW draft_scores AS
-- WITH season_scores AS (
--     SELECT
--         season_id,
--         team_id,
--         coalesce(SUM(value), 0)::smallint AS total
--     FROM
--         scores
--     JOIN score_categories ON category_id = score_categories.score_category_id
--     GROUP BY
--         season_id,
--         team_id
-- )
-- SELECT
--     season_id,
--     draft_id,
--     team,
--     player,
--     coalesce(win, 0) AS win,
--     playoffs,
--     divisional,
--     conference,
--     superbowl,
--     champion,
--     coalesce(total, 0) AS total
-- FROM
--     draft_picks
--     LEFT OUTER JOIN season_scores USING (team_id);
