import asyncio
import time
from enum import Enum
from typing import Optional, Any


class EGovStatus(str, Enum):
    IDLE        = "idle"
    STARTING    = "starting"
    WAITING_MFA = "waiting_mfa"
    LOGGED_IN   = "logged_in"
    DOWNLOADING = "downloading"
    ERROR       = "error"


class EGovState:
    def __init__(self):
        self.status: EGovStatus       = EGovStatus.IDLE
        self.message: str             = ""
        self.mfa_event: asyncio.Event = asyncio.Event()
        self.mfa_code: Optional[str]  = None
        self.screenshot_b64: Optional[str] = None
        self.last_download: Optional[dict] = None  # {filename, path, size}

        # ブラウザセッション（Playwright 方式, 後方互換用）
        self._playwright: Optional[Any] = None
        self._browser:    Optional[Any] = None
        self._context:    Optional[Any] = None
        self._page:       Optional[Any] = None

        # ── OAuth2 / e-Gov API 方式 ──────────────────────────────
        self.access_token:     Optional[str]   = None
        self.refresh_token:    Optional[str]   = None
        self.token_expires_at: Optional[float] = None  # unix timestamp
        self._pkce_verifier:   Optional[str]   = None
        self._oauth_state:     Optional[str]   = None

    def is_token_valid(self) -> bool:
        """アクセストークンが有効かどうかを返す（60秒マージン）"""
        if not self.access_token:
            return False
        if self.token_expires_at and time.time() >= self.token_expires_at - 60:
            return False
        return True

    def set_tokens(self, token_response: dict):
        """トークンレスポンスをステートにセット"""
        self.access_token     = token_response.get("access_token")
        self.refresh_token    = token_response.get("refresh_token")
        expires_in            = token_response.get("expires_in", 300)
        self.token_expires_at = time.time() + int(expires_in)

    def reset(self):
        self.status         = EGovStatus.IDLE
        self.message        = ""
        self.mfa_event      = asyncio.Event()
        self.mfa_code       = None
        self.screenshot_b64 = None
        self.last_download  = None
        self.access_token     = None
        self.refresh_token    = None
        self.token_expires_at = None
        self._pkce_verifier   = None
        self._oauth_state     = None

    async def close_browser(self):
        """ブラウザを閉じてリソースを解放"""
        try:
            if self._browser:
                await self._browser.close()
        except Exception:
            pass
        try:
            if self._playwright:
                await self._playwright.stop()
        except Exception:
            pass
        self._playwright = None
        self._browser    = None
        self._context    = None
        self._page       = None


# モジュールレベルのシングルトン
state = EGovState()
