-- Corrosion Platform — Initial Schema
-- All tables scoped by license_id for multi-tenant isolation

-- Enable UUID extension
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-----------------------------------------------------------
-- USERS & AUTH
-----------------------------------------------------------

CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    email VARCHAR(255) NOT NULL UNIQUE,
    username VARCHAR(50) NOT NULL UNIQUE,
    password_hash TEXT NOT NULL,
    totp_secret TEXT,
    totp_enabled BOOLEAN NOT NULL DEFAULT false,
    backup_codes TEXT[],
    email_verified BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    last_login_at TIMESTAMPTZ
);

CREATE INDEX idx_users_email ON users(email);

-----------------------------------------------------------
-- LICENSES
-----------------------------------------------------------

CREATE TABLE licenses (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_key VARCHAR(64) NOT NULL UNIQUE,
    status VARCHAR(20) NOT NULL DEFAULT 'active'
        CHECK (status IN ('active', 'suspended', 'expired', 'revoked')),
    owner_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    server_name VARCHAR(100),
    subdomain VARCHAR(63) UNIQUE,
    custom_domain VARCHAR(255) UNIQUE,
    modules_enabled TEXT[] DEFAULT '{}',
    webstore_active BOOLEAN NOT NULL DEFAULT false,
    webstore_subscription_id VARCHAR(100),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    expires_at TIMESTAMPTZ
);

CREATE INDEX idx_licenses_key ON licenses(license_key);
CREATE INDEX idx_licenses_owner ON licenses(owner_user_id);
CREATE INDEX idx_licenses_subdomain ON licenses(subdomain);

-----------------------------------------------------------
-- TEAM & RBAC
-----------------------------------------------------------

CREATE TABLE roles (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID REFERENCES licenses(id) ON DELETE CASCADE,
    role_name VARCHAR(50) NOT NULL,
    is_system_default BOOLEAN NOT NULL DEFAULT false,
    is_cloned_from UUID REFERENCES roles(id) ON DELETE SET NULL,
    permissions JSONB NOT NULL DEFAULT '{}',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_roles_license ON roles(license_id);

CREATE TABLE team_members (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    role_id UUID NOT NULL REFERENCES roles(id) ON DELETE RESTRICT,
    invited_by UUID NOT NULL REFERENCES users(id),
    accepted_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE(license_id, user_id)
);

CREATE INDEX idx_team_license ON team_members(license_id);
CREATE INDEX idx_team_user ON team_members(user_id);

-----------------------------------------------------------
-- SERVER CONNECTION & CONFIG
-----------------------------------------------------------

CREATE TABLE server_connections (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL UNIQUE REFERENCES licenses(id) ON DELETE CASCADE,
    connection_type VARCHAR(20) NOT NULL
        CHECK (connection_type IN ('amp', 'pterodactyl', 'bare_metal')),
    panel_api_endpoint TEXT,
    panel_api_key_encrypted TEXT,
    panel_server_identifier VARCHAR(255),
    companion_agent_token VARCHAR(128),
    companion_last_seen TIMESTAMPTZ,
    plugin_last_seen TIMESTAMPTZ,
    server_ip VARCHAR(45),
    server_port INTEGER,
    game_port INTEGER,
    connection_status VARCHAR(20) NOT NULL DEFAULT 'offline'
        CHECK (connection_status IN ('connected', 'degraded', 'offline')),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_server_conn_license ON server_connections(license_id);

CREATE TABLE server_config (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL UNIQUE REFERENCES licenses(id) ON DELETE CASCADE,
    server_name VARCHAR(255) NOT NULL DEFAULT '',
    max_players INTEGER,
    world_size INTEGER,
    current_seed INTEGER,
    current_map_id UUID,
    server_description TEXT,
    server_url TEXT,
    server_header_image TEXT,
    tags TEXT[] DEFAULT '{}',
    auto_restart_enabled BOOLEAN NOT NULL DEFAULT false,
    auto_restart_cron VARCHAR(100),
    auto_restart_timezone VARCHAR(50),
    crash_recovery_enabled BOOLEAN NOT NULL DEFAULT true,
    crash_recovery_max_attempts INTEGER NOT NULL DEFAULT 3,
    crash_recovery_cooldown_minutes INTEGER NOT NULL DEFAULT 10,
    force_wipe_eligible BOOLEAN NOT NULL DEFAULT true,
    auto_update_on_force_wipe BOOLEAN NOT NULL DEFAULT true,
    config_overrides JSONB DEFAULT '{}',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_server_config_license ON server_config(license_id);

-----------------------------------------------------------
-- GAME ADMINS (in-game SteamID-based)
-----------------------------------------------------------

CREATE TABLE game_admins (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    steam_id VARCHAR(20) NOT NULL,
    display_name VARCHAR(100) NOT NULL DEFAULT '',
    admin_level VARCHAR(20) NOT NULL DEFAULT 'admin'
        CHECK (admin_level IN ('owner', 'admin', 'moderator')),
    permissions JSONB DEFAULT '{}',
    added_by UUID NOT NULL REFERENCES users(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE(license_id, steam_id)
);

CREATE INDEX idx_game_admins_license ON game_admins(license_id);

-----------------------------------------------------------
-- WIPE PROFILES & SCHEDULES
-----------------------------------------------------------

CREATE TABLE wipe_profiles (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    profile_name VARCHAR(100) NOT NULL,
    description TEXT,
    pre_wipe_config JSONB NOT NULL DEFAULT '{
        "enabled": true,
        "backup_before_wipe": true,
        "countdown_warnings": [30, 15, 5, 1],
        "countdown_unit": "minutes",
        "countdown_messages": {},
        "kick_players_before_wipe": true,
        "kick_message": "Server is wiping. Be back shortly!",
        "run_final_save": true,
        "discord_pre_announce": true,
        "pushbullet_notify": false,
        "custom_commands_before": []
    }',
    post_wipe_config JSONB NOT NULL DEFAULT '{
        "enabled": true,
        "verify_server_started": true,
        "verify_correct_map": true,
        "verify_plugins_loaded": true,
        "verify_player_slots_open": true,
        "max_restart_attempts": 3,
        "health_check_timeout_seconds": 120,
        "discord_post_announce": true,
        "pushbullet_notify": false,
        "rollback_on_failure": true,
        "post_wipe_commands": []
    }',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_wipe_profiles_license ON wipe_profiles(license_id);

CREATE TABLE wipe_schedules (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    wipe_profile_id UUID NOT NULL REFERENCES wipe_profiles(id) ON DELETE CASCADE,
    schedule_name VARCHAR(100) NOT NULL,
    wipe_type VARCHAR(20) NOT NULL
        CHECK (wipe_type IN ('map', 'blueprint', 'full')),
    cron_expression VARCHAR(100) NOT NULL,
    timezone VARCHAR(50) NOT NULL DEFAULT 'America/New_York',
    wipe_blueprints BOOLEAN NOT NULL DEFAULT false,
    is_active BOOLEAN NOT NULL DEFAULT true,
    next_scheduled_run TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_wipe_schedules_license ON wipe_schedules(license_id);
CREATE INDEX idx_wipe_schedules_next_run ON wipe_schedules(next_scheduled_run) WHERE is_active = true;

-----------------------------------------------------------
-- MAP LIBRARY & ROTATION
-----------------------------------------------------------

CREATE TABLE map_library (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    filename VARCHAR(255) NOT NULL,
    display_name VARCHAR(255) NOT NULL,
    storage_path TEXT NOT NULL,
    file_size_bytes BIGINT NOT NULL DEFAULT 0,
    map_type VARCHAR(20) NOT NULL DEFAULT 'custom'
        CHECK (map_type IN ('custom', 'procedural')),
    seed INTEGER,
    world_size INTEGER,
    thumbnail_path TEXT,
    checksum VARCHAR(64) NOT NULL,
    uploaded_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_map_library_license ON map_library(license_id);

-- FK for server_config.current_map_id (deferred because map_library created after server_config)
ALTER TABLE server_config
    ADD CONSTRAINT fk_server_config_map
    FOREIGN KEY (current_map_id) REFERENCES map_library(id) ON DELETE SET NULL;

CREATE TABLE map_rotations (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    map_id UUID NOT NULL REFERENCES map_library(id) ON DELETE CASCADE,
    rotation_order INTEGER NOT NULL DEFAULT 0,
    is_active BOOLEAN NOT NULL DEFAULT true,
    UNIQUE(license_id, rotation_order)
);

CREATE INDEX idx_map_rotations_license ON map_rotations(license_id);

-----------------------------------------------------------
-- PLUGIN REGISTRY
-----------------------------------------------------------

CREATE TABLE plugin_registry (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    plugin_name VARCHAR(255) NOT NULL,
    plugin_version VARCHAR(50),
    source VARCHAR(20) NOT NULL DEFAULT 'manual'
        CHECK (source IN ('umod', 'corrosion_module', 'manual')),
    umod_slug VARCHAR(255),
    is_installed BOOLEAN NOT NULL DEFAULT false,
    is_loaded BOOLEAN NOT NULL DEFAULT false,
    config_json JSONB,
    data_path TEXT,
    wipe_on_map BOOLEAN NOT NULL DEFAULT false,
    wipe_on_bp BOOLEAN NOT NULL DEFAULT false,
    wipe_on_full BOOLEAN NOT NULL DEFAULT false,
    never_wipe BOOLEAN NOT NULL DEFAULT false,
    installed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE(license_id, plugin_name)
);

CREATE INDEX idx_plugin_registry_license ON plugin_registry(license_id);

-----------------------------------------------------------
-- WIPE HISTORY
-----------------------------------------------------------

CREATE TABLE wipe_history (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    wipe_schedule_id UUID REFERENCES wipe_schedules(id) ON DELETE SET NULL,
    wipe_profile_id UUID NOT NULL REFERENCES wipe_profiles(id),
    wipe_type VARCHAR(20) NOT NULL,
    trigger_type VARCHAR(20) NOT NULL
        CHECK (trigger_type IN ('scheduled', 'manual', 'force_wipe')),
    status VARCHAR(20) NOT NULL DEFAULT 'pending'
        CHECK (status IN ('pending', 'pre_wipe', 'wiping', 'post_wipe', 'success', 'failed', 'rolled_back')),
    started_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ,
    map_used VARCHAR(255),
    plugins_wiped TEXT[],
    plugins_preserved TEXT[],
    backup_reference TEXT,
    error_message TEXT,
    execution_log JSONB DEFAULT '[]',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_wipe_history_license ON wipe_history(license_id);
CREATE INDEX idx_wipe_history_created ON wipe_history(created_at DESC);

-----------------------------------------------------------
-- SCHEDULED TASKS (restarts, announcements, etc.)
-----------------------------------------------------------

CREATE TABLE scheduled_tasks (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    task_type VARCHAR(30) NOT NULL
        CHECK (task_type IN ('restart', 'announcement', 'command', 'plugin_reload')),
    task_name VARCHAR(100) NOT NULL,
    cron_expression VARCHAR(100) NOT NULL,
    timezone VARCHAR(50) NOT NULL DEFAULT 'America/New_York',
    task_config JSONB NOT NULL DEFAULT '{}',
    is_active BOOLEAN NOT NULL DEFAULT true,
    next_run TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_scheduled_tasks_license ON scheduled_tasks(license_id);

-----------------------------------------------------------
-- NOTIFICATIONS
-----------------------------------------------------------

CREATE TABLE notifications_config (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL UNIQUE REFERENCES licenses(id) ON DELETE CASCADE,
    discord_webhook_url TEXT,
    discord_enabled BOOLEAN NOT NULL DEFAULT false,
    pushbullet_api_key TEXT,
    pushbullet_enabled BOOLEAN NOT NULL DEFAULT false,
    email_alerts_enabled BOOLEAN NOT NULL DEFAULT true,
    notify_wipe_start BOOLEAN NOT NULL DEFAULT true,
    notify_wipe_complete BOOLEAN NOT NULL DEFAULT true,
    notify_wipe_failed BOOLEAN NOT NULL DEFAULT true,
    notify_server_crash BOOLEAN NOT NULL DEFAULT true,
    notify_server_offline BOOLEAN NOT NULL DEFAULT true,
    notify_store_purchase BOOLEAN NOT NULL DEFAULT true,
    notify_player_report BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-----------------------------------------------------------
-- CHAT LOGS & PLAYER ACTIONS
-----------------------------------------------------------

CREATE TABLE chat_logs (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    steam_id VARCHAR(20) NOT NULL,
    player_name VARCHAR(100) NOT NULL,
    channel VARCHAR(20) NOT NULL DEFAULT 'global'
        CHECK (channel IN ('global', 'team', 'server')),
    message TEXT NOT NULL,
    flagged BOOLEAN NOT NULL DEFAULT false,
    flagged_by UUID REFERENCES users(id),
    flag_reason TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_chat_logs_license ON chat_logs(license_id);
CREATE INDEX idx_chat_logs_created ON chat_logs(created_at DESC);
CREATE INDEX idx_chat_logs_steam ON chat_logs(license_id, steam_id);

CREATE TABLE player_actions (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    steam_id VARCHAR(20) NOT NULL,
    player_name VARCHAR(100) NOT NULL,
    action_type VARCHAR(20) NOT NULL
        CHECK (action_type IN ('kick', 'ban', 'unban', 'warn', 'note')),
    reason TEXT,
    duration_minutes INTEGER,
    performed_by UUID NOT NULL REFERENCES users(id),
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_player_actions_license ON player_actions(license_id);
CREATE INDEX idx_player_actions_steam ON player_actions(license_id, steam_id);

-----------------------------------------------------------
-- SERVER STATS (time-series)
-----------------------------------------------------------

CREATE TABLE server_stats (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    player_count INTEGER NOT NULL DEFAULT 0,
    max_players INTEGER NOT NULL DEFAULT 0,
    fps DOUBLE PRECISION NOT NULL DEFAULT 0,
    entity_count INTEGER NOT NULL DEFAULT 0,
    uptime_seconds INTEGER NOT NULL DEFAULT 0,
    memory_usage_mb INTEGER NOT NULL DEFAULT 0,
    recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_server_stats_license_time ON server_stats(license_id, recorded_at DESC);

CREATE TABLE server_stats_hourly (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    hour TIMESTAMPTZ NOT NULL,
    avg_players DOUBLE PRECISION NOT NULL DEFAULT 0,
    max_players INTEGER NOT NULL DEFAULT 0,
    avg_fps DOUBLE PRECISION NOT NULL DEFAULT 0,
    min_fps DOUBLE PRECISION NOT NULL DEFAULT 0,
    avg_entities INTEGER NOT NULL DEFAULT 0,
    uptime_percentage DOUBLE PRECISION NOT NULL DEFAULT 0,
    UNIQUE(license_id, hour)
);

CREATE INDEX idx_stats_hourly_license ON server_stats_hourly(license_id, hour DESC);

-----------------------------------------------------------
-- PUBLIC SITE CONFIG
-----------------------------------------------------------

CREATE TABLE public_site_config (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL UNIQUE REFERENCES licenses(id) ON DELETE CASCADE,
    site_enabled BOOLEAN NOT NULL DEFAULT true,
    show_on_status_page BOOLEAN NOT NULL DEFAULT false,
    steam_connect_url VARCHAR(255),
    motd TEXT,
    public_mods TEXT[] DEFAULT '{}',
    header_image_url TEXT,
    theme_color VARCHAR(7) DEFAULT '#ef4444',
    custom_css TEXT,
    discord_invite_url TEXT,
    show_player_count BOOLEAN NOT NULL DEFAULT true,
    show_wipe_schedule BOOLEAN NOT NULL DEFAULT true,
    show_wipe_countdown BOOLEAN NOT NULL DEFAULT true,
    show_mod_list BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-----------------------------------------------------------
-- WEBSTORE
-----------------------------------------------------------

CREATE TABLE webstore_config (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL UNIQUE REFERENCES licenses(id) ON DELETE CASCADE,
    is_active BOOLEAN NOT NULL DEFAULT false,
    paypal_client_id TEXT,
    paypal_secret TEXT,
    paypal_mode VARCHAR(10) NOT NULL DEFAULT 'sandbox'
        CHECK (paypal_mode IN ('sandbox', 'live')),
    store_name VARCHAR(100),
    store_description TEXT,
    currency VARCHAR(3) NOT NULL DEFAULT 'USD',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE webstore_categories (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    category_name VARCHAR(100) NOT NULL,
    display_order INTEGER NOT NULL DEFAULT 0,
    is_active BOOLEAN NOT NULL DEFAULT true
);

CREATE INDEX idx_webstore_cats_license ON webstore_categories(license_id);

CREATE TABLE webstore_items (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    category_id UUID NOT NULL REFERENCES webstore_categories(id) ON DELETE CASCADE,
    item_name VARCHAR(100) NOT NULL,
    description TEXT,
    price DECIMAL(10,2) NOT NULL,
    image_url TEXT,
    item_type VARCHAR(20) NOT NULL DEFAULT 'kit'
        CHECK (item_type IN ('kit', 'rank', 'currency', 'custom_command')),
    delivery_config JSONB NOT NULL DEFAULT '{"commands": []}',
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_webstore_items_license ON webstore_items(license_id);
CREATE INDEX idx_webstore_items_category ON webstore_items(category_id);

CREATE TABLE webstore_transactions (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    item_id UUID NOT NULL REFERENCES webstore_items(id),
    buyer_steam_id VARCHAR(20) NOT NULL,
    buyer_name VARCHAR(100),
    amount DECIMAL(10,2) NOT NULL,
    currency VARCHAR(3) NOT NULL DEFAULT 'USD',
    paypal_transaction_id VARCHAR(100),
    status VARCHAR(20) NOT NULL DEFAULT 'pending'
        CHECK (status IN ('pending', 'paid', 'delivered', 'failed', 'refunded')),
    delivered_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_webstore_txn_license ON webstore_transactions(license_id);
CREATE INDEX idx_webstore_txn_status ON webstore_transactions(license_id, status);

-----------------------------------------------------------
-- MIGRATION EXPORTS
-----------------------------------------------------------

CREATE TABLE migration_exports (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
    export_type VARCHAR(20) NOT NULL DEFAULT 'full'
        CHECK (export_type IN ('full', 'config_only', 'store_only')),
    storage_path TEXT NOT NULL,
    file_size_bytes BIGINT NOT NULL DEFAULT 0,
    created_by UUID NOT NULL REFERENCES users(id),
    expires_at TIMESTAMPTZ NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-----------------------------------------------------------
-- PLATFORM CHANGELOG
-----------------------------------------------------------

CREATE TABLE platform_changelog (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    version VARCHAR(20) NOT NULL,
    title VARCHAR(200) NOT NULL,
    body TEXT NOT NULL,
    category VARCHAR(20) NOT NULL DEFAULT 'feature'
        CHECK (category IN ('feature', 'bugfix', 'module', 'security')),
    published_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-----------------------------------------------------------
-- MODULE STORE
-----------------------------------------------------------

CREATE TABLE module_store (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    module_slug VARCHAR(50) NOT NULL UNIQUE,
    module_name VARCHAR(100) NOT NULL,
    description TEXT,
    long_description TEXT,
    price DECIMAL(10,2) NOT NULL DEFAULT 0,
    price_type VARCHAR(20) NOT NULL DEFAULT 'one_time'
        CHECK (price_type IN ('one_time', 'monthly')),
    monthly_price DECIMAL(10,2),
    version VARCHAR(20) NOT NULL DEFAULT '1.0.0',
    download_path TEXT,
    thumbnail_url TEXT,
    screenshots TEXT[] DEFAULT '{}',
    category VARCHAR(50),
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-----------------------------------------------------------
-- DEFAULT SYSTEM ROLES
-----------------------------------------------------------

INSERT INTO roles (id, license_id, role_name, is_system_default, permissions) VALUES
(uuid_generate_v4(), NULL, 'Owner', true, '{
    "server.*": true,
    "wipe.*": true,
    "plugins.*": true,
    "players.*": true,
    "team.*": true,
    "billing.*": true,
    "store.*": true,
    "settings.*": true,
    "public_site.*": true
}'),
(uuid_generate_v4(), NULL, 'Head Admin', true, '{
    "server.*": true,
    "wipe.*": true,
    "plugins.*": true,
    "players.*": true,
    "team.view": true,
    "team.invite": true,
    "store.*": true,
    "settings.server": true,
    "public_site.*": true
}'),
(uuid_generate_v4(), NULL, 'Moderator', true, '{
    "server.view": true,
    "server.console": true,
    "players.kick": true,
    "players.ban": true,
    "players.chat_log": true,
    "wipe.view": true,
    "store.view": true
}'),
(uuid_generate_v4(), NULL, 'Viewer', true, '{
    "server.view": true,
    "players.view": true,
    "wipe.view": true,
    "store.view": true
}');
