CREATE TABLE IF NOT EXISTS users (
    id VARCHAR(64) PRIMARY KEY,
    external_id VARCHAR(255),
    email VARCHAR(320),
    username VARCHAR(255),
    password_hash VARCHAR(255),
    role VARCHAR(64),
    auth_source VARCHAR(64) NOT NULL DEFAULT 'local',
    email_verified TINYINT(1) NOT NULL DEFAULT 0,
    is_active TINYINT(1) NOT NULL DEFAULT 1,
    is_deleted TINYINT(1) NOT NULL DEFAULT 0,
    allowed_models TEXT,
    allowed_providers TEXT,
    allowed_api_formats TEXT,
    model_capability_settings TEXT,
    rate_limit INT,
    metadata TEXT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    last_login_at BIGINT,
    ldap_dn VARCHAR(1024),
    ldap_username VARCHAR(255),
    UNIQUE KEY users_email_key (email),
    UNIQUE KEY users_username_key (username)
);

CREATE TABLE IF NOT EXISTS api_keys (
    id VARCHAR(64) PRIMARY KEY,
    user_id VARCHAR(64) NOT NULL,
    key_hash VARCHAR(255) NOT NULL,
    key_encrypted TEXT,
    name VARCHAR(255),
    key_prefix VARCHAR(64),
    status VARCHAR(64) NOT NULL DEFAULT 'active',
    allowed_models TEXT,
    allowed_providers TEXT,
    allowed_api_formats TEXT,
    rate_limit INT DEFAULT 100,
    concurrent_limit INT,
    force_capabilities TEXT,
    is_active TINYINT(1) NOT NULL DEFAULT 1,
    is_locked TINYINT(1) NOT NULL DEFAULT 0,
    is_standalone TINYINT(1) NOT NULL DEFAULT 0,
    auto_delete_on_expiry TINYINT(1) NOT NULL DEFAULT 0,
    total_requests BIGINT NOT NULL DEFAULT 0,
    total_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost_usd DOUBLE NOT NULL DEFAULT 0,
    metadata TEXT,
    expires_at BIGINT,
    last_used_at BIGINT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY [REDACTED](key_hash),
    KEY [REDACTED](user_id)
);

CREATE TABLE IF NOT EXISTS audit_logs (
    id VARCHAR(64) PRIMARY KEY,
    event_type VARCHAR(64) NOT NULL,
    user_id VARCHAR(64),
    api_key_id VARCHAR(64),
    description TEXT NOT NULL,
    ip_address VARCHAR(64),
    user_agent VARCHAR(512),
    request_id VARCHAR(128),
    event_metadata TEXT,
    status_code INT,
    error_message TEXT,
    created_at BIGINT NOT NULL,
    KEY audit_logs_created_at_idx (created_at),
    KEY audit_logs_event_type_idx (event_type),
    KEY audit_logs_request_id_idx (request_id),
    KEY audit_logs_user_id_idx (user_id)
);

CREATE TABLE IF NOT EXISTS announcements (
    id VARCHAR(64) PRIMARY KEY,
    title VARCHAR(200) NOT NULL,
    content TEXT NOT NULL,
    `type` VARCHAR(32) NOT NULL DEFAULT 'info',
    priority INT NOT NULL DEFAULT 0,
    author_id VARCHAR(64),
    is_active TINYINT(1) NOT NULL DEFAULT 1,
    is_pinned TINYINT(1) NOT NULL DEFAULT 0,
    start_time BIGINT,
    end_time BIGINT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    KEY announcements_author_id_idx (author_id),
    KEY announcements_created_at_idx (created_at),
    KEY announcements_is_active_idx (is_active)
);

CREATE TABLE IF NOT EXISTS announcement_reads (
    id VARCHAR(64) PRIMARY KEY,
    user_id VARCHAR(64) NOT NULL,
    announcement_id VARCHAR(64) NOT NULL,
    read_at BIGINT NOT NULL,
    UNIQUE KEY uq_user_announcement (user_id, announcement_id),
    KEY announcement_reads_announcement_id_idx (announcement_id),
    KEY announcement_reads_user_id_idx (user_id)
);

CREATE TABLE IF NOT EXISTS management_tokens (
    id VARCHAR(64) PRIMARY KEY,
    user_id VARCHAR(64) NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    token_hash VARCHAR(255) NOT NULL,
    token_prefix VARCHAR(64),
    allowed_ips TEXT,
    expires_at BIGINT,
    last_used_at BIGINT,
    last_used_ip VARCHAR(255),
    usage_count BIGINT NOT NULL DEFAULT 0,
    is_active TINYINT(1) NOT NULL DEFAULT 1,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY management_tokens_token_hash_key (token_hash),
    UNIQUE KEY uq_management_tokens_user_name (user_id, name),
    KEY management_tokens_user_id_idx (user_id)
);

CREATE TABLE IF NOT EXISTS user_preferences (
    id VARCHAR(36) PRIMARY KEY,
    user_id VARCHAR(36) NOT NULL UNIQUE,
    avatar_url VARCHAR(500),
    bio TEXT,
    default_provider_id VARCHAR(36),
    theme VARCHAR(20) NOT NULL DEFAULT 'light',
    language VARCHAR(10) NOT NULL DEFAULT 'zh-CN',
    timezone VARCHAR(50) NOT NULL DEFAULT 'Asia/Shanghai',
    email_notifications BOOLEAN NOT NULL DEFAULT TRUE,
    usage_alerts BOOLEAN NOT NULL DEFAULT TRUE,
    announcement_notifications BOOLEAN NOT NULL DEFAULT TRUE,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    INDEX user_preferences_default_provider_id_idx (default_provider_id),
    INDEX user_preferences_user_id_idx (user_id)
);

CREATE TABLE IF NOT EXISTS user_sessions (
    id VARCHAR(36) PRIMARY KEY,
    user_id VARCHAR(36) NOT NULL,
    client_device_id VARCHAR(128) NOT NULL,
    device_label VARCHAR(120),
    device_type VARCHAR(20) NOT NULL DEFAULT 'unknown',
    browser_name VARCHAR(50),
    browser_version VARCHAR(50),
    os_name VARCHAR(50),
    os_version VARCHAR(50),
    device_model VARCHAR(100),
    ip_address VARCHAR(45),
    user_agent VARCHAR(1000),
    client_hints TEXT,
    refresh_token_hash VARCHAR(64) NOT NULL,
    prev_refresh_token_hash VARCHAR(64),
    rotated_at BIGINT,
    last_seen_at BIGINT NOT NULL,
    expires_at BIGINT NOT NULL,
    revoked_at BIGINT,
    revoke_reason VARCHAR(100),
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    INDEX user_sessions_user_active_idx (user_id, revoked_at, expires_at),
    INDEX user_sessions_user_device_idx (user_id, client_device_id)
);
CREATE TABLE IF NOT EXISTS billing_rules (
    id VARCHAR(64) PRIMARY KEY,
    global_model_id VARCHAR(64),
    model_id VARCHAR(64),
    name VARCHAR(255) NOT NULL,
    task_type VARCHAR(64) NOT NULL DEFAULT 'chat',
    expression TEXT NOT NULL,
    variables TEXT NOT NULL,
    dimension_mappings TEXT NOT NULL,
    is_enabled TINYINT(1) NOT NULL DEFAULT 1,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    KEY billing_rules_global_model_task_idx (global_model_id, task_type, is_enabled),
    KEY billing_rules_model_task_idx (model_id, task_type, is_enabled)
);

CREATE TABLE IF NOT EXISTS dimension_collectors (
    id VARCHAR(64) PRIMARY KEY,
    api_format VARCHAR(64) NOT NULL,
    task_type VARCHAR(64) NOT NULL,
    dimension_name VARCHAR(128) NOT NULL,
    source_type VARCHAR(64) NOT NULL,
    source_path VARCHAR(255),
    value_type VARCHAR(64) NOT NULL DEFAULT 'float',
    transform_expression TEXT,
    default_value VARCHAR(255),
    priority INT NOT NULL DEFAULT 0,
    is_enabled TINYINT(1) NOT NULL DEFAULT 1,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    KEY dimension_collectors_enabled_idx (
        api_format,
        task_type,
        dimension_name,
        priority,
        is_enabled
    )
);

CREATE TABLE IF NOT EXISTS providers (
    id VARCHAR(64) PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    website VARCHAR(500),
    provider_type VARCHAR(64) NOT NULL,
    billing_type VARCHAR(64),
    monthly_quota_usd DOUBLE,
    monthly_used_usd DOUBLE,
    quota_reset_day INT,
    quota_last_reset_at BIGINT,
    quota_expires_at BIGINT,
    enabled TINYINT(1) NOT NULL DEFAULT 1,
    is_active TINYINT(1) NOT NULL DEFAULT 1,
    priority BIGINT NOT NULL DEFAULT 0,
    provider_priority INT NOT NULL DEFAULT 100,
    keep_priority_on_conversion TINYINT(1) NOT NULL DEFAULT 0,
    enable_format_conversion TINYINT(1) NOT NULL DEFAULT 1,
    concurrent_limit INT,
    max_retries INT,
    proxy TEXT,
    request_timeout DOUBLE,
    stream_first_byte_timeout DOUBLE,
    config TEXT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY providers_name_key (name)
);

CREATE TABLE IF NOT EXISTS provider_api_keys (
    id VARCHAR(64) PRIMARY KEY,
    provider_id VARCHAR(64) NOT NULL,
    name VARCHAR(255) NOT NULL,
    api_key TEXT,
    encrypted_key TEXT,
    auth_type VARCHAR(32) NOT NULL DEFAULT 'api_key',
    auth_config TEXT,
    note TEXT,
    internal_priority INT NOT NULL DEFAULT 50,
    capabilities TEXT,
    api_formats TEXT,
    auth_type_by_format TEXT,
    allow_auth_channel_mismatch_formats TEXT,
    rate_multipliers TEXT,
    global_priority_by_format TEXT,
    allowed_models TEXT,
    expires_at BIGINT,
    cache_ttl_minutes INT NOT NULL DEFAULT 5,
    max_probe_interval_minutes INT NOT NULL DEFAULT 32,
    proxy TEXT,
    fingerprint TEXT,
    concurrent_limit INT,
    learned_rpm_limit INT,
    concurrent_429_count INT NOT NULL DEFAULT 0,
    rpm_429_count INT NOT NULL DEFAULT 0,
    last_429_at BIGINT,
    last_429_type VARCHAR(64),
    adjustment_history TEXT,
    utilization_samples TEXT,
    last_probe_increase_at BIGINT,
    last_rpm_peak INT,
    request_count BIGINT NOT NULL DEFAULT 0,
    total_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost_usd DOUBLE NOT NULL DEFAULT 0,
    success_count BIGINT NOT NULL DEFAULT 0,
    error_count BIGINT NOT NULL DEFAULT 0,
    total_response_time_ms BIGINT NOT NULL DEFAULT 0,
    last_used_at BIGINT,
    auto_fetch_models TINYINT(1) NOT NULL DEFAULT 0,
    last_models_fetch_at BIGINT,
    last_models_fetch_error TEXT,
    locked_models TEXT,
    model_include_patterns TEXT,
    model_exclude_patterns TEXT,
    upstream_metadata TEXT,
    oauth_invalid_at BIGINT,
    oauth_invalid_reason VARCHAR(255),
    status_snapshot TEXT,
    health_by_format TEXT,
    circuit_breaker_by_format TEXT,
    status VARCHAR(64) NOT NULL DEFAULT 'active',
    is_active TINYINT(1) NOT NULL DEFAULT 1,
    weight BIGINT NOT NULL DEFAULT 1,
    rpm_limit BIGINT,
    metadata TEXT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    KEY provider_api_keys_provider_id_idx (provider_id)
);

CREATE TABLE IF NOT EXISTS gemini_file_mappings (
    id VARCHAR(64) PRIMARY KEY,
    file_name VARCHAR(512) NOT NULL,
    key_id VARCHAR(64) NOT NULL,
    user_id VARCHAR(64),
    display_name VARCHAR(512),
    mime_type VARCHAR(255),
    source_hash VARCHAR(128),
    created_at BIGINT NOT NULL,
    expires_at BIGINT NOT NULL,
    UNIQUE KEY gemini_file_mappings_file_name_key (file_name),
    KEY gemini_file_mappings_key_id_idx (key_id),
    KEY gemini_file_mappings_user_id_idx (user_id),
    KEY gemini_file_mappings_expires_at_idx (expires_at),
    KEY gemini_file_mappings_source_hash_idx (source_hash)
);

CREATE TABLE IF NOT EXISTS request_candidates (
    id VARCHAR(64) PRIMARY KEY,
    request_id VARCHAR(128) NOT NULL,
    user_id VARCHAR(64),
    api_key_id VARCHAR(64),
    username VARCHAR(255),
    api_key_name VARCHAR(255),
    candidate_index INT NOT NULL,
    retry_index INT NOT NULL DEFAULT 0,
    provider_id VARCHAR(64),
    endpoint_id VARCHAR(64),
    key_id VARCHAR(64),
    status VARCHAR(32) NOT NULL,
    skip_reason TEXT,
    is_cached TINYINT(1) NOT NULL DEFAULT 0,
    status_code INT,
    error_type VARCHAR(128),
    error_message TEXT,
    latency_ms INT,
    concurrent_requests INT,
    extra_data TEXT,
    required_capabilities TEXT,
    created_at BIGINT NOT NULL,
    started_at BIGINT,
    finished_at BIGINT,
    UNIQUE KEY uq_request_candidate_with_retry (request_id, candidate_index, retry_index),
    KEY request_candidates_request_id_idx (request_id),
    KEY request_candidates_provider_id_idx (provider_id),
    KEY request_candidates_endpoint_id_idx (endpoint_id),
    KEY request_candidates_status_idx (status),
    KEY request_candidates_created_at_idx (created_at),
    KEY request_candidates_endpoint_status_created_idx (endpoint_id, status, created_at)
);

CREATE TABLE IF NOT EXISTS video_tasks (
    id VARCHAR(64) PRIMARY KEY,
    short_id VARCHAR(32),
    request_id VARCHAR(128) NOT NULL,
    user_id VARCHAR(64),
    api_key_id VARCHAR(64),
    username VARCHAR(255),
    api_key_name VARCHAR(255),
    external_task_id VARCHAR(255),
    provider_id VARCHAR(64),
    endpoint_id VARCHAR(64),
    key_id VARCHAR(64),
    client_api_format VARCHAR(128),
    provider_api_format VARCHAR(128),
    format_converted TINYINT(1) NOT NULL DEFAULT 0,
    model VARCHAR(255),
    prompt TEXT,
    original_request_body TEXT,
    duration_seconds INT,
    resolution VARCHAR(64),
    aspect_ratio VARCHAR(32),
    size VARCHAR(64),
    status VARCHAR(32) NOT NULL DEFAULT 'pending',
    progress_percent INT NOT NULL DEFAULT 0,
    progress_message TEXT,
    retry_count INT NOT NULL DEFAULT 0,
    poll_interval_seconds INT NOT NULL DEFAULT 10,
    next_poll_at BIGINT,
    poll_count INT NOT NULL DEFAULT 0,
    max_poll_count INT NOT NULL DEFAULT 360,
    created_at BIGINT NOT NULL,
    submitted_at BIGINT,
    completed_at BIGINT,
    updated_at BIGINT NOT NULL,
    error_code VARCHAR(128),
    error_message TEXT,
    video_url TEXT,
    request_metadata TEXT,
    UNIQUE KEY video_tasks_short_id_key (short_id),
    UNIQUE KEY video_tasks_request_id_key (request_id),
    KEY video_tasks_external_id_idx (external_task_id),
    KEY video_tasks_next_poll_idx (next_poll_at),
    KEY video_tasks_user_status_idx (user_id, status),
    KEY video_tasks_api_key_id_idx (api_key_id),
    KEY video_tasks_provider_id_idx (provider_id),
    KEY video_tasks_endpoint_id_idx (endpoint_id),
    KEY video_tasks_key_id_idx (key_id)
);

CREATE TABLE IF NOT EXISTS provider_endpoints (
    id VARCHAR(64) PRIMARY KEY,
    provider_id VARCHAR(64) NOT NULL,
    name VARCHAR(255) NOT NULL,
    base_url TEXT NOT NULL,
    api_format VARCHAR(128),
    api_family VARCHAR(128),
    endpoint_kind VARCHAR(128),
    enabled TINYINT(1) NOT NULL DEFAULT 1,
    is_active TINYINT(1) NOT NULL DEFAULT 1,
    health_score DOUBLE NOT NULL DEFAULT 1.0,
    weight BIGINT NOT NULL DEFAULT 1,
    header_rules TEXT,
    body_rules TEXT,
    max_retries INT,
    custom_path TEXT,
    metadata TEXT,
    config TEXT,
    format_acceptance_config TEXT,
    proxy TEXT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    KEY provider_endpoints_provider_id_idx (provider_id)
);

CREATE TABLE IF NOT EXISTS models (
    id VARCHAR(64) PRIMARY KEY,
    provider_id VARCHAR(64) NOT NULL,
    global_model_id VARCHAR(64),
    provider_model_name VARCHAR(255) NOT NULL,
    global_model_name VARCHAR(255),
    api_format VARCHAR(128),
    enabled TINYINT(1) NOT NULL DEFAULT 1,
    is_active TINYINT(1) NOT NULL DEFAULT 1,
    is_available TINYINT(1) NOT NULL DEFAULT 1,
    price_per_request DOUBLE,
    tiered_pricing TEXT,
    supports_vision TINYINT(1),
    supports_function_calling TINYINT(1),
    supports_streaming TINYINT(1),
    supports_extended_thinking TINYINT(1),
    supports_image_generation TINYINT(1),
    provider_model_mappings TEXT,
    config TEXT,
    metadata TEXT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    KEY models_provider_id_idx (provider_id)
);

CREATE TABLE IF NOT EXISTS global_models (
    id VARCHAR(64) PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    display_name VARCHAR(255),
    enabled TINYINT(1) NOT NULL DEFAULT 1,
    is_active TINYINT(1) NOT NULL DEFAULT 1,
    default_price_per_request DOUBLE,
    default_tiered_pricing TEXT,
    supported_capabilities TEXT,
    usage_count BIGINT NOT NULL DEFAULT 0,
    config TEXT,
    metadata TEXT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY global_models_name_key (name)
);
CREATE TABLE IF NOT EXISTS system_configs (
    id VARCHAR(64) PRIMARY KEY,
    `key` VARCHAR(255) NOT NULL,
    value TEXT NOT NULL,
    description TEXT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY system_configs_key_key (`key`)
);

CREATE TABLE IF NOT EXISTS auth_modules (
    id VARCHAR(64) PRIMARY KEY,
    module_type VARCHAR(128) NOT NULL,
    enabled TINYINT(1) NOT NULL DEFAULT 1,
    config TEXT NOT NULL,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY auth_modules_module_type_key (module_type)
);

CREATE TABLE IF NOT EXISTS oauth_providers (
    provider_type VARCHAR(64) PRIMARY KEY,
    display_name VARCHAR(255) NOT NULL,
    client_id TEXT NOT NULL,
    client_secret_encrypted TEXT,
    authorization_url_override VARCHAR(500),
    token_url_override VARCHAR(500),
    userinfo_url_override VARCHAR(500),
    scopes TEXT,
    redirect_uri VARCHAR(500) NOT NULL,
    frontend_callback_url VARCHAR(500) NOT NULL,
    attribute_mapping TEXT,
    extra_config TEXT,
    is_enabled TINYINT(1) NOT NULL DEFAULT 0,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL
);

CREATE TABLE IF NOT EXISTS ldap_configs (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    server_url VARCHAR(255) NOT NULL,
    bind_dn TEXT NOT NULL,
    bind_password_encrypted TEXT,
    base_dn TEXT NOT NULL,
    user_search_filter VARCHAR(512) NOT NULL DEFAULT '(uid={username})',
    username_attr VARCHAR(50) NOT NULL DEFAULT 'uid',
    email_attr VARCHAR(50) NOT NULL DEFAULT 'mail',
    display_name_attr VARCHAR(50) NOT NULL DEFAULT 'cn',
    is_enabled TINYINT(1) NOT NULL DEFAULT 0,
    is_exclusive TINYINT(1) NOT NULL DEFAULT 0,
    use_starttls TINYINT(1) NOT NULL DEFAULT 0,
    connect_timeout INT NOT NULL DEFAULT 10,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL
);

CREATE TABLE IF NOT EXISTS user_oauth_links (
    id VARCHAR(64) PRIMARY KEY,
    user_id VARCHAR(64) NOT NULL,
    provider_type VARCHAR(64) NOT NULL,
    provider_user_id VARCHAR(255) NOT NULL,
    provider_username VARCHAR(255),
    provider_email VARCHAR(255),
    extra_data TEXT,
    linked_at BIGINT NOT NULL,
    last_login_at BIGINT,
    UNIQUE KEY uq_user_oauth_links_provider_user (provider_type, provider_user_id),
    UNIQUE KEY uq_user_oauth_links_user_provider (user_id, provider_type),
    KEY user_oauth_links_provider_type_idx (provider_type),
    KEY user_oauth_links_user_id_idx (user_id)
);
CREATE TABLE IF NOT EXISTS proxy_nodes (
    id VARCHAR(64) PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    ip VARCHAR(512) NOT NULL,
    port INT NOT NULL,
    region VARCHAR(100),
    status VARCHAR(32) NOT NULL DEFAULT 'online',
    registered_by VARCHAR(64),
    last_heartbeat_at BIGINT,
    heartbeat_interval INT NOT NULL DEFAULT 30,
    active_connections INT NOT NULL DEFAULT 0,
    total_requests BIGINT NOT NULL DEFAULT 0,
    avg_latency_ms DOUBLE,
    is_manual TINYINT(1) NOT NULL DEFAULT 0,
    proxy_url VARCHAR(500),
    proxy_username VARCHAR(255),
    proxy_password VARCHAR(500),
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    remote_config TEXT,
    config_version INT NOT NULL DEFAULT 0,
    hardware_info TEXT,
    estimated_max_concurrency INT,
    tunnel_mode TINYINT(1) NOT NULL DEFAULT 0,
    tunnel_connected TINYINT(1) NOT NULL DEFAULT 0,
    tunnel_connected_at BIGINT,
    failed_requests BIGINT NOT NULL DEFAULT 0,
    dns_failures BIGINT NOT NULL DEFAULT 0,
    stream_errors BIGINT NOT NULL DEFAULT 0,
    proxy_metadata TEXT
);

CREATE TABLE IF NOT EXISTS proxy_node_events (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    node_id VARCHAR(64) NOT NULL,
    event_type VARCHAR(64) NOT NULL,
    detail VARCHAR(500),
    created_at BIGINT NOT NULL
);
CREATE TABLE IF NOT EXISTS wallets (
    id VARCHAR(64) PRIMARY KEY,
    user_id VARCHAR(64),
    api_key_id VARCHAR(64),
    balance DOUBLE NOT NULL DEFAULT 0,
    gift_balance DOUBLE NOT NULL DEFAULT 0,
    limit_mode VARCHAR(64) NOT NULL DEFAULT 'finite',
    currency VARCHAR(16) NOT NULL DEFAULT 'USD',
    status VARCHAR(64) NOT NULL DEFAULT 'active',
    total_recharged DOUBLE NOT NULL DEFAULT 0,
    total_consumed DOUBLE NOT NULL DEFAULT 0,
    total_refunded DOUBLE NOT NULL DEFAULT 0,
    total_adjusted DOUBLE NOT NULL DEFAULT 0,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY wallets_user_id_key (user_id),
    UNIQUE KEY wallets_api_key_id_key (api_key_id),
    KEY wallets_api_key_id_idx (api_key_id),
    KEY wallets_user_id_idx (user_id)
);

CREATE TABLE IF NOT EXISTS wallet_transactions (
    id VARCHAR(64) PRIMARY KEY,
    wallet_id VARCHAR(64) NOT NULL,
    category VARCHAR(64) NOT NULL,
    reason_code VARCHAR(64) NOT NULL,
    amount DOUBLE NOT NULL,
    balance_before DOUBLE NOT NULL,
    balance_after DOUBLE NOT NULL,
    recharge_balance_before DOUBLE NOT NULL,
    recharge_balance_after DOUBLE NOT NULL,
    gift_balance_before DOUBLE NOT NULL,
    gift_balance_after DOUBLE NOT NULL,
    link_type VARCHAR(64),
    link_id VARCHAR(128),
    operator_id VARCHAR(64),
    description TEXT,
    created_at BIGINT NOT NULL,
    KEY idx_wallet_tx_wallet_created (wallet_id, created_at),
    KEY idx_wallet_tx_category_created (category, created_at),
    KEY idx_wallet_tx_reason_created (reason_code, created_at),
    KEY idx_wallet_tx_link (link_type, link_id),
    KEY ix_wallet_transactions_operator_id (operator_id)
);

CREATE TABLE IF NOT EXISTS wallet_daily_usage_ledgers (
    id VARCHAR(64) PRIMARY KEY,
    wallet_id VARCHAR(64) NOT NULL,
    billing_date VARCHAR(16) NOT NULL,
    billing_timezone VARCHAR(64) NOT NULL,
    total_cost_usd DOUBLE NOT NULL DEFAULT 0,
    total_requests BIGINT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    cache_creation_tokens BIGINT NOT NULL DEFAULT 0,
    cache_read_tokens BIGINT NOT NULL DEFAULT 0,
    first_finalized_at BIGINT,
    last_finalized_at BIGINT,
    aggregated_at BIGINT NOT NULL,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    KEY idx_wallet_daily_usage_wallet_date (wallet_id, billing_timezone, billing_date)
);

CREATE TABLE IF NOT EXISTS payment_orders (
    id VARCHAR(64) PRIMARY KEY,
    order_no VARCHAR(128) NOT NULL,
    wallet_id VARCHAR(64) NOT NULL,
    user_id VARCHAR(64),
    amount_usd DOUBLE NOT NULL,
    pay_amount DOUBLE,
    pay_currency VARCHAR(16),
    exchange_rate DOUBLE,
    refunded_amount_usd DOUBLE NOT NULL DEFAULT 0,
    refundable_amount_usd DOUBLE NOT NULL DEFAULT 0,
    payment_method VARCHAR(64) NOT NULL,
    gateway_order_id VARCHAR(128),
    gateway_response TEXT,
    status VARCHAR(64) NOT NULL DEFAULT 'pending',
    created_at BIGINT NOT NULL,
    paid_at BIGINT,
    credited_at BIGINT,
    expires_at BIGINT,
    UNIQUE KEY uq_payment_orders_order_no (order_no),
    KEY idx_payment_orders_wallet_created (wallet_id, created_at),
    KEY idx_payment_orders_user_created (user_id, created_at),
    KEY idx_payment_orders_status (status),
    KEY idx_payment_orders_gateway_order_id (gateway_order_id)
);

CREATE TABLE IF NOT EXISTS payment_callbacks (
    id VARCHAR(64) PRIMARY KEY,
    payment_order_id VARCHAR(64),
    payment_method VARCHAR(64) NOT NULL,
    callback_key VARCHAR(128) NOT NULL,
    order_no VARCHAR(128),
    gateway_order_id VARCHAR(128),
    payload_hash VARCHAR(128),
    signature_valid TINYINT(1) NOT NULL DEFAULT 0,
    status VARCHAR(64) NOT NULL DEFAULT 'received',
    payload TEXT,
    error_message TEXT,
    created_at BIGINT NOT NULL,
    processed_at BIGINT,
    UNIQUE KEY uq_payment_callbacks_callback_key (callback_key),
    KEY idx_payment_callbacks_order (order_no),
    KEY idx_payment_callbacks_gateway_order (gateway_order_id),
    KEY idx_payment_callbacks_created (created_at),
    KEY ix_payment_callbacks_payment_order_id (payment_order_id)
);

CREATE TABLE IF NOT EXISTS refund_requests (
    id VARCHAR(64) PRIMARY KEY,
    refund_no VARCHAR(128) NOT NULL,
    wallet_id VARCHAR(64) NOT NULL,
    user_id VARCHAR(64),
    payment_order_id VARCHAR(64),
    source_type VARCHAR(64) NOT NULL,
    source_id VARCHAR(128),
    refund_mode VARCHAR(64) NOT NULL,
    amount_usd DOUBLE NOT NULL,
    status VARCHAR(64) NOT NULL DEFAULT 'pending_approval',
    reason TEXT,
    requested_by VARCHAR(64),
    approved_by VARCHAR(64),
    processed_by VARCHAR(64),
    gateway_refund_id VARCHAR(128),
    payout_method VARCHAR(64),
    payout_reference VARCHAR(255),
    payout_proof TEXT,
    failure_reason TEXT,
    idempotency_key VARCHAR(128),
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    processed_at BIGINT,
    completed_at BIGINT,
    UNIQUE KEY uq_refund_requests_refund_no (refund_no),
    UNIQUE KEY uq_refund_requests_idempotency_key (idempotency_key),
    KEY idx_refund_wallet_created (wallet_id, created_at),
    KEY idx_refund_user_created (user_id, created_at),
    KEY idx_refund_status (status),
    KEY ix_refund_requests_payment_order_id (payment_order_id),
    KEY ix_refund_requests_requested_by (requested_by),
    KEY ix_refund_requests_approved_by (approved_by),
    KEY ix_refund_requests_processed_by (processed_by)
);

CREATE TABLE IF NOT EXISTS redeem_code_batches (
    id VARCHAR(64) PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    amount_usd DOUBLE NOT NULL,
    currency VARCHAR(16) NOT NULL DEFAULT 'USD',
    balance_bucket VARCHAR(64) NOT NULL DEFAULT 'gift',
    total_count INT NOT NULL,
    status VARCHAR(64) NOT NULL DEFAULT 'active',
    description TEXT,
    created_by VARCHAR(64),
    expires_at BIGINT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    KEY idx_redeem_code_batches_status (status, created_at)
);

CREATE TABLE IF NOT EXISTS redeem_codes (
    id VARCHAR(64) PRIMARY KEY,
    batch_id VARCHAR(64) NOT NULL,
    code_hash VARCHAR(128) NOT NULL,
    code_prefix VARCHAR(16) NOT NULL,
    code_suffix VARCHAR(16) NOT NULL,
    status VARCHAR(64) NOT NULL DEFAULT 'active',
    redeemed_by_user_id VARCHAR(64),
    redeemed_wallet_id VARCHAR(64),
    redeemed_payment_order_id VARCHAR(64),
    redeemed_at BIGINT,
    disabled_by VARCHAR(64),
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_redeem_codes_code_hash (code_hash),
    KEY idx_redeem_codes_batch_created (batch_id, created_at),
    KEY idx_redeem_codes_status (status, updated_at),
    KEY idx_redeem_codes_redeemed_user (redeemed_by_user_id, redeemed_at),
    KEY idx_redeem_codes_redeemed_order (redeemed_payment_order_id)
);
CREATE TABLE IF NOT EXISTS `usage` (
    request_id VARCHAR(128) PRIMARY KEY,
    id VARCHAR(128),
    user_id VARCHAR(64),
    api_key_id VARCHAR(64),
    provider_name VARCHAR(255) NOT NULL DEFAULT 'unknown',
    model VARCHAR(255) NOT NULL DEFAULT 'unknown',
    target_model VARCHAR(255),
    provider_id VARCHAR(64),
    provider_endpoint_id VARCHAR(64),
    provider_api_key_id VARCHAR(64),
    request_type VARCHAR(64),
    api_format VARCHAR(64),
    api_family VARCHAR(64),
    endpoint_kind VARCHAR(64),
    endpoint_api_format VARCHAR(64),
    provider_api_family VARCHAR(64),
    provider_endpoint_kind VARCHAR(64),
    has_format_conversion TINYINT(1) NOT NULL DEFAULT 0,
    is_stream TINYINT(1) NOT NULL DEFAULT 0,
    upstream_is_stream TINYINT(1),
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    total_tokens BIGINT NOT NULL DEFAULT 0,
    cache_creation_input_tokens BIGINT NOT NULL DEFAULT 0,
    cache_creation_ephemeral_5m_input_tokens BIGINT NOT NULL DEFAULT 0,
    cache_creation_ephemeral_1h_input_tokens BIGINT NOT NULL DEFAULT 0,
    cache_read_input_tokens BIGINT NOT NULL DEFAULT 0,
    cache_creation_cost_usd DOUBLE NOT NULL DEFAULT 0,
    cache_read_cost_usd DOUBLE NOT NULL DEFAULT 0,
    output_price_per_1m DOUBLE,
    status_code INT,
    error_message TEXT,
    error_category VARCHAR(255),
    response_time_ms BIGINT,
    first_byte_time_ms BIGINT,
    wallet_id VARCHAR(64),
    status VARCHAR(64) NOT NULL DEFAULT 'completed',
    billing_status VARCHAR(64) NOT NULL DEFAULT 'pending',
    total_cost_usd DOUBLE NOT NULL DEFAULT 0,
    actual_total_cost_usd DOUBLE NOT NULL DEFAULT 0,
    request_metadata TEXT,
    candidate_id VARCHAR(128),
    candidate_index BIGINT,
    key_name VARCHAR(255),
    planner_kind VARCHAR(64),
    route_family VARCHAR(128),
    route_kind VARCHAR(128),
    execution_path VARCHAR(128),
    local_execution_runtime_miss_reason VARCHAR(255),
    wallet_balance_before DOUBLE,
    wallet_balance_after DOUBLE,
    wallet_recharge_balance_before DOUBLE,
    wallet_recharge_balance_after DOUBLE,
    wallet_gift_balance_before DOUBLE,
    wallet_gift_balance_after DOUBLE,
    finalized_at BIGINT,
    created_at_unix_ms BIGINT NOT NULL DEFAULT 0,
    updated_at_unix_secs BIGINT NOT NULL DEFAULT 0,
    KEY usage_api_key_id_idx (api_key_id),
    KEY usage_billing_status_idx (billing_status),
    KEY usage_created_at_idx (created_at_unix_ms),
    KEY usage_provider_api_key_id_idx (provider_api_key_id),
    KEY usage_provider_id_idx (provider_id),
    KEY usage_request_id_idx (request_id),
    KEY usage_user_id_idx (user_id),
    KEY usage_wallet_id_idx (wallet_id)
);

CREATE TABLE IF NOT EXISTS usage_settlement_snapshots (
    request_id VARCHAR(128) PRIMARY KEY,
    billing_status VARCHAR(64) NOT NULL,
    wallet_id VARCHAR(64),
    wallet_balance_before DOUBLE,
    wallet_balance_after DOUBLE,
    wallet_recharge_balance_before DOUBLE,
    wallet_recharge_balance_after DOUBLE,
    wallet_gift_balance_before DOUBLE,
    wallet_gift_balance_after DOUBLE,
    provider_monthly_used_usd DOUBLE,
    finalized_at BIGINT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    KEY usage_settlement_snapshots_billing_status_idx (billing_status),
    KEY usage_settlement_snapshots_wallet_id_idx (wallet_id)
);


CREATE TABLE IF NOT EXISTS stats_hourly (
    id VARCHAR(64) PRIMARY KEY,
    hour_utc BIGINT NOT NULL,
    total_requests BIGINT NOT NULL DEFAULT 0,
    success_requests BIGINT NOT NULL DEFAULT 0,
    error_requests BIGINT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    cache_creation_tokens BIGINT NOT NULL DEFAULT 0,
    cache_read_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost DOUBLE NOT NULL DEFAULT 0,
    actual_total_cost DOUBLE NOT NULL DEFAULT 0,
    avg_response_time_ms DOUBLE NOT NULL DEFAULT 0,
    is_complete TINYINT(1) NOT NULL DEFAULT 0,
    aggregated_at BIGINT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_stats_hourly_hour (hour_utc)
);

CREATE TABLE IF NOT EXISTS stats_hourly_user (
    id VARCHAR(64) PRIMARY KEY,
    hour_utc BIGINT NOT NULL,
    user_id VARCHAR(64) NOT NULL,
    total_requests BIGINT NOT NULL DEFAULT 0,
    success_requests BIGINT NOT NULL DEFAULT 0,
    error_requests BIGINT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost DOUBLE NOT NULL DEFAULT 0,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_stats_hourly_user (hour_utc, user_id)
);

CREATE TABLE IF NOT EXISTS stats_hourly_user_model (
    id VARCHAR(64) PRIMARY KEY,
    hour_utc BIGINT NOT NULL,
    user_id VARCHAR(64) NOT NULL,
    model VARCHAR(255) NOT NULL,
    total_requests BIGINT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost DOUBLE NOT NULL DEFAULT 0,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_stats_hourly_user_model (hour_utc, user_id, model)
);

CREATE TABLE IF NOT EXISTS stats_hourly_model (
    id VARCHAR(64) PRIMARY KEY,
    hour_utc BIGINT NOT NULL,
    model VARCHAR(255) NOT NULL,
    total_requests BIGINT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost DOUBLE NOT NULL DEFAULT 0,
    avg_response_time_ms DOUBLE NOT NULL DEFAULT 0,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_stats_hourly_model (hour_utc, model)
);

CREATE TABLE IF NOT EXISTS stats_hourly_provider (
    id VARCHAR(64) PRIMARY KEY,
    hour_utc BIGINT NOT NULL,
    provider_name VARCHAR(255) NOT NULL,
    total_requests BIGINT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost DOUBLE NOT NULL DEFAULT 0,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_stats_hourly_provider (hour_utc, provider_name)
);

CREATE TABLE IF NOT EXISTS stats_daily (
    id VARCHAR(64) PRIMARY KEY,
    `date` BIGINT NOT NULL,
    total_requests BIGINT NOT NULL DEFAULT 0,
    success_requests BIGINT NOT NULL DEFAULT 0,
    error_requests BIGINT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    cache_creation_tokens BIGINT NOT NULL DEFAULT 0,
    cache_read_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost DOUBLE NOT NULL DEFAULT 0,
    actual_total_cost DOUBLE NOT NULL DEFAULT 0,
    avg_response_time_ms DOUBLE NOT NULL DEFAULT 0,
    fallback_count BIGINT NOT NULL DEFAULT 0,
    unique_models BIGINT NOT NULL DEFAULT 0,
    unique_providers BIGINT NOT NULL DEFAULT 0,
    is_complete TINYINT(1) NOT NULL DEFAULT 0,
    aggregated_at BIGINT,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_stats_daily_date (`date`)
);

CREATE TABLE IF NOT EXISTS stats_daily_model (
    id VARCHAR(64) PRIMARY KEY,
    `date` BIGINT NOT NULL,
    model VARCHAR(255) NOT NULL,
    total_requests BIGINT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    cache_creation_tokens BIGINT NOT NULL DEFAULT 0,
    cache_read_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost DOUBLE NOT NULL DEFAULT 0,
    avg_response_time_ms DOUBLE NOT NULL DEFAULT 0,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_stats_daily_model (`date`, model)
);

CREATE TABLE IF NOT EXISTS stats_daily_provider (
    id VARCHAR(64) PRIMARY KEY,
    `date` BIGINT NOT NULL,
    provider_name VARCHAR(255) NOT NULL,
    total_requests BIGINT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    cache_creation_tokens BIGINT NOT NULL DEFAULT 0,
    cache_read_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost DOUBLE NOT NULL DEFAULT 0,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_stats_daily_provider (`date`, provider_name)
);

CREATE TABLE IF NOT EXISTS stats_daily_api_key (
    id VARCHAR(64) PRIMARY KEY,
    api_key_id VARCHAR(64) NOT NULL,
    `date` BIGINT NOT NULL,
    total_requests BIGINT NOT NULL DEFAULT 0,
    success_requests BIGINT NOT NULL DEFAULT 0,
    error_requests BIGINT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    cache_creation_tokens BIGINT NOT NULL DEFAULT 0,
    cache_read_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost DOUBLE NOT NULL DEFAULT 0,
    api_key_name VARCHAR(255),
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_stats_daily_api_key (`date`, api_key_id)
);

CREATE TABLE IF NOT EXISTS stats_daily_error (
    id VARCHAR(64) PRIMARY KEY,
    `date` BIGINT NOT NULL,
    error_category VARCHAR(255) NOT NULL,
    provider_name VARCHAR(255),
    model VARCHAR(255),
    count BIGINT NOT NULL DEFAULT 0,
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_stats_daily_error (`date`, error_category, provider_name, model)
);

CREATE TABLE IF NOT EXISTS stats_user_daily (
    id VARCHAR(64) PRIMARY KEY,
    user_id VARCHAR(64) NOT NULL,
    `date` BIGINT NOT NULL,
    total_requests BIGINT NOT NULL DEFAULT 0,
    success_requests BIGINT NOT NULL DEFAULT 0,
    error_requests BIGINT NOT NULL DEFAULT 0,
    input_tokens BIGINT NOT NULL DEFAULT 0,
    output_tokens BIGINT NOT NULL DEFAULT 0,
    cache_creation_tokens BIGINT NOT NULL DEFAULT 0,
    cache_read_tokens BIGINT NOT NULL DEFAULT 0,
    total_cost DOUBLE NOT NULL DEFAULT 0,
    username VARCHAR(255),
    created_at BIGINT NOT NULL,
    updated_at BIGINT NOT NULL,
    UNIQUE KEY uq_stats_user_daily (`date`, user_id)
);
