"""Logs + Usage: project_log_config, project_log_drains, workspace_usage_snapshots.

Revision ID: 042
Revises: 041
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

revision = "042"
down_revision = "041"
branch_labels = None
depends_on = None


def upgrade() -> None:
    # project_log_config — one row per project (upsert pattern)
    op.create_table(
        "project_log_config",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column(
            "project_id",
            postgresql.UUID(as_uuid=True),
            sa.ForeignKey("projects.id", ondelete="CASCADE"),
            nullable=False,
            unique=True,
        ),
        sa.Column("debug_enabled", sa.Boolean, nullable=False, server_default="false"),
        sa.Column("debug_expires_at", sa.DateTime(timezone=True), nullable=True),
        # Minimum level forwarded to log drains (debug | info | warn | error | fatal)
        sa.Column("min_drain_level", sa.String(10), nullable=False, server_default="info"),
        # Retention in days — derived from plan, stored here for Cloud to enforce
        sa.Column("retention_days", sa.Integer, nullable=False, server_default="1"),
        sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
    )
    op.create_index("ix_project_log_config_project_id", "project_log_config", ["project_id"])

    # project_log_drains — one or more drain destinations per project
    op.create_table(
        "project_log_drains",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column(
            "project_id",
            postgresql.UUID(as_uuid=True),
            sa.ForeignKey("projects.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column("name", sa.String(64), nullable=False),
        # logtail | datadog | custom_webhook
        sa.Column("destination_type", sa.String(32), nullable=False),
        sa.Column("endpoint_url", sa.Text, nullable=False),
        # Fernet-encrypted auth secret — never returned raw, never sent to Cloud
        sa.Column("auth_secret_enc", sa.Text, nullable=True),
        # debug | info | warn | error | fatal
        sa.Column("min_level", sa.String(10), nullable=False, server_default="info"),
        # null = all sources; JSONB list otherwise
        sa.Column("sources_json", postgresql.JSONB, nullable=True),
        sa.Column("enabled", sa.Boolean, nullable=False, server_default="true"),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
        sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
        sa.UniqueConstraint("project_id", "name", name="uq_log_drain_project_name"),
    )
    op.create_index("ix_project_log_drains_project_id", "project_log_drains", ["project_id"])

    # workspace_usage_snapshots — daily workspace-aggregate for billing
    op.create_table(
        "workspace_usage_snapshots",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column(
            "workspace_id",
            postgresql.UUID(as_uuid=True),
            sa.ForeignKey("workspaces.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column("snapshot_date", sa.Date, nullable=False),
        # All metrics summed across projects
        sa.Column("cpu_minutes", sa.Numeric(12, 4), nullable=False, server_default="0"),
        sa.Column("db_reads", sa.BigInteger, nullable=False, server_default="0"),
        sa.Column("db_writes", sa.BigInteger, nullable=False, server_default="0"),
        sa.Column("storage_gb", sa.Numeric(12, 6), nullable=False, server_default="0"),
        sa.Column("cdn_gb", sa.Numeric(12, 6), nullable=False, server_default="0"),
        sa.Column("auth_users_active", sa.Integer, nullable=False, server_default="0"),
        sa.Column("ai_embed_tokens", sa.BigInteger, nullable=False, server_default="0"),
        sa.Column("ai_completion_tokens", sa.BigInteger, nullable=False, server_default="0"),
        sa.Column("ai_searches", sa.BigInteger, nullable=False, server_default="0"),
        sa.Column("job_executions", sa.BigInteger, nullable=False, server_default="0"),
        sa.Column("realtime_minutes", sa.Numeric(12, 4), nullable=False, server_default="0"),
        sa.Column("ext_queries", sa.BigInteger, nullable=False, server_default="0"),
        sa.Column("credits_consumed", sa.Numeric(12, 6), nullable=False, server_default="0"),
        # Credit exhaustion notification dedup
        sa.Column("notified_50pct_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("notified_90pct_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.func.now()),
        sa.UniqueConstraint(
            "workspace_id", "snapshot_date",
            name="uq_workspace_usage_snapshot_date",
        ),
    )
    op.create_index(
        "ix_workspace_usage_snapshots_workspace_id",
        "workspace_usage_snapshots",
        ["workspace_id"],
    )
    op.create_index(
        "ix_workspace_usage_snapshots_date",
        "workspace_usage_snapshots",
        ["snapshot_date"],
    )


def downgrade() -> None:
    op.drop_table("workspace_usage_snapshots")
    op.drop_table("project_log_drains")
    op.drop_table("project_log_config")
