-- W2-1 게임잼 엔티티/라이프사이클. 멱등. db/apply-local-ddl.sh 로 실행 DB 비파괴 적용.
-- games 변경 없음(연결은 jam_entries 가 보유). 추가만, 파괴 없음.

-- ===========================================================================
-- 1) jams (게임잼 회차. 회차 독립 = 다중 인스턴스)
-- ===========================================================================
CREATE SEQUENCE IF NOT EXISTS "jams_id_seq";
CREATE TABLE IF NOT EXISTS "jams" (
    "id"             bigint DEFAULT nextval('jams_id_seq'::regclass) NOT NULL,
    "slug"           character varying(80)  NOT NULL,
    "title"          character varying(200) NOT NULL,
    "description"    text,
    "status"         character varying(20)  DEFAULT 'RECRUIT' NOT NULL,
    "recruit_start_at" timestamp with time zone,
    "dev_start_at"     timestamp with time zone,
    "eval_start_at"    timestamp with time zone,
    "eval_end_at"      timestamp with time zone,
    "discord_url"      character varying(500),
    "prize_info"       text,
    "sponsor_info"     text,
    "is_visible"     boolean DEFAULT true  NOT NULL,
    "created_by"     bigint,
    "created_at"     timestamp with time zone DEFAULT now() NOT NULL,
    "updated_at"     timestamp with time zone DEFAULT now() NOT NULL,
    "is_delete"      boolean DEFAULT false NOT NULL,
    PRIMARY KEY ("id")
);
ALTER SEQUENCE "jams_id_seq" OWNED BY "jams"."id";

DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jams_status_check') THEN
        ALTER TABLE "jams"
            ADD CONSTRAINT "jams_status_check"
            CHECK ("status" IN ('RECRUIT', 'DEV', 'EVAL', 'CLOSED'));
    END IF;
END
$$;

CREATE UNIQUE INDEX IF NOT EXISTS "ux_jams_slug_active"
    ON "jams" ("slug") WHERE "is_delete" IS NOT TRUE;
CREATE INDEX IF NOT EXISTS "idx_jams_visible_keyset"
    ON "jams" ("is_visible", "is_delete", "created_at" DESC, "id" DESC);

-- ===========================================================================
-- 2) jam_teams
-- ===========================================================================
CREATE SEQUENCE IF NOT EXISTS "jam_teams_id_seq";
CREATE TABLE IF NOT EXISTS "jam_teams" (
    "id"          bigint DEFAULT nextval('jam_teams_id_seq'::regclass) NOT NULL,
    "jam_id"      bigint NOT NULL,
    "name"        character varying(120) NOT NULL,
    "owner_user_id" bigint NOT NULL,
    "created_at"  timestamp with time zone DEFAULT now() NOT NULL,
    "is_delete"   boolean DEFAULT false NOT NULL,
    PRIMARY KEY ("id")
);
ALTER SEQUENCE "jam_teams_id_seq" OWNED BY "jam_teams"."id";
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_teams_jam_id_fkey') THEN
        ALTER TABLE "jam_teams" ADD CONSTRAINT "jam_teams_jam_id_fkey"
            FOREIGN KEY ("jam_id") REFERENCES "jams" ("id");
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_teams_owner_fkey') THEN
        ALTER TABLE "jam_teams" ADD CONSTRAINT "jam_teams_owner_fkey"
            FOREIGN KEY ("owner_user_id") REFERENCES "users" ("id");
    END IF;
END
$$;
CREATE INDEX IF NOT EXISTS "idx_jam_teams_jam" ON "jam_teams" ("jam_id");

-- ===========================================================================
-- 3) jam_team_members
-- ===========================================================================
CREATE SEQUENCE IF NOT EXISTS "jam_team_members_id_seq";
CREATE TABLE IF NOT EXISTS "jam_team_members" (
    "id"           bigint DEFAULT nextval('jam_team_members_id_seq'::regclass) NOT NULL,
    "jam_team_id"  bigint NOT NULL,
    "user_id"      bigint NOT NULL,
    "created_at"   timestamp with time zone DEFAULT now() NOT NULL,
    PRIMARY KEY ("id")
);
ALTER SEQUENCE "jam_team_members_id_seq" OWNED BY "jam_team_members"."id";
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_team_members_team_fkey') THEN
        ALTER TABLE "jam_team_members" ADD CONSTRAINT "jam_team_members_team_fkey"
            FOREIGN KEY ("jam_team_id") REFERENCES "jam_teams" ("id");
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_team_members_user_fkey') THEN
        ALTER TABLE "jam_team_members" ADD CONSTRAINT "jam_team_members_user_fkey"
            FOREIGN KEY ("user_id") REFERENCES "users" ("id");
    END IF;
END
$$;
CREATE UNIQUE INDEX IF NOT EXISTS "ux_jam_team_members_team_user"
    ON "jam_team_members" ("jam_team_id", "user_id");

-- ===========================================================================
-- 4) jam_entries (출품작 = 잼-게임 연결 조인. 평가 단위 = (jam_id, game_id) 활성 자연키)
-- ===========================================================================
CREATE SEQUENCE IF NOT EXISTS "jam_entries_id_seq";
CREATE TABLE IF NOT EXISTS "jam_entries" (
    "id"             bigint DEFAULT nextval('jam_entries_id_seq'::regclass) NOT NULL,
    "jam_id"         bigint NOT NULL,
    "game_id"        bigint NOT NULL,
    "entrant_type"   character varying(10) NOT NULL,
    "entrant_user_id" bigint,
    "jam_team_id"    bigint,
    "submitted_at"   timestamp with time zone DEFAULT now() NOT NULL,
    "is_delete"      boolean DEFAULT false NOT NULL,
    PRIMARY KEY ("id")
);
ALTER SEQUENCE "jam_entries_id_seq" OWNED BY "jam_entries"."id";
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_entries_jam_fkey') THEN
        ALTER TABLE "jam_entries" ADD CONSTRAINT "jam_entries_jam_fkey"
            FOREIGN KEY ("jam_id") REFERENCES "jams" ("id");
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_entries_game_fkey') THEN
        ALTER TABLE "jam_entries" ADD CONSTRAINT "jam_entries_game_fkey"
            FOREIGN KEY ("game_id") REFERENCES "games" ("id");
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_entries_team_fkey') THEN
        ALTER TABLE "jam_entries" ADD CONSTRAINT "jam_entries_team_fkey"
            FOREIGN KEY ("jam_team_id") REFERENCES "jam_teams" ("id");
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_entries_user_fkey') THEN
        ALTER TABLE "jam_entries" ADD CONSTRAINT "jam_entries_user_fkey"
            FOREIGN KEY ("entrant_user_id") REFERENCES "users" ("id");
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_entries_entrant_type_check') THEN
        ALTER TABLE "jam_entries" ADD CONSTRAINT "jam_entries_entrant_type_check"
            CHECK ("entrant_type" IN ('USER', 'TEAM'));
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_entries_entrant_xor_check') THEN
        ALTER TABLE "jam_entries" ADD CONSTRAINT "jam_entries_entrant_xor_check"
            CHECK (
                ("entrant_type" = 'USER' AND "entrant_user_id" IS NOT NULL AND "jam_team_id" IS NULL)
                OR
                ("entrant_type" = 'TEAM' AND "jam_team_id" IS NOT NULL AND "entrant_user_id" IS NULL)
            );
    END IF;
END
$$;
CREATE UNIQUE INDEX IF NOT EXISTS "ux_jam_entries_jam_game_active"
    ON "jam_entries" ("jam_id", "game_id") WHERE "is_delete" IS NOT TRUE;
CREATE INDEX IF NOT EXISTS "idx_jam_entries_jam" ON "jam_entries" ("jam_id");
CREATE INDEX IF NOT EXISTS "idx_jam_entries_game" ON "jam_entries" ("game_id");

-- ===========================================================================
-- 5) jam_status_log
-- ===========================================================================
CREATE SEQUENCE IF NOT EXISTS "jam_status_log_id_seq";
CREATE TABLE IF NOT EXISTS "jam_status_log" (
    "id"          bigint DEFAULT nextval('jam_status_log_id_seq'::regclass) NOT NULL,
    "jam_id"      bigint NOT NULL,
    "from_status" character varying(20),
    "to_status"   character varying(20) NOT NULL,
    "actor_id"    bigint,
    "transition_type" character varying(10) DEFAULT 'MANUAL' NOT NULL,
    "created_at"  timestamp with time zone DEFAULT now() NOT NULL,
    PRIMARY KEY ("id")
);
ALTER SEQUENCE "jam_status_log_id_seq" OWNED BY "jam_status_log"."id";
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_status_log_jam_fkey') THEN
        ALTER TABLE "jam_status_log" ADD CONSTRAINT "jam_status_log_jam_fkey"
            FOREIGN KEY ("jam_id") REFERENCES "jams" ("id");
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_status_log_to_status_check') THEN
        ALTER TABLE "jam_status_log" ADD CONSTRAINT "jam_status_log_to_status_check"
            CHECK ("to_status" IN ('RECRUIT', 'DEV', 'EVAL', 'CLOSED'));
    END IF;
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'jam_status_log_transition_type_check') THEN
        ALTER TABLE "jam_status_log" ADD CONSTRAINT "jam_status_log_transition_type_check"
            CHECK ("transition_type" IN ('MANUAL', 'AUTO'));
    END IF;
END
$$;
CREATE INDEX IF NOT EXISTS "idx_jam_status_log_jam" ON "jam_status_log" ("jam_id", "created_at" DESC);
