# -*- coding: utf-8 -*-
"""generator/output 스캔 → content 테이블 upsert.

디스크의 완성 mp4 와 DB 를 잇는다. 시작 시 + 잡 완료 시 호출.
"""
import re

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from .config import OUTPUT_DIR, ENGINE_SCENARIO
from .database import SessionLocal
from .models import Content

_TITLE_RE = re.compile(r"\[제목\]\s*(.+)")


def _title(job_dir) -> str:
    txt = job_dir / "narration.txt"
    if txt.exists():
        for line in txt.read_text(encoding="utf-8", errors="ignore").splitlines():
            m = _TITLE_RE.match(line.strip())
            if m:
                return m.group(1).strip()
    return job_dir.name


def _scan() -> list[dict]:
    rows = []
    if not OUTPUT_DIR.is_dir():
        return rows
    for engine, sc in ENGINE_SCENARIO.items():
        d = OUTPUT_DIR / engine
        if not d.is_dir():
            continue
        for job in d.iterdir():
            if not job.is_dir():
                continue
            mp4s = sorted(job.glob("*.mp4"))
            if not mp4s:
                continue
            rel = mp4s[0].relative_to(OUTPUT_DIR).as_posix()
            rows.append({"id": job.name, "sc": sc, "title": _title(job), "video": f"/videos/{rel}"})
    return rows


async def sync_output(session: AsyncSession | None = None, owner_uuid: str | None = None) -> int:
    """새 output 폴더를 content 로 삽입. 삽입 개수 반환."""
    own = session is None
    session = session or SessionLocal()
    try:
        existing = set((await session.execute(select(Content.id))).scalars().all())
        added = 0
        for r in _scan():
            if r["id"] in existing:
                continue
            session.add(Content(
                id=r["id"], scenario=r["sc"], title=r["title"], video=r["video"],
                owner_uuid=owner_uuid,
            ))
            added += 1
        if added:
            await session.commit()
        return added
    finally:
        if own:
            await session.close()
