from fastapi import APIRouter, HTTPException, File, UploadFile
from pydantic import BaseModel
from typing import Optional
from models.schemas import PersonaCreate
from services.personas import (
    get_all_personas,
    get_persona,
    create_persona,
    delete_persona,
    patch_persona,
)

router = APIRouter(prefix="/personas", tags=["personas"])


@router.get("/")
async def list_personas():
    personas = await get_all_personas()
    return [{"persona_id": pid, **data} for pid, data in personas.items()]


@router.get("/{persona_id}")
async def get_one_persona(persona_id: str):
    persona = await get_persona(persona_id)
    if not persona:
        raise HTTPException(status_code=404, detail="Персонаж не найден")
    return {"persona_id": persona_id, **persona}


@router.post("/")
async def create_new_persona(data: PersonaCreate):
    persona = await create_persona(
        persona_id=data.persona_id,
        name=data.name,
        emoji=data.emoji,
        description=data.description,
        prompt=data.prompt,
        sd_enabled=data.sd_enabled,
        lora_name=data.lora_name,
        lora_weight=data.lora_weight,
        appearance_tags=data.appearance_tags,
        personality=data.personality,
        scenario=data.scenario,
        first_mes=data.first_mes,
        mes_example=data.mes_example,
        lorebook_json=data.lorebook_json,
    )
    return {"persona_id": data.persona_id, **persona}


class PersonaPatch(BaseModel):
    name: Optional[str] = None
    emoji: Optional[str] = None
    description: Optional[str] = None
    prompt: Optional[str] = None
    sd_enabled: Optional[bool] = None
    lora_name: Optional[str] = None
    lora_weight: Optional[float] = None
    appearance_tags: Optional[str] = None
    appearance_prose: Optional[str] = None
    personality: Optional[str] = None
    scenario: Optional[str] = None
    first_mes: Optional[str] = None
    mes_example: Optional[str] = None
    lorebook_json: Optional[str] = None
    avatar_path: Optional[str] = None


@router.patch("/{persona_id}")
async def patch_one_persona(persona_id: str, body: PersonaPatch):
    fields = {k: v for k, v in body.model_dump().items() if v is not None}
    ok = await patch_persona(persona_id, fields)
    if not ok:
        raise HTTPException(status_code=400, detail="Нельзя редактировать этого персонажа")
    persona = await get_persona(persona_id)
    if not persona:
        raise HTTPException(status_code=404, detail="Персонаж не найден")
    return {"persona_id": persona_id, **persona}


@router.post("/{persona_id}/avatar")
async def upload_persona_avatar(persona_id: str, file: UploadFile = File(...)):
    # only custom personas editable
    persona = await get_persona(persona_id)
    if not persona:
        raise HTTPException(status_code=404, detail="Персонаж не найден")
    if not persona.get("custom"):
        raise HTTPException(status_code=400, detail="Нельзя менять аватар встроенного персонажа")
    content = await file.read()
    if not content.startswith(b"\x89PNG"):
        raise HTTPException(status_code=400, detail="Нужен PNG")
    from pathlib import Path
    import uuid

    avatars_dir = Path("static/avatars")
    avatars_dir.mkdir(parents=True, exist_ok=True)
    fname = f"persona_{persona_id}_{uuid.uuid4().hex[:8]}.png"
    path = avatars_dir / fname
    path.write_bytes(content)
    rel = f"avatars/{fname}"
    ok = await patch_persona(persona_id, {"avatar_path": rel})
    if not ok:
        raise HTTPException(status_code=400, detail="Нельзя изменить аватар")
    return {"avatar_path": f"/static/{rel}"}


@router.delete("/{persona_id}")
async def remove_persona(persona_id: str):
    if not await delete_persona(persona_id):
        raise HTTPException(status_code=400, detail="Нельзя удалить встроенного персонажа")
    return {"status": "deleted", "persona_id": persona_id}
