-- +mixmaker Up
CREATE TABLE discord_managed_roles (
    scope text NOT NULL CHECK (scope IN ('global', 'event')),
    event_id text NOT NULL DEFAULT '',
    team_id text NOT NULL DEFAULT '',
    kind text NOT NULL CHECK (kind IN ('tank', 'damage', 'support', 'team', 'captain')),
    discord_role_id text NOT NULL UNIQUE,
    role_name text NOT NULL,
    updated_at timestamptz NOT NULL DEFAULT now(),
    PRIMARY KEY (scope, event_id, team_id, kind)
);

CREATE TABLE discord_role_assignments (
    discord_role_id text NOT NULL REFERENCES discord_managed_roles(discord_role_id) ON DELETE CASCADE,
    discord_user_id text NOT NULL,
    updated_at timestamptz NOT NULL DEFAULT now(),
    PRIMARY KEY (discord_role_id, discord_user_id)
);

CREATE TABLE discord_role_sync_jobs (
    id bigserial PRIMARY KEY,
    event_id text NOT NULL,
    action text NOT NULL CHECK (action IN ('reconcile', 'teardown')),
    generation bigint NOT NULL,
    role_snapshot jsonb NOT NULL DEFAULT '[]'::jsonb,
    status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'completed')),
    attempts integer NOT NULL DEFAULT 0,
    available_at timestamptz NOT NULL DEFAULT now(),
    last_error text NOT NULL DEFAULT '',
    created_at timestamptz NOT NULL DEFAULT now(),
    updated_at timestamptz NOT NULL DEFAULT now(),
    completed_at timestamptz,
    UNIQUE (event_id, action, generation)
);

CREATE INDEX discord_role_sync_jobs_claim_idx
    ON discord_role_sync_jobs(status, available_at, id);

-- +mixmaker Down
DROP TABLE IF EXISTS discord_role_sync_jobs;
DROP TABLE IF EXISTS discord_role_assignments;
DROP TABLE IF EXISTS discord_managed_roles;
