# -*- coding: utf-8 -*-
"""콘텐츠(피드)·생성·좋아요·업장명 자동완성 라우터."""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession

from .. import credit_service, jobs
from ..config import GEMINI_API_KEY, SCENARIO_ENGINE, settings
from ..content_sync import sync_output
from ..database import get_session
from ..deps import Pagination, get_current_user, get_current_user_optional, get_pagination
from ..models import Comment, Content, Like, User
from ..schemas import CreateReq, FeedItem, PaginatedResponse

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


@router.get("/feed", response_model=PaginatedResponse[FeedItem])
async def feed(
    sort: str = Query("latest", pattern="^(latest|likes)$"),
    owner: str | None = None,                       # "me" → 내 채널
    pg: Pagination = Depends(get_pagination),
    user: User | None = Depends(get_current_user_optional),
    session: AsyncSession = Depends(get_session),
):
    like_ct = (
        select(func.count(Like.id)).where(Like.content_id == Content.id).correlate(Content).scalar_subquery()
    )
    cmt_ct = (
        select(func.count(Comment.id))
        .where(Comment.content_id == Content.id, Comment.is_deleted == False)  # noqa: E712
        .correlate(Content).scalar_subquery()
    )
    where = [Content.is_deleted == False]  # noqa: E712
    if owner == "me":
        if user is None:
            return PaginatedResponse.create([], 0, pg.page, pg.page_size)
        where.append(Content.owner_uuid == user.user_uuid)

    total = (await session.execute(select(func.count(Content.id)).where(*where))).scalar() or 0
    order = like_ct.desc() if sort == "likes" else Content.created_at.desc()
    rows = (
        await session.execute(
            select(Content, like_ct.label("likes"), cmt_ct.label("comments"))
            .where(*where).order_by(order).offset(pg.offset).limit(pg.page_size)
        )
    ).all()

    ids = [r[0].id for r in rows]
    liked = set()
    if user and ids:
        liked = set(
            (await session.execute(
                select(Like.content_id).where(Like.user_uuid == user.user_uuid, Like.content_id.in_(ids))
            )).scalars().all()
        )

    items = [
        FeedItem(
            id=c.id, sc=c.scenario, title=c.title, video=c.video, views=c.views,
            likes=likes, comments=comments, liked=(c.id in liked),
            mine=(user is not None and c.owner_uuid == user.user_uuid), createdAt=c.created_at,
        )
        for (c, likes, comments) in rows
    ]
    return PaginatedResponse.create(items, total, pg.page, pg.page_size)


@router.post("/create")
async def create(body: CreateReq, user: User = Depends(get_current_user)):
    if body.scenario not in SCENARIO_ENGINE:
        raise HTTPException(400, f"알 수 없는 시나리오: {body.scenario}")
    if not body.input.strip():
        raise HTTPException(400, "링크 또는 업장명이 필요합니다.")
    if not GEMINI_API_KEY:
        raise HTTPException(400, "GEMINI_API_KEY 가 설정되지 않았습니다.")
    if user.credits < settings.CREDITS_PER_VIDEO:
        raise HTTPException(402, "크레딧이 부족합니다. 충전 후 이용해주세요.")
    job = jobs.create_job(
        body.scenario, body.input.strip(),
        max(4, min(20, body.scenes)), max(20, min(90, body.seconds)),
        owner_uuid=user.user_uuid,
    )
    return {"id": job["id"], "status": job["status"]}


@router.get("/jobs/{jid}")
async def job_status(jid: str, session: AsyncSession = Depends(get_session)):
    job = jobs.get_job(jid)
    if not job:
        raise HTTPException(404, "잡을 찾을 수 없습니다.")
    # 완료 최초 관측 시 1회: 새 output → content 삽입 + 크레딧 차감
    if job["status"] == "done" and not job["finalized"]:
        job["finalized"] = True
        try:
            await sync_output(session, owner_uuid=job["owner_uuid"])
            if job["owner_uuid"]:
                await credit_service.deduct(session, job["owner_uuid"], settings.CREDITS_PER_VIDEO, reason="영상 생성")
                await session.commit()
        except Exception:
            await session.rollback()
    return {
        "id": job["id"], "status": job["status"], "step": job["step"],
        "stepName": jobs.STEP_NAMES[job["step"] - 1] if job["step"] else "대기 중",
        "output": job["output"], "error": job["error"], "log": job["log"][-15:],
    }


@router.post("/content/{cid}/like")
async def toggle_like(cid: str, user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session)):
    c = await session.get(Content, cid)
    if c is None or c.is_deleted:
        raise HTTPException(404, "콘텐츠를 찾을 수 없습니다.")
    existing = (
        await session.execute(select(Like).where(Like.content_id == cid, Like.user_uuid == user.user_uuid))
    ).scalar_one_or_none()
    if existing:
        await session.delete(existing)
        liked = False
    else:
        session.add(Like(content_id=cid, user_uuid=user.user_uuid))
        liked = True
    await session.commit()
    count = (await session.execute(select(func.count(Like.id)).where(Like.content_id == cid))).scalar() or 0
    return {"liked": liked, "likes": count}


@router.get("/search/place", tags=["Search"])
async def search_place(query: str = Query(..., min_length=2)):
    """업장명 → 네이버 지도 후보 목록(동명 업장 주소로 구분). 키 불필요(Playwright).

    각 후보는 place_url 을 가지므로, 프론트에서 하나를 고르면 그 URL 로 정확히 크롤링한다.
    """
    from .. import place_service
    items = await place_service.search_places(query, limit=8)
    return {"query": query, "count": len(items), "items": items}
