-- =============================================
-- 四川路桥 Maas 算力平台 - 数据库初始化脚本
-- PostgreSQL 15+
-- =============================================

-- 创建 schema
CREATE SCHEMA IF NOT EXISTS aigcspace;

-- =============================================
-- 1. 用户表
-- =============================================
CREATE TABLE aigcspace.users (
    id VARCHAR(50) NOT NULL PRIMARY KEY,
    username VARCHAR(50) UNIQUE,
    password_hash VARCHAR(255),
    nickname VARCHAR(100) NOT NULL,
    phone VARCHAR(20),
    email VARCHAR(255),
    avatar TEXT,
    real_name VARCHAR(100),
    id_card VARCHAR(18),
    is_verified VARCHAR(20) NOT NULL DEFAULT 'unverified',
    verified_at TIMESTAMP WITHOUT TIME ZONE,
    apikey VARCHAR(255),
    registration_date DATE,
    status VARCHAR(20) NOT NULL DEFAULT 'active',
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
    updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
);

CREATE INDEX idx_users_username ON aigcspace.users(username);
CREATE INDEX idx_users_phone ON aigcspace.users(phone);
CREATE INDEX idx_users_email ON aigcspace.users(email);
CREATE INDEX idx_users_status ON aigcspace.users(status);

-- =============================================
-- 2. 管理员表
-- =============================================
CREATE TABLE aigcspace.admin_users (
    id SERIAL NOT NULL PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    password_hash VARCHAR(255) NOT NULL,
    nickname VARCHAR(100),
    status VARCHAR(20) NOT NULL DEFAULT 'active',
    last_login_at TIMESTAMP WITHOUT TIME ZONE,
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(),
    updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
);

CREATE TABLE aigcspace.admin_login_attempt (
    id SERIAL NOT NULL PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    success BOOLEAN NOT NULL,
    ip_address VARCHAR(50),
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
);

CREATE TABLE aigcspace.operation_log (
    id BIGSERIAL NOT NULL PRIMARY KEY,
    admin_id INTEGER NOT NULL REFERENCES aigcspace.admin_users(id),
    operation_type VARCHAR(50) NOT NULL,
    module VARCHAR(50) NOT NULL,
    target_id VARCHAR(100),
    detail JSON,
    ip_address VARCHAR(50),
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
);

CREATE INDEX idx_operation_log_admin_id ON aigcspace.operation_log(admin_id);
CREATE INDEX idx_operation_log_created_at ON aigcspace.operation_log(created_at);

-- =============================================
-- 3. 模型表
-- =============================================
CREATE TABLE aigcspace.models_new (
    id SERIAL NOT NULL PRIMARY KEY,
    model_code VARCHAR(200) NOT NULL UNIQUE,
    description TEXT,
    display_tags TEXT[],
    input_modalities TEXT[],
    output_modalities TEXT[],
    features JSONB,
    rate_limits JSONB,
    tool_call_prices JSONB,
    raw_prices JSONB,
    source_url TEXT,
    crawled_at TIMESTAMP WITHOUT TIME ZONE,
    categories INTEGER[] NOT NULL DEFAULT '{0}',
    display_name VARCHAR(255),
    img TEXT,
    supplier VARCHAR(100) NOT NULL DEFAULT '',
    tag1 VARCHAR(100),
    tag2 VARCHAR(100),
    keywords TEXT,
    custom_description TEXT,
    is_featured BOOLEAN NOT NULL DEFAULT false,
    is_show_enabled BOOLEAN NOT NULL DEFAULT true,
    is_api_enabled BOOLEAN NOT NULL DEFAULT false,
    is_search BOOLEAN NOT NULL DEFAULT false,
    is_thinking BOOLEAN NOT NULL DEFAULT false,
    source_keys TEXT[],
    normalized_keys TEXT[],
    group_name VARCHAR(100),
    encrypted_api_key TEXT,
    -- 本地模型字段
    is_local BOOLEAN NOT NULL DEFAULT false,
    user_id VARCHAR(50) REFERENCES aigcspace.users(id),
    base_url VARCHAR(500),
    local_api_key VARCHAR(500),
    visibility VARCHAR(20) DEFAULT 'user',
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
    updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
);

CREATE INDEX idx_models_new_categories ON aigcspace.models_new USING GIN(categories);
CREATE INDEX idx_models_new_supplier ON aigcspace.models_new(supplier);
CREATE INDEX idx_models_new_is_local ON aigcspace.models_new(is_local);
CREATE INDEX idx_models_new_user_id ON aigcspace.models_new(user_id);
CREATE INDEX idx_models_new_is_show_enabled ON aigcspace.models_new(is_show_enabled);
CREATE INDEX idx_models_new_is_api_enabled ON aigcspace.models_new(is_api_enabled);

CREATE TABLE aigcspace.model_price_new (
    id SERIAL NOT NULL PRIMARY KEY,
    model_code VARCHAR(200) NOT NULL,
    label VARCHAR(200) NOT NULL DEFAULT 'default',
    tier_min NUMERIC(20, 2),
    tier_max NUMERIC(20, 2),
    tier_unit VARCHAR(50),
    input_price_original NUMERIC(20, 8) NOT NULL DEFAULT 0,
    output_price_original NUMERIC(20, 8) NOT NULL DEFAULT 0,
    discount_rate NUMERIC(5, 4) NOT NULL DEFAULT 1.0,
    discount_label VARCHAR(20),
    input_price_discounted NUMERIC(20, 8) NOT NULL DEFAULT 0,
    output_price_discounted NUMERIC(20, 8) NOT NULL DEFAULT 0,
    currency VARCHAR(10) NOT NULL DEFAULT 'CNY',
    unit VARCHAR(100) NOT NULL DEFAULT '千tokens',
    display_multiplier INTEGER NOT NULL DEFAULT 1,
    source_url TEXT,
    crawled_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now(),
    is_active BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
    updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
);

CREATE INDEX idx_model_price_new_model_code ON aigcspace.model_price_new(model_code);

CREATE TABLE aigcspace.model_category (
    id SERIAL NOT NULL PRIMARY KEY,
    code INTEGER NOT NULL UNIQUE,
    name VARCHAR(50) NOT NULL,
    description VARCHAR(200),
    sort_order INTEGER NOT NULL DEFAULT 0,
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
);

-- 初始化模型分类
INSERT INTO aigcspace.model_category (code, name, sort_order) VALUES
(0, '语言模型', 0),
(1, '多模态', 1),
(2, 'TTS', 2),
(3, 'STT', 3),
(4, '文生图', 4),
(5, '生视频', 5),
(6, '图生图', 6),
(7, 'Embedding', 7),
(8, 'Rerank', 8);

-- =============================================
-- 4. API 密钥表
-- =============================================
CREATE TABLE aigcspace.platform_api_key (
    id SERIAL NOT NULL PRIMARY KEY,
    user_id VARCHAR(50) NOT NULL REFERENCES aigcspace.users(id) ON DELETE CASCADE,
    api_key VARCHAR(100) NOT NULL,
    api_key_prefix VARCHAR(20) NOT NULL,
    name VARCHAR(100),
    status VARCHAR(20) NOT NULL DEFAULT 'active',
    key_type VARCHAR(20) NOT NULL DEFAULT 'public',
    last_used_at TIMESTAMP WITHOUT TIME ZONE,
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
    updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
);

CREATE INDEX idx_platform_api_key_user_id ON aigcspace.platform_api_key(user_id);
CREATE INDEX idx_platform_api_key_api_key ON aigcspace.platform_api_key(api_key);
CREATE INDEX idx_platform_api_key_status ON aigcspace.platform_api_key(status);
CREATE INDEX idx_platform_api_key_key_type ON aigcspace.platform_api_key(key_type);

-- =============================================
-- 5. API 调用日志表
-- =============================================
CREATE TABLE aigcspace.api_call_log (
    id BIGSERIAL NOT NULL PRIMARY KEY,
    user_id VARCHAR(50) NOT NULL REFERENCES aigcspace.users(id) ON DELETE CASCADE,
    api_key_id INTEGER REFERENCES aigcspace.platform_api_key(id) ON DELETE SET NULL,
    model_id INTEGER,
    model_name VARCHAR(255) NOT NULL,
    is_local BOOLEAN NOT NULL DEFAULT false,
    input_tokens INTEGER NOT NULL DEFAULT 0,
    output_tokens INTEGER NOT NULL DEFAULT 0,
    bill NUMERIC(12, 4) NOT NULL DEFAULT 0,
    status VARCHAR(20) NOT NULL DEFAULT 'success',
    error_message TEXT,
    request_ip VARCHAR(50),
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL
);

CREATE INDEX idx_api_call_log_user_id ON aigcspace.api_call_log(user_id);
CREATE INDEX idx_api_call_log_api_key_id ON aigcspace.api_call_log(api_key_id);
CREATE INDEX idx_api_call_log_model_id ON aigcspace.api_call_log(model_id);
CREATE INDEX idx_api_call_log_created_at ON aigcspace.api_call_log(created_at);
CREATE INDEX idx_api_call_log_is_local ON aigcspace.api_call_log(is_local);
CREATE INDEX idx_api_call_log_model_name ON aigcspace.api_call_log(model_name);

-- =============================================
-- 6. 用户本地模型权限表
-- =============================================
CREATE TABLE aigcspace.user_local_model_permission (
    id SERIAL NOT NULL PRIMARY KEY,
    user_id VARCHAR(50) NOT NULL REFERENCES aigcspace.users(id) ON DELETE CASCADE,
    model_id INTEGER NOT NULL REFERENCES aigcspace.models_new(id) ON DELETE CASCADE,
    has_access BOOLEAN NOT NULL DEFAULT true,
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
    updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now() NOT NULL,
    UNIQUE(user_id, model_id)
);

-- =============================================
-- 7. 系统配置表
-- =============================================
CREATE TABLE aigcspace.system_config (
    id SERIAL NOT NULL PRIMARY KEY,
    config_key VARCHAR(100) NOT NULL UNIQUE,
    config_value TEXT NOT NULL DEFAULT '',
    config_type VARCHAR(20) NOT NULL DEFAULT 'string',
    category VARCHAR(50) NOT NULL DEFAULT 'basic',
    description VARCHAR(500),
    updated_by INTEGER REFERENCES aigcspace.admin_users(id),
    updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now(),
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
);

CREATE TABLE aigcspace.config_history (
    id SERIAL NOT NULL PRIMARY KEY,
    config_key VARCHAR(100) NOT NULL,
    old_value TEXT,
    new_value TEXT NOT NULL,
    updated_by INTEGER REFERENCES aigcspace.admin_users(id),
    updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
);

-- =============================================
-- 8. 日志表
-- =============================================
CREATE TABLE aigcspace.login_log (
    id SERIAL NOT NULL PRIMARY KEY,
    user_id VARCHAR(50) NOT NULL,
    username VARCHAR(100),
    user_type VARCHAR(20) NOT NULL DEFAULT 'user',
    login_result VARCHAR(20) NOT NULL,
    fail_reason VARCHAR(200),
    ip_address VARCHAR(50),
    user_agent TEXT,
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
);

CREATE INDEX idx_login_log_user_id ON aigcspace.login_log(user_id);
CREATE INDEX idx_login_log_created_at ON aigcspace.login_log(created_at);

CREATE TABLE aigcspace.api_log (
    id SERIAL NOT NULL PRIMARY KEY,
    user_id VARCHAR(50),
    username VARCHAR(100),
    phone VARCHAR(20),
    module VARCHAR(50),
    api_path VARCHAR(500) NOT NULL,
    request_method VARCHAR(10) NOT NULL,
    request_params JSON,
    response_status INTEGER,
    response_time INTEGER,
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
);

CREATE INDEX idx_api_log_user_id ON aigcspace.api_log(user_id);
CREATE INDEX idx_api_log_created_at ON aigcspace.api_log(created_at);
CREATE INDEX idx_api_log_module ON aigcspace.api_log(module);

-- =============================================
-- 9. 初始化默认管理员（密码: admin123 的 SHA256）
-- =============================================
INSERT INTO aigcspace.admin_users (username, password_hash, nickname, status)
VALUES ('admin', '240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9', '超级管理员', 'active')
ON CONFLICT (username) DO NOTHING;

-- =============================================
-- 10. 初始化系统配置
-- =============================================
INSERT INTO aigcspace.system_config (config_key, config_value, config_type, category, description) VALUES
('system_name', '四川路桥Maas算力平台', 'string', 'basic', '平台名称'),
('system_logo', '', 'string', 'basic', '平台Logo URL'),
('icp_number', '', 'string', 'basic', 'ICP备案号'),
('contact_email', '', 'string', 'basic', '联系邮箱'),
('enable_local_models', 'true', 'boolean', 'feature', '是否启用私域模型功能'),
('enable_registration', 'true', 'boolean', 'feature', '是否开放注册'),
('max_api_keys_per_user', '5', 'number', 'limit', '每用户最大API Key数量')
ON CONFLICT (config_key) DO NOTHING;
