from __future__ import annotations

import secrets
import uuid
from dataclasses import dataclass
from datetime import datetime, timedelta, timezone
from typing import Any


@dataclass
class PairingToken:
    token: str
    expires_at: str
    qr_payload: dict[str, Any]

    def to_dict(self) -> dict[str, Any]:
        return {
            "token": self.token,
            "expires_at": self.expires_at,
            "qr_url": f"niannian://pair?token={self.token}",
            "qr_payload": self.qr_payload,
        }


class PairingService:
    """Bridge 配对 — 内存 token 存储（MVP）。"""

    def __init__(self, *, ttl_minutes: int = 10) -> None:
        self._ttl = ttl_minutes
        self._tokens: dict[str, datetime] = {}
        self._devices: dict[str, dict[str, Any]] = {}

    def create_pairing(self, *, host: str = "http://127.0.0.1:18765") -> PairingToken:
        token = secrets.token_urlsafe(16)
        expires = datetime.now(timezone.utc) + timedelta(minutes=self._ttl)
        self._tokens[token] = expires
        payload = {"host": host, "token": token}
        return PairingToken(token=token, expires_at=expires.isoformat(), qr_payload=payload)

    def verify(self, token: str) -> bool:
        exp = self._tokens.get(token)
        if exp is None:
            return False
        if datetime.now(timezone.utc) > exp:
            self._tokens.pop(token, None)
            return False
        return True

    def register_device(self, token: str, *, name: str = "mobile") -> dict[str, Any]:
        if not self.verify(token):
            raise ValueError("invalid or expired pairing token")
        device_id = uuid.uuid4().hex[:12]
        device_token = secrets.token_urlsafe(24)
        self._devices[device_id] = {"name": name, "device_token": device_token}
        self._tokens.pop(token, None)
        return {"device_id": device_id, "device_token": device_token}

    def list_devices(self) -> list[dict[str, Any]]:
        return [{"id": k, **v} for k, v in self._devices.items()]
