# -*- coding: utf-8 -*-
"""SNS 연동 라우터 — 유튜브(Google OAuth + YouTube Data API v3) 실연동.

- 연결: /youtube/connect → Google 동의 URL → 콜백에서 토큰 저장(채널명 포함)
- 업로드: 완성 mp4 를 연동 채널에 resumable 업로드
(castad app/social 패턴 이식)
"""
from fastapi import APIRouter, Depends, HTTPException
from fastapi.responses import RedirectResponse
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from .. import youtube_client
from ..config import OUTPUT_DIR, settings
from ..database import get_session
from ..deps import get_current_user
from ..models import Content, SocialAccount, User
from ..security import create_access_token, decode_token

router = APIRouter(prefix="/api/social", tags=["Social"])
# Google OAuth 앱에 등록된 콜백 경로(prefix 밖)를 그대로 받기 위한 보조 라우터.
compat_router = APIRouter(tags=["Social"])

SUPPORTED = {"youtube"}


@router.get("/config")
async def social_config():
    """플랫폼별 연동 활성(키 설정) 여부. 프론트가 '곧 지원' 배지 판단에 사용."""
    return settings.social_enabled


@router.get("/accounts")
async def list_accounts(user: User = Depends(get_current_user), session: AsyncSession = Depends(get_session)):
    rows = (
        await session.execute(
            select(SocialAccount).where(SocialAccount.user_uuid == user.user_uuid, SocialAccount.is_active == True)  # noqa: E712
        )
    ).scalars().all()
    return [{"id": a.id, "platform": a.platform, "account_name": a.account_name} for a in rows]


@router.get("/youtube/connect")
async def youtube_connect(user: User = Depends(get_current_user)):
    """Google OAuth 동의 URL 반환. state 에 로그인 사용자 토큰을 실어 콜백에서 식별."""
    state = create_access_token(user.user_uuid)   # 짧은 수명 서명 토큰을 state 로 사용
    return {"auth_url": youtube_client.get_authorization_url(state)}


@compat_router.get("/social/oauth/youtube/callback")
async def youtube_callback(code: str, state: str, session: AsyncSession = Depends(get_session)):
    """Google 콜백: state→사용자 식별, 코드→토큰 교환, 채널명 조회 후 계정 upsert."""
    payload = decode_token(state)
    if not payload or not payload.get("sub"):
        raise HTTPException(400, "유효하지 않은 state")
    user_uuid = payload["sub"]

    tokens = await youtube_client.exchange_code(code)
    channel = await youtube_client.get_channel_info(tokens["access_token"])

    acc = (
        await session.execute(
            select(SocialAccount).where(
                SocialAccount.user_uuid == user_uuid, SocialAccount.platform == "youtube"
            )
        )
    ).scalar_one_or_none()
    if acc is None:
        acc = SocialAccount(user_uuid=user_uuid, platform="youtube")
        session.add(acc)
    acc.account_name = channel.get("title") or "내 채널"
    acc.access_token = tokens.get("access_token")
    if tokens.get("refresh_token"):          # Google 은 재동의 때만 refresh 재발급
        acc.refresh_token = tokens["refresh_token"]
    acc.is_active = True
    await session.commit()

    return RedirectResponse(url=f"{settings.FRONTEND_URL}/?tab=channel&connected=youtube", status_code=302)


@router.delete("/{platform}/disconnect")
async def disconnect(platform: str, user: User = Depends(get_current_user),
                     session: AsyncSession = Depends(get_session)):
    acc = (
        await session.execute(
            select(SocialAccount).where(
                SocialAccount.user_uuid == user.user_uuid, SocialAccount.platform == platform
            )
        )
    ).scalar_one_or_none()
    if acc is None:
        raise HTTPException(404, "연동된 계정이 없습니다.")
    acc.is_active = False
    await session.commit()
    return {"ok": True}


def _video_file_path(content: Content):
    """Content.video(/videos/...) → 디스크 실제 경로(OUTPUT_DIR 기준)."""
    if not content.video:
        return None
    rel = content.video.removeprefix("/videos/")
    return OUTPUT_DIR / rel


@router.post("/upload/{platform}/{content_id}")
async def upload(platform: str, content_id: str, user: User = Depends(get_current_user),
                 session: AsyncSession = Depends(get_session)):
    if platform != "youtube":
        raise HTTPException(400, f"지원하지 않는 플랫폼: {platform}")
    content = await session.get(Content, content_id)
    if content is None or not content.video:
        raise HTTPException(404, "업로드할 영상을 찾을 수 없습니다.")
    acc = (
        await session.execute(
            select(SocialAccount).where(
                SocialAccount.user_uuid == user.user_uuid, SocialAccount.platform == "youtube",
                SocialAccount.is_active == True,  # noqa: E712
            )
        )
    ).scalar_one_or_none()
    if acc is None:
        raise HTTPException(400, "유튜브 계정을 먼저 연동해주세요.")

    path = _video_file_path(content)
    if path is None or not path.exists():
        raise HTTPException(404, "영상 파일을 찾을 수 없습니다.")

    access_token = acc.access_token
    desc = f"{content.title}\n\n#썰박스 로 만든 병맛 역사 홍보 쇼츠"
    try:
        result = await youtube_client.upload_video(str(path), access_token, content.title, desc)
    except HTTPException as e:
        # 401 이면 refresh 로 재시도
        if e.status_code in (401, 403) and acc.refresh_token:
            access_token = await youtube_client.refresh_access_token(acc.refresh_token)
            acc.access_token = access_token
            await session.commit()
            result = await youtube_client.upload_video(str(path), access_token, content.title, desc)
        else:
            raise
    return {"ok": True, "platform": "youtube", **result}
