import os
import tempfile
import uuid

from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException
from fastapi.responses import FileResponse
from loguru import logger
from starlette.background import BackgroundTask

from app.core.deps import get_current_user
from app.core.response import success_response
from app.services.tts_service import TTSService

from .schemas import GenerateRequest, VoicePreviewRequest
from .task_store import create_task, get_task, list_tasks
from .workflow import process_video_generation, get_lipsync_health, get_voiceclone_health
from .service import list_generated_videos, delete_generated_video


router = APIRouter()

PREVIEW_TEXTS = {
    "zh-CN": "你好，请选择你喜欢的音色吧。",
    "en-US": "Hello, please choose the voice you like.",
    "ja-JP": "こんにちは。お好きな音声を選んでください。",
    "ko-KR": "안녕하세요, 마음에 드는 음성을 선택해 주세요.",
    "fr-FR": "Bonjour, veuillez choisir la voix que vous preferez.",
    "de-DE": "Hallo, bitte waehlen Sie die Stimme, die Ihnen gefaellt.",
    "es-ES": "Hola, por favor elige la voz que mas te guste.",
    "ru-RU": "Zdravstvuite, pozhaluista, vyberite golos, kotoryi vam nravitsya.",
    "it-IT": "Ciao, scegli la voce che preferisci.",
    "pt-BR": "Ola, escolha a voz de que voce mais gosta.",
}


def _cleanup_temp_file(path: str) -> None:
    try:
        os.unlink(path)
    except Exception:
        pass


def _get_voice_locale(voice: str) -> str:
    parts = voice.split("-")
    if len(parts) >= 2:
        return f"{parts[0]}-{parts[1]}"
    return "zh-CN"


def _get_preview_text_for_voice(voice: str) -> str:
    locale = _get_voice_locale(voice)
    return PREVIEW_TEXTS.get(locale, PREVIEW_TEXTS["zh-CN"])


async def _render_voice_preview(voice: str, text: str) -> FileResponse:
    tmp_file = tempfile.NamedTemporaryFile(prefix="voice_preview_", suffix=".mp3", delete=False)
    output_path = tmp_file.name
    tmp_file.close()

    tts = TTSService()
    try:
        await tts.generate_audio(text=text, voice=voice, output_path=output_path)
    except Exception as e:
        _cleanup_temp_file(output_path)
        logger.error(f"音色试听生成失败: voice={voice}, error={e}")
        raise HTTPException(status_code=500, detail="音色试听生成失败，请稍后重试")

    return FileResponse(
        path=output_path,
        media_type="audio/mpeg",
        filename="voice_preview.mp3",
        background=BackgroundTask(_cleanup_temp_file, output_path),
    )


@router.post("/generate")
async def generate_video(
    req: GenerateRequest,
    background_tasks: BackgroundTasks,
    current_user: dict = Depends(get_current_user)
):
    user_id = current_user["id"]
    task_id = str(uuid.uuid4())
    create_task(task_id, user_id)
    background_tasks.add_task(process_video_generation, task_id, req, user_id)
    return success_response({"task_id": task_id})


@router.get("/tasks/{task_id}")
async def get_task_status(task_id: str, current_user: dict = Depends(get_current_user)):
    task = get_task(task_id)
    # 验证任务归属：只能查看自己的任务
    if task.get("status") != "not_found" and task.get("user_id") != current_user["id"]:
        return success_response({"status": "not_found"})
    return success_response(task)


@router.get("/tasks")
async def list_tasks_view(current_user: dict = Depends(get_current_user)):
    # 只返回当前用户的任务
    all_tasks = list_tasks()
    user_tasks = [t for t in all_tasks if t.get("user_id") == current_user["id"]]
    return success_response({"tasks": user_tasks})


@router.get("/lipsync/health")
async def lipsync_health():
    return success_response(await get_lipsync_health())


@router.get("/voiceclone/health")
async def voiceclone_health():
    return success_response(await get_voiceclone_health())


@router.get("/generated")
async def list_generated(current_user: dict = Depends(get_current_user)):
    return success_response(await list_generated_videos(current_user["id"]))


@router.delete("/generated/{video_id}")
async def delete_generated(video_id: str, current_user: dict = Depends(get_current_user)):
    result = await delete_generated_video(current_user["id"], video_id)
    return success_response(result, message="视频已删除")


@router.post("/voice-preview")
async def preview_voice_post(
    req: VoicePreviewRequest,
    current_user: dict = Depends(get_current_user),
):
    # 复用统一鉴权，接口本身不需要 user_id
    _ = current_user

    voice = req.voice.strip()
    text = req.text.strip()

    if not voice:
        raise HTTPException(status_code=400, detail="voice 不能为空")
    if not text:
        raise HTTPException(status_code=400, detail="text 不能为空")

    return await _render_voice_preview(voice=voice, text=text)


@router.get("/voice-preview")
async def preview_voice_get(
    voice: str,
    current_user: dict = Depends(get_current_user),
):
    # 复用统一鉴权，接口本身不需要 user_id
    _ = current_user

    voice_value = voice.strip()
    if not voice_value:
        raise HTTPException(status_code=400, detail="voice 不能为空")

    text = _get_preview_text_for_voice(voice_value)
    return await _render_voice_preview(voice=voice_value, text=text)
