"""DB-backed Codegen provider, model, credential, and execution metadata."""
from __future__ import annotations

from datetime import datetime
from typing import Optional
from uuid import UUID, uuid4

from sqlalchemy import Boolean, ForeignKey, Integer, String, Text, UniqueConstraint
from sqlalchemy.dialects.postgresql import JSONB, UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.sql import func
from sqlalchemy.types import DateTime

from src.core.database import Base


class CodegenProvider(Base):
    __tablename__ = "codegen_providers"

    id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
    slug: Mapped[str] = mapped_column(String(64), unique=True, nullable=False)
    display_name: Mapped[str] = mapped_column(String(120), nullable=False)
    adapter_key: Mapped[str] = mapped_column(String(64), nullable=False)
    executable: Mapped[str] = mapped_column(String(128), nullable=False)
    enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, server_default="true")
    available_p2hs: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, server_default="true")
    available_byok: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, server_default="true")
    install_strategy_key: Mapped[str] = mapped_column(String(80), nullable=False)
    metadata_json: Mapped[dict] = mapped_column(JSONB, nullable=False, default=dict, server_default="{}")
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())


class CodegenModel(Base):
    __tablename__ = "codegen_models"

    id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
    provider_id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("codegen_providers.id", ondelete="CASCADE"), nullable=False)
    model_key: Mapped[str] = mapped_column(String(120), nullable=False)
    display_name: Mapped[str] = mapped_column(String(160), nullable=False)
    cli_model_value: Mapped[str] = mapped_column(String(160), nullable=False)
    enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, server_default="true")
    available_p2hs: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, server_default="true")
    available_byok: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, server_default="true")
    is_default: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, server_default="false")
    is_recommended: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, server_default="false")
    context_window: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    capabilities_json: Mapped[dict] = mapped_column(JSONB, nullable=False, default=dict, server_default="{}")
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())

    __table_args__ = (UniqueConstraint("provider_id", "model_key", name="uq_codegen_model_provider_key"),)


class CodegenCredential(Base):
    __tablename__ = "codegen_credentials"

    id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
    workspace_id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("workspaces.id", ondelete="CASCADE"), nullable=False)
    provider_id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("codegen_providers.id", ondelete="RESTRICT"), nullable=False)
    label: Mapped[str] = mapped_column(String(120), nullable=False)
    encrypted_secret: Mapped[str] = mapped_column(Text, nullable=False)
    secret_version: Mapped[int] = mapped_column(Integer, nullable=False, default=1, server_default="1")
    status: Mapped[str] = mapped_column(String(24), nullable=False, default="active", server_default="active")
    last_four: Mapped[Optional[str]] = mapped_column(String(4), nullable=True)
    validation_status: Mapped[str] = mapped_column(String(24), nullable=False, default="unvalidated", server_default="unvalidated")
    validated_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
    created_by: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
    revoked_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)


class CodegenWorkspaceConfig(Base):
    __tablename__ = "codegen_workspace_configs"

    id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
    workspace_id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("workspaces.id", ondelete="CASCADE"), nullable=False, unique=True)
    provider_id: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), ForeignKey("codegen_providers.id", ondelete="SET NULL"), nullable=True)
    model_id: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), ForeignKey("codegen_models.id", ondelete="SET NULL"), nullable=True)
    credential_id: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), ForeignKey("codegen_credentials.id", ondelete="SET NULL"), nullable=True)
    funding_source: Mapped[str] = mapped_column(String(16), nullable=False, default="p2hs", server_default="p2hs")
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())


class CodegenProjectConfig(Base):
    __tablename__ = "codegen_project_configs"

    id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
    project_id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("projects.id", ondelete="CASCADE"), nullable=False, unique=True)
    provider_id: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), ForeignKey("codegen_providers.id", ondelete="SET NULL"), nullable=True)
    model_id: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), ForeignKey("codegen_models.id", ondelete="SET NULL"), nullable=True)
    credential_id: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), ForeignKey("codegen_credentials.id", ondelete="SET NULL"), nullable=True)
    funding_source: Mapped[Optional[str]] = mapped_column(String(16), nullable=True)
    updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())


class CodegenExecutionSnapshot(Base):
    __tablename__ = "codegen_execution_snapshots"

    run_id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("codegen_runs.id", ondelete="CASCADE"), primary_key=True)
    provider_slug: Mapped[str] = mapped_column(String(64), nullable=False)
    model_key: Mapped[str] = mapped_column(String(120), nullable=False)
    funding_source: Mapped[str] = mapped_column(String(16), nullable=False)
    credential_id: Mapped[Optional[UUID]] = mapped_column(PGUUID(as_uuid=True), nullable=True)
    adapter_version: Mapped[Optional[str]] = mapped_column(String(64), nullable=True)
    cli_version: Mapped[Optional[str]] = mapped_column(String(128), nullable=True)
    execution_provider: Mapped[str] = mapped_column(String(32), nullable=False, default="github", server_default="github")
    execution_target: Mapped[str] = mapped_column(String(64), nullable=False, default="hosted", server_default="hosted")
    runner_class: Mapped[str] = mapped_column(String(64), nullable=False, default="linux_standard", server_default="linux_standard")
    execution_config_version: Mapped[str] = mapped_column(String(32), nullable=False, default="1", server_default="1")
    pricing_version: Mapped[str] = mapped_column(String(96), nullable=False, default="github-linux-2026-01", server_default="github-linux-2026-01")
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())


class CodegenUsage(Base):
    __tablename__ = "codegen_usage"

    id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
    run_id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), ForeignKey("codegen_runs.id", ondelete="CASCADE"), nullable=False, unique=True)
    funding_source: Mapped[str] = mapped_column(String(16), nullable=False)
    usage_source: Mapped[str] = mapped_column(String(24), nullable=False, default="unavailable", server_default="unavailable")
    input_tokens: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    output_tokens: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    cached_tokens: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    estimated_cost: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    wallet_debit: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0")
    provider_request_id: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    execution_seconds: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    execution_provider: Mapped[Optional[str]] = mapped_column(String(32), nullable=True)
    execution_target: Mapped[Optional[str]] = mapped_column(String(64), nullable=True)
    runner_class: Mapped[Optional[str]] = mapped_column(String(64), nullable=True)
    provider_cost_microusd: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    execution_credits: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0")
    execution_pricing_version: Mapped[Optional[str]] = mapped_column(String(96), nullable=True)
    metadata_json: Mapped[dict] = mapped_column(JSONB, nullable=False, default=dict, server_default="{}")
    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
