from __future__ import annotations

from alembic import op
import sqlalchemy as sa

revision = "0001_initial_schema"
down_revision = None
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.create_table(
        "sys_user",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("phone", sa.String(length=20), nullable=False),
        sa.Column("name", sa.String(length=50), nullable=False),
        sa.Column("nickname", sa.String(length=50), nullable=True),
        sa.Column("status", sa.Integer(), nullable=False),
        sa.Column("daily_chat_limit", sa.Integer(), nullable=False),
        sa.Column("daily_chat_used", sa.Integer(), nullable=False),
        sa.Column("effective_at", sa.DateTime(), nullable=True),
        sa.Column("expired_at", sa.DateTime(), nullable=True),
        sa.Column("last_login_at", sa.DateTime(), nullable=True),
        sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.Column("is_deleted", sa.Integer(), nullable=False),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_sys_user_phone", "sys_user", ["phone"], unique=True)

    op.create_table(
        "sys_role",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("code", sa.String(length=50), nullable=False),
        sa.Column("name", sa.String(length=50), nullable=False),
        sa.Column("remark", sa.String(length=255), nullable=True),
        sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_sys_role_code", "sys_role", ["code"], unique=True)

    op.create_table(
        "sys_admin",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("username", sa.String(length=50), nullable=False),
        sa.Column("password", sa.String(length=255), nullable=False),
        sa.Column("name", sa.String(length=50), nullable=False),
        sa.Column("role_id", sa.BigInteger(), nullable=True),
        sa.Column("status", sa.Integer(), nullable=False),
        sa.Column("last_login_at", sa.DateTime(), nullable=True),
        sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.ForeignKeyConstraint(["role_id"], ["sys_role.id"]),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_sys_admin_username", "sys_admin", ["username"], unique=True)

    op.create_table(
        "sys_knowledge",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("name", sa.String(length=100), nullable=False),
        sa.Column("feishu_space_id", sa.String(length=100), nullable=False),
        sa.Column("feishu_node_id", sa.String(length=100), nullable=False),
        sa.Column("status", sa.Integer(), nullable=False),
        sa.Column("remark", sa.String(length=255), nullable=True),
        sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.PrimaryKeyConstraint("id"),
    )

    op.create_table(
        "sys_user_kb",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("user_id", sa.BigInteger(), nullable=False),
        sa.Column("knowledge_id", sa.BigInteger(), nullable=False),
        sa.Column("effective_at", sa.DateTime(), nullable=True),
        sa.Column("expired_at", sa.DateTime(), nullable=True),
        sa.Column("created_by", sa.BigInteger(), nullable=True),
        sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.ForeignKeyConstraint(["knowledge_id"], ["sys_knowledge.id"]),
        sa.ForeignKeyConstraint(["user_id"], ["sys_user.id"]),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_sys_user_kb_user_id", "sys_user_kb", ["user_id"])
    op.create_index("ix_sys_user_kb_knowledge_id", "sys_user_kb", ["knowledge_id"])

    op.create_table(
        "sys_model",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("provider", sa.String(length=50), nullable=False),
        sa.Column("model_name", sa.String(length=100), nullable=False),
        sa.Column("api_url", sa.String(length=255), nullable=False),
        sa.Column("api_key", sa.Text(), nullable=False),
        sa.Column("temperature", sa.Numeric(4, 2), nullable=True),
        sa.Column("max_token", sa.Integer(), nullable=True),
        sa.Column("timeout_second", sa.Integer(), nullable=False),
        sa.Column("enabled", sa.Integer(), nullable=False),
        sa.PrimaryKeyConstraint("id"),
    )

    op.create_table(
        "sys_prompt",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("prompt_content", sa.Text(), nullable=False),
        sa.Column("updated_by", sa.BigInteger(), nullable=True),
        sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.PrimaryKeyConstraint("id"),
    )

    op.create_table(
        "sys_system_config",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("config_key", sa.String(length=100), nullable=False),
        sa.Column("config_value", sa.Text(), nullable=False),
        sa.Column("description", sa.String(length=255), nullable=True),
        sa.Column("updated_by", sa.BigInteger(), nullable=True),
        sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_sys_system_config_config_key", "sys_system_config", ["config_key"], unique=True)

    op.create_table(
        "sys_chat_session",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("user_id", sa.BigInteger(), nullable=False),
        sa.Column("title", sa.String(length=100), nullable=False),
        sa.Column("message_count", sa.Integer(), nullable=False),
        sa.Column("last_message_at", sa.DateTime(), nullable=True),
        sa.Column("is_deleted", sa.Integer(), nullable=False),
        sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.Column("updated_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.ForeignKeyConstraint(["user_id"], ["sys_user.id"]),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_sys_chat_session_user_id", "sys_chat_session", ["user_id"])

    op.create_table(
        "sys_chat_message",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("session_id", sa.BigInteger(), nullable=False),
        sa.Column("user_id", sa.BigInteger(), nullable=False),
        sa.Column("role", sa.String(length=20), nullable=False),
        sa.Column("content", sa.Text(), nullable=False),
        sa.Column("message_status", sa.String(length=20), nullable=False),
        sa.Column("token_input", sa.Integer(), nullable=True),
        sa.Column("token_output", sa.Integer(), nullable=True),
        sa.Column("response_time_ms", sa.Integer(), nullable=True),
        sa.Column("model_id", sa.BigInteger(), nullable=True),
        sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.ForeignKeyConstraint(["model_id"], ["sys_model.id"]),
        sa.ForeignKeyConstraint(["session_id"], ["sys_chat_session.id"]),
        sa.ForeignKeyConstraint(["user_id"], ["sys_user.id"]),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_sys_chat_message_session_id", "sys_chat_message", ["session_id"])
    op.create_index("ix_sys_chat_message_user_id", "sys_chat_message", ["user_id"])

    op.create_table(
        "sys_ai_request_log",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("session_id", sa.BigInteger(), nullable=True),
        sa.Column("message_id", sa.BigInteger(), nullable=True),
        sa.Column("user_id", sa.BigInteger(), nullable=True),
        sa.Column("model_name", sa.String(length=100), nullable=True),
        sa.Column("prompt", sa.Text(), nullable=True),
        sa.Column("knowledge_ids", sa.String(length=500), nullable=True),
        sa.Column("retrieve_count", sa.Integer(), nullable=False),
        sa.Column("input_token", sa.Integer(), nullable=True),
        sa.Column("output_token", sa.Integer(), nullable=True),
        sa.Column("total_token", sa.Integer(), nullable=True),
        sa.Column("cost_ms", sa.Integer(), nullable=True),
        sa.Column("status", sa.String(length=20), nullable=False),
        sa.Column("error_message", sa.Text(), nullable=True),
        sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_sys_ai_request_log_session_id", "sys_ai_request_log", ["session_id"])
    op.create_index("ix_sys_ai_request_log_message_id", "sys_ai_request_log", ["message_id"])
    op.create_index("ix_sys_ai_request_log_user_id", "sys_ai_request_log", ["user_id"])

    op.create_table(
        "sys_operation_log",
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("admin_id", sa.BigInteger(), nullable=True),
        sa.Column("module", sa.String(length=50), nullable=False),
        sa.Column("action", sa.String(length=50), nullable=False),
        sa.Column("target_id", sa.BigInteger(), nullable=True),
        sa.Column("before_json", sa.Text(), nullable=True),
        sa.Column("after_json", sa.Text(), nullable=True),
        sa.Column("ip", sa.String(length=50), nullable=True),
        sa.Column("result", sa.String(length=20), nullable=False),
        sa.Column("created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("ix_sys_operation_log_admin_id", "sys_operation_log", ["admin_id"])


def downgrade() -> None:
    op.drop_index("ix_sys_operation_log_admin_id", table_name="sys_operation_log")
    op.drop_table("sys_operation_log")
    op.drop_index("ix_sys_ai_request_log_user_id", table_name="sys_ai_request_log")
    op.drop_index("ix_sys_ai_request_log_message_id", table_name="sys_ai_request_log")
    op.drop_index("ix_sys_ai_request_log_session_id", table_name="sys_ai_request_log")
    op.drop_table("sys_ai_request_log")
    op.drop_index("ix_sys_chat_message_user_id", table_name="sys_chat_message")
    op.drop_index("ix_sys_chat_message_session_id", table_name="sys_chat_message")
    op.drop_table("sys_chat_message")
    op.drop_index("ix_sys_chat_session_user_id", table_name="sys_chat_session")
    op.drop_table("sys_chat_session")
    op.drop_index("ix_sys_system_config_config_key", table_name="sys_system_config")
    op.drop_table("sys_system_config")
    op.drop_table("sys_prompt")
    op.drop_table("sys_model")
    op.drop_index("ix_sys_user_kb_knowledge_id", table_name="sys_user_kb")
    op.drop_index("ix_sys_user_kb_user_id", table_name="sys_user_kb")
    op.drop_table("sys_user_kb")
    op.drop_table("sys_knowledge")
    op.drop_index("ix_sys_admin_username", table_name="sys_admin")
    op.drop_table("sys_admin")
    op.drop_index("ix_sys_role_code", table_name="sys_role")
    op.drop_table("sys_role")
    op.drop_index("ix_sys_user_phone", table_name="sys_user")
    op.drop_table("sys_user")
