"""G-10: PWA Push 알림 구독 관리 API."""
from __future__ import annotations

import logging
import os
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from core.auth import get_current_user, require_admin_role
from database import get_db
from models import PushSubscription, User

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/push", tags=["push"])


class SubscribeRequest(BaseModel):
    endpoint:   str
    p256dh:     str
    auth:       str
    user_agent: Optional[str] = None


class PushTestRequest(BaseModel):
    title: str = "GUARDiA 테스트"
    body:  str = "푸시 알림 테스트입니다."
    url:   str = "/"


@router.get("/vapid-key")
async def get_vapid_public_key():
    """VAPID 공개키 반환 (프론트엔드 subscribe 시 사용)."""
    key = os.getenv("VAPID_PUBLIC_KEY", "")
    return {"vapid_public_key": key, "configured": bool(key)}


@router.post("/subscribe", status_code=201)
async def subscribe(
    body: SubscribeRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """PWA Push 구독 등록."""
    # 기존 구독 확인 (endpoint 기준)
    existing = (await db.execute(
        select(PushSubscription).where(PushSubscription.endpoint == body.endpoint)
    )).scalars().first()

    if existing:
        # 갱신
        existing.user_id    = current_user.id
        existing.p256dh     = body.p256dh
        existing.auth       = body.auth
        existing.user_agent = body.user_agent
    else:
        sub = PushSubscription(
            user_id    = current_user.id,
            endpoint   = body.endpoint,
            p256dh     = body.p256dh,
            auth       = body.auth,
            user_agent = body.user_agent,
        )
        db.add(sub)

    await db.commit()
    return {"message": "푸시 구독이 등록되었습니다.", "user": current_user.username}


@router.delete("/subscribe", status_code=204)
async def unsubscribe(
    endpoint: str,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """PWA Push 구독 해제."""
    sub = (await db.execute(
        select(PushSubscription).where(
            PushSubscription.endpoint == endpoint,
            PushSubscription.user_id == current_user.id,
        )
    )).scalars().first()

    if sub:
        await db.delete(sub)
        await db.commit()


@router.post("/test")
async def test_push(
    body: PushTestRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_admin_role),
):
    """테스트 푸시 전송 (ADMIN 전용 — 자신의 구독에 발송)."""
    subs = (await db.execute(
        select(PushSubscription).where(PushSubscription.user_id == current_user.id)
    )).scalars().all()

    if not subs:
        raise HTTPException(404, "등록된 푸시 구독이 없습니다. 먼저 구독을 등록하세요.")

    from core.push_notify import send_push
    sent = 0
    for sub in subs:
        ok = await send_push(
            subscription_info={
                "endpoint": sub.endpoint,
                "keys": {"p256dh": sub.p256dh, "auth": sub.auth},
            },
            title=body.title,
            body=body.body,
            url=body.url,
        )
        if ok:
            sent += 1

    return {
        "message":     f"테스트 푸시 전송 완료 (성공: {sent}/{len(subs)})",
        "sent":        sent,
        "total_subs":  len(subs),
    }
