CREATE EXTENSION IF NOT EXISTS pgcrypto;

CREATE TABLE users (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    external_ref text NOT NULL UNIQUE,
    created_at timestamptz NOT NULL DEFAULT now(),
    preferred_language text NOT NULL,
    device_platform text NOT NULL
);

CREATE TABLE sessions (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    started_at timestamptz NOT NULL DEFAULT now(),
    ended_at timestamptz,
    experiment_variant text NOT NULL,
    app_version text NOT NULL,
    device_model text,
    os_version text,
    locale_code text NOT NULL
);

CREATE TABLE events (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    sport_type text NOT NULL,
    source_ref text NOT NULL UNIQUE,
    title_en text NOT NULL,
    title_sv text NOT NULL,
    status text NOT NULL,
    preview_start_ms bigint NOT NULL,
    preview_end_ms bigint NOT NULL,
    reveal_start_ms bigint NOT NULL,
    reveal_end_ms bigint NOT NULL,
    lock_at timestamptz NOT NULL,
    settle_at timestamptz NOT NULL
);

CREATE TABLE event_media (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    event_id uuid NOT NULL REFERENCES events(id) ON DELETE CASCADE,
    media_type text NOT NULL,
    hls_master_url text NOT NULL,
    poster_url text,
    duration_ms bigint NOT NULL,
    preview_start_ms bigint NOT NULL,
    preview_end_ms bigint NOT NULL,
    reveal_start_ms bigint NOT NULL,
    reveal_end_ms bigint NOT NULL,
    UNIQUE (event_id, media_type)
);

CREATE TABLE markets (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    event_id uuid NOT NULL REFERENCES events(id) ON DELETE CASCADE,
    question_key text NOT NULL,
    market_type text NOT NULL,
    status text NOT NULL,
    lock_at timestamptz NOT NULL,
    settlement_rule_key text NOT NULL
);

CREATE TABLE outcomes (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    market_id uuid NOT NULL REFERENCES markets(id) ON DELETE CASCADE,
    outcome_code text NOT NULL,
    label_key text NOT NULL,
    sort_order integer NOT NULL,
    UNIQUE (market_id, outcome_code)
);

CREATE TABLE odds_versions (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    market_id uuid NOT NULL REFERENCES markets(id) ON DELETE CASCADE,
    version_no integer NOT NULL,
    created_at timestamptz NOT NULL DEFAULT now(),
    is_current boolean NOT NULL DEFAULT false,
    UNIQUE (market_id, version_no)
);

CREATE UNIQUE INDEX odds_versions_current_idx
    ON odds_versions (market_id)
    WHERE is_current;

CREATE TABLE outcome_odds (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    odds_version_id uuid NOT NULL REFERENCES odds_versions(id) ON DELETE CASCADE,
    outcome_id uuid NOT NULL REFERENCES outcomes(id) ON DELETE CASCADE,
    decimal_odds numeric(10,4) NOT NULL,
    fractional_num integer NOT NULL,
    fractional_den integer NOT NULL,
    UNIQUE (odds_version_id, outcome_id)
);

CREATE TABLE bet_intents (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id uuid NOT NULL REFERENCES users(id),
    session_id uuid NOT NULL REFERENCES sessions(id),
    event_id uuid NOT NULL REFERENCES events(id),
    market_id uuid NOT NULL REFERENCES markets(id),
    outcome_id uuid NOT NULL REFERENCES outcomes(id),
    idempotency_key text NOT NULL UNIQUE,
    client_sent_at timestamptz NOT NULL,
    server_received_at timestamptz NOT NULL DEFAULT now(),
    accepted boolean NOT NULL,
    acceptance_code text NOT NULL,
    accepted_odds_version_id uuid REFERENCES odds_versions(id)
);

CREATE TABLE settlements (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    market_id uuid NOT NULL UNIQUE REFERENCES markets(id) ON DELETE CASCADE,
    settled_at timestamptz NOT NULL,
    winning_outcome_id uuid NOT NULL REFERENCES outcomes(id)
);

CREATE TABLE experiment_assignments (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    session_id uuid NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
    variant text NOT NULL,
    assigned_at timestamptz NOT NULL DEFAULT now(),
    UNIQUE (session_id)
);

CREATE TABLE localization_keys (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    key_name text NOT NULL UNIQUE,
    description text NOT NULL
);

CREATE TABLE localization_values (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    localization_key_id uuid NOT NULL REFERENCES localization_keys(id) ON DELETE CASCADE,
    locale_code text NOT NULL,
    text_value text NOT NULL,
    UNIQUE (localization_key_id, locale_code)
);

CREATE TABLE analytics_event_types (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    event_name text NOT NULL UNIQUE,
    description text NOT NULL
);

CREATE TABLE analytics_events (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    analytics_event_type_id uuid NOT NULL REFERENCES analytics_event_types(id),
    session_id uuid NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
    user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    occurred_at timestamptz NOT NULL DEFAULT now()
);

CREATE TABLE analytics_event_attributes (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    analytics_event_id uuid NOT NULL REFERENCES analytics_events(id) ON DELETE CASCADE,
    attribute_key text NOT NULL,
    attribute_value text NOT NULL
);

CREATE TABLE audit_logs (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    created_at timestamptz NOT NULL DEFAULT now(),
    actor_type text NOT NULL,
    actor_id uuid,
    action_name text NOT NULL,
    target_type text NOT NULL,
    target_id uuid,
    trace_id text NOT NULL,
    note text
);

CREATE TABLE audit_log_attributes (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    audit_log_id uuid NOT NULL REFERENCES audit_logs(id) ON DELETE CASCADE,
    attribute_key text NOT NULL,
    attribute_value text NOT NULL
);

CREATE INDEX sessions_user_id_idx ON sessions (user_id);
CREATE INDEX sessions_started_at_idx ON sessions (started_at);
CREATE INDEX events_status_idx ON events (status);
CREATE INDEX markets_event_id_idx ON markets (event_id);
CREATE INDEX markets_lock_at_idx ON markets (lock_at);
CREATE INDEX bet_intents_session_id_idx ON bet_intents (session_id);
CREATE INDEX bet_intents_market_id_idx ON bet_intents (market_id);
CREATE INDEX bet_intents_idempotency_key_idx ON bet_intents (idempotency_key);
CREATE INDEX analytics_events_session_id_idx ON analytics_events (session_id);
CREATE INDEX analytics_events_user_id_idx ON analytics_events (user_id);
CREATE INDEX analytics_events_type_id_idx ON analytics_events (analytics_event_type_id);
CREATE INDEX audit_logs_created_at_idx ON audit_logs (created_at);
