import json

from fastapi import APIRouter, Depends
from pydantic import BaseModel, Field
from sqlalchemy import select
from sqlalchemy.orm import Session

from app.core.database import get_db
from app.core.models import PlatformAIConfig
from app.core.security import require_platform_admin

router = APIRouter(
    prefix="/api/platform/ai",
    tags=["platform-ai"],
    dependencies=[Depends(require_platform_admin)],
)


class PlatformAIConfigUpdate(BaseModel):
    provider: str = Field(min_length=1, max_length=50)
    api_key: str | None = None
    endpoint: str | None = Field(default=None, max_length=500)
    default_model: str | None = Field(default=None, max_length=100)
    enabled_models: list[str] | None = None
    input_credit_rate: int = Field(default=0, ge=0)
    output_credit_rate: int = Field(default=0, ge=0)
    per_request_credit_cap: int = Field(default=0, ge=0)
    enabled: bool = False


class PlatformAIConfigResponse(BaseModel):
    provider: str
    endpoint: str | None
    default_model: str | None
    enabled_models: list[str] | None
    input_credit_rate: int
    output_credit_rate: int
    per_request_credit_cap: int
    enabled: bool
    api_key_configured: bool


def _json_value(value: str | None, default, expected_type: type):
    if not value:
        return default
    try:
        decoded = json.loads(value)
    except (TypeError, ValueError):
        return default
    if not isinstance(decoded, expected_type):
        return default
    if expected_type is list and not all(isinstance(item, str) for item in decoded):
        return default
    return decoded


def get_platform_ai_config(db: Session) -> dict:
    row = db.execute(
        select(PlatformAIConfig).where(PlatformAIConfig.config_key == "platform")
    ).scalar_one_or_none()
    rates = _json_value(row.credit_rates if row else None, {}, dict)
    return {
        "provider": row.provider if row else "openai",
        "api_key": row.api_key if row else None,
        "endpoint": row.endpoint if row else None,
        "default_model": row.default_model if row else None,
        "enabled_models": _json_value(row.enabled_models if row else None, None, list),
        "input_credit_rate": rates.get("input", 0),
        "output_credit_rate": rates.get("output", 0),
        "per_request_credit_cap": row.per_request_credit_cap if row else 0,
        "enabled": row.enabled if row else False,
    }


def _public_config(db: Session) -> PlatformAIConfigResponse:
    config = get_platform_ai_config(db)
    api_key = config.pop("api_key")
    return PlatformAIConfigResponse(**config, api_key_configured=bool(api_key))


@router.get("/config", response_model=PlatformAIConfigResponse)
def read_platform_ai_config(db: Session = Depends(get_db)):
    return _public_config(db)


@router.put("/config", response_model=PlatformAIConfigResponse)
def update_platform_ai_config(data: PlatformAIConfigUpdate, db: Session = Depends(get_db)):
    row = db.execute(
        select(PlatformAIConfig).where(PlatformAIConfig.config_key == "platform")
    ).scalar_one_or_none()
    if row is None:
        row = PlatformAIConfig(config_key="platform")
        db.add(row)

    row.provider = data.provider
    if data.api_key and data.api_key.strip():
        row.api_key = data.api_key.strip()
    row.endpoint = data.endpoint
    row.default_model = data.default_model
    row.enabled_models = json.dumps(data.enabled_models) if data.enabled_models is not None else None
    row.credit_rates = json.dumps({"input": data.input_credit_rate, "output": data.output_credit_rate})
    row.per_request_credit_cap = data.per_request_credit_cap
    row.enabled = data.enabled
    db.commit()
    return _public_config(db)
