# backend/app/routers/connectors.py — phase-13 외부 연동 API
# prefix 없음. main.py 에서 include_router(prefix="/api").
import uuid

from fastapi import APIRouter, Depends, File, HTTPException, UploadFile
from fastapi.responses import RedirectResponse
from sqlmodel import Session

from ..config import get_settings
from ..connectors import oauth as oauthlib
from ..connectors.registry import ConnectorRegistry
from ..db import get_session
from ..models import ConnectorAccount, ConnectorAccountLog, ConnState
from ..schemas import ConnectorStatusOut, ImportResultOut, OAuthStartOut, SyncResultOut

router = APIRouter()


@router.get("/connectors", response_model=list[ConnectorStatusOut])
def list_connectors(domain: str | None = None, s: Session = Depends(get_session)):
    rows = ConnectorRegistry.accounts(s, domain)
    return [ConnectorStatusOut.from_account(a, ConnectorRegistry.mode_for(a.domain)) for a in rows]


@router.post("/connectors/{account_id}/sync", response_model=SyncResultOut)
def sync_one(account_id: str, full: bool = False, s: Session = Depends(get_session)):
    a = s.get(ConnectorAccount, account_id)
    if not a:
        raise HTTPException(404, "connector account not found")
    res = ConnectorRegistry.get(s, a).sync(s, full=full)
    return SyncResultOut(**res.__dict__)


@router.post("/connectors/sync-all", response_model=list[SyncResultOut])
def sync_all(s: Session = Depends(get_session)):
    out = []
    for a in ConnectorRegistry.accounts(s):
        if a.state == ConnState.disconnected:  # 연결 안 된 계정은 건너뜀
            continue
        out.append(SyncResultOut(**ConnectorRegistry.get(s, a).sync(s).__dict__))
    return out


# ── OAuth ──
@router.get("/connectors/oauth/start", response_model=OAuthStartOut)
def oauth_start(
    domain: str, provider: str, redirect_after: str = "/life", s: Session = Depends(get_session)
):
    cfg = get_settings()
    if provider in ("gmail", "google_calendar") and not cfg.google_client_id:
        raise HTTPException(400, "google_client_id 미설정 — real 연동 비활성")
    if provider == "notion" and not cfg.notion_client_id:
        raise HTTPException(400, "notion_client_id 미설정 — real 연동 비활성")
    url = oauthlib.start_oauth(s, domain, provider, redirect_after)
    return OAuthStartOut(authorize_url=url)


@router.get("/connectors/oauth/callback")
def oauth_callback(code: str, state: str, s: Session = Depends(get_session)):
    origin = get_settings().frontend_origin
    try:
        acct = oauthlib.finish_oauth(s, code, state)
    except Exception:
        return RedirectResponse(url=f"{origin}/life?connect=error")
    try:
        ConnectorRegistry.get(s, acct).sync(s, full=True)  # 연결 직후 1회 초기 sync
    except Exception:
        pass
    return RedirectResponse(url=f"{origin}/life?connect=ok&domain={acct.domain.value}")


@router.post("/connectors/{account_id}/disconnect", response_model=ConnectorStatusOut)
def disconnect(account_id: str, s: Session = Depends(get_session)):
    a = s.get(ConnectorAccount, account_id)
    if not a:
        raise HTTPException(404, "not found")
    a.state = ConnState.disconnected
    a.token_enc = ""
    a.last_label = "연결 안 됨"
    s.add(a)
    s.add(
        ConnectorAccountLog(
            id="cl-" + uuid.uuid4().hex[:8],
            account_id=a.id,
            action="disconnected",
            detail="사용자 해제",
        )
    )
    s.commit()
    return ConnectorStatusOut.from_account(a, ConnectorRegistry.mode_for(a.domain))


# ── 로컬 우선: 수동 임포트(CSV / .ics / HealthKit export) ──
@router.post("/connectors/{account_id}/import", response_model=ImportResultOut)
async def import_file(
    account_id: str, file: UploadFile = File(...), s: Session = Depends(get_session)
):
    a = s.get(ConnectorAccount, account_id)
    if not a:
        raise HTTPException(404, "not found")
    conn = ConnectorRegistry.get(s, a)
    if not hasattr(conn, "import_bytes"):
        raise HTTPException(400, "이 커넥터는 파일 임포트를 지원하지 않아요")
    content = await file.read()
    res = conn.import_bytes(s, content, filename=file.filename or "")
    return ImportResultOut(**res)
