"""
Authentication endpoints for Google Sheets integration.
Provides JWT token distribution for Sheets add-on users.
"""

from fastapi import APIRouter, HTTPException, Depends, Response, Request
from fastapi.security import HTTPAuthorizationCredentials
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from typing import Dict, Any, Optional
from datetime import datetime, timedelta
import os
import string
from jose import jwt
import secrets
import logging

from ...auth_core import get_current_identity, bearer_scheme
from ...db import get_session
from ...settings import JWT_SECRET_KEY, JWT_ALGORITHM
from ...services.cache import LruTtlCache

try:
    from ...models import Account, APIKey
except Exception:  # pragma: no cover - optional imports in stripped environments
    Account = None
    APIKey = None

log = logging.getLogger(__name__)

router = APIRouter(prefix="/auth", tags=["Auth"])

# ─────────────────────────────────────────────────────────────────────────────
# Polling-based Auth Session Store
# Stores pending auth sessions for the seamless Google Sheets login flow
# ─────────────────────────────────────────────────────────────────────────────
_auth_sessions = LruTtlCache(maxsize=1000, ttl=300)  # 5 minute TTL


def _generate_auth_code() -> str:
    """Generate a short, URL-safe auth code (e.g., 'A3X9K2')."""
    chars = string.ascii_uppercase + string.digits
    # Remove ambiguous characters
    chars = chars.replace("O", "").replace("0", "").replace("I", "").replace("1", "")
    return "".join(secrets.choice(chars) for _ in range(6))


@router.get("/session")
async def get_session_info(
    credentials: HTTPAuthorizationCredentials = Depends(bearer_scheme),
    db: AsyncSession = Depends(get_session),
) -> Dict[str, Any]:
    """
    Return the authenticated Clerk session context for Google Sheets.

    This maps the Clerk token to our FoundryMatch account so that the add-on
    can persist a single login across all features (no per-feature API keys).
    """
    identity = await get_current_identity(credentials)
    account_id = identity.get("org_id")
    if not account_id:
        raise HTTPException(
            status_code=401,
            detail={
                "error": "NO_ORG",
                "message": "No organization is associated with this session. Switch to an organization in FoundryOps and try again.",
            },
        )

    account_name: Optional[str] = None
    account_status: Optional[str] = None
    has_active_api_key = False

    if Account is not None:
        try:
            account = await db.get(Account, account_id)
            if account:
                account_name = getattr(account, "name", None)
                account_status = getattr(account, "status", None)
        except Exception as e:
            # Handle schema mismatches gracefully (e.g., missing columns)
            log.warning(f"Failed to fetch account details for {account_id}: {e}")

    if APIKey is not None:
        try:
            result = await db.execute(
                select(APIKey).where(
                    APIKey.account_id == account_id, APIKey.is_active.is_(True)
                )
            )
            has_active_api_key = result.scalar_one_or_none() is not None
        except Exception as e:
            # Handle schema mismatches gracefully
            log.warning(f"Failed to check API key status for {account_id}: {e}")

    return {
        "ok": True,
        "account_id": account_id,
        "accountId": account_id,  # Also include camelCase for Apps Script compatibility
        "org_id": account_id,  # Include org_id for backwards compatibility
        "account_name": account_name,
        "accountName": account_name,  # Also include camelCase
        "account_status": account_status,
        "user_id": identity.get("user_id"),
        "email": identity.get("email"),
        "has_active_api_key": has_active_api_key,
    }


@router.get("/sheets-token")
async def get_sheets_token(
    credentials: HTTPAuthorizationCredentials = Depends(bearer_scheme),
) -> Dict[str, Any]:
    """
    Get JWT token for Google Sheets add-on.

    This endpoint is designed to be opened in a browser by a user who is already
    authenticated with Clerk. The user's existing Clerk session provides the JWT,
    which is then validated and returned for use in Google Sheets.

    Flow:
    1. User clicks "Sign In" in Google Sheets add-on
    2. Opens this URL in browser: https://dev.foundryops.io/api/v1/auth/sheets-token
    3. User is prompted to sign in with Clerk (if not already signed in)
    4. Clerk session cookie validates the user
    5. This endpoint returns the JWT token with user info
    6. User copies token and pastes into Google Sheets dialog

    Returns:
        {
            "token": "eyJhbGc...",     # JWT token to use in Sheets
            "user_id": "user_xxx",     # Clerk user ID
            "org_id": "org_xxx",       # Clerk organization ID
            "email": "user@example.com",
            "expires_in": 2592000      # Token validity (seconds)
        }

    Raises:
        401: If user is not authenticated with Clerk
    """
    if not credentials:
        raise HTTPException(
            status_code=401,
            detail={
                "error": "not_authenticated",
                "message": "Please sign in to FoundryOps first. Visit https://dev.foundryops.io and sign in with Clerk, then try again.",
                "instructions": [
                    "1. Open https://dev.foundryops.io in your browser",
                    "2. Sign in with your Clerk account",
                    "3. Return to this page to get your token",
                ],
            },
        )

    # Validate the Clerk session and extract identity
    try:
        identity = await get_current_identity(credentials)
    except HTTPException as e:
        log.warning(f"Token validation failed: {e.detail}")
        raise HTTPException(
            status_code=401,
            detail={
                "error": "invalid_session",
                "message": "Your session has expired. Please sign in again.",
                "instructions": [
                    "1. Open https://dev.foundryops.io in a new tab",
                    "2. Sign in with your Clerk account",
                    "3. Return here to get a fresh token",
                ],
            },
        )

    log.info(
        f"[AUTH] Generated Sheets token for user {identity['user_id']} (org: {identity['org_id']})"
    )

    # Issue a long-lived HS256 token specifically for the Sheets add-on.
    # Clerk session tokens expire quickly (≈60s), so we mint our own token using
    # the shared JWT secret so Apps Script can reuse the token for longer periods.
    secret = JWT_SECRET_KEY
    if not secret:
        raise HTTPException(
            status_code=500,
            detail="JWT_SECRET_KEY is not configured on the server",
        )

    ttl_seconds = int(os.getenv("SHEETS_TOKEN_TTL_SECONDS", "2592000"))  # 30 days
    now = datetime.utcnow()
    expires_at = now + timedelta(seconds=ttl_seconds)

    payload = {
        "sub": identity["user_id"],
        "user_id": identity["user_id"],
        "org_id": identity["org_id"],
        "email": identity.get("email"),
        "iss": "foundryops",
        "aud": "google-sheets-addon",
        "iat": int(now.timestamp()),
        "exp": int(expires_at.timestamp()),
    }

    alg = JWT_ALGORITHM or "HS256"
    sheets_token = jwt.encode(payload, secret, algorithm=alg)

    return {
        "token": sheets_token,
        "user_id": identity["user_id"],
        "org_id": identity["org_id"],
        "email": identity.get("email"),
        "expires_in": ttl_seconds,
        "expires_at": expires_at.isoformat() + "Z",
        "instructions": "Copy this token and paste it into Google Sheets when prompted.",
    }


@router.get("/sheets-token-ui")
async def get_sheets_token_ui(request: Request) -> Response:
    """
    Browser-friendly version for generating Sheets tokens.

    This page uses Clerk's client-side SDK to authenticate users and get their session token.
    Once authenticated, it displays the token with a copy button.

    Flow:
    1. Page loads with Clerk SDK
    2. Checks if user is signed in via Clerk session
    3. If signed in: Gets JWT token and displays it
    4. If not signed in: Shows Clerk sign-in widget
    5. After sign-in: Auto-displays token (no page reload needed)
    """
    from fmatch.shared.settings import get_settings
    from pathlib import Path

    settings = get_settings()
    clerk_key = getattr(settings, "CLERK_PUBLISHABLE_KEY", "")
    clerk_issuer = getattr(settings, "CLERK_ISSUER", "")

    # Extract domain from issuer (e.g., "splendid-kid-31.clerk.accounts.dev")
    clerk_domain = (
        clerk_issuer.replace("https://", "").replace("http://", "")
        if clerk_issuer
        else ""
    )

    # Load HTML template
    html_path = Path(__file__).parent / "auth_clerk.html"
    with open(html_path, "r", encoding="utf-8") as f:
        html = f.read()

    # Replace placeholders
    html = html.replace("{{CLERK_PUBLISHABLE_KEY}}", clerk_key)
    html = html.replace("{{CLERK_DOMAIN}}", clerk_domain)

    return Response(content=html, media_type="text/html")


@router.get("/sheets-token-ui-dev")
async def get_sheets_token_ui_dev(request: Request) -> Response:
    """
    DEV VERSION - Shows hardcoded dev-token for testing without Clerk.
    """
    html = """
    <!DOCTYPE html>
    <html>
    <head>
        <title>FoundryOps - Get Your Token</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
        <style>
            body {
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
                max-width: 700px;
                margin: 50px auto;
                padding: 20px;
                background: #f5f5f5;
            }
            .card {
                background: white;
                padding: 30px;
                border-radius: 8px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            }
            h1 {
                color: #333;
                margin-top: 0;
            }
            .hidden {
                display: none;
            }
            .loading {
                text-align: center;
                color: #666;
                padding: 40px 0;
            }
            .spinner {
                border: 4px solid #f3f3f3;
                border-top: 4px solid #2563eb;
                border-radius: 50%;
                width: 40px;
                height: 40px;
                animation: spin 1s linear infinite;
                margin: 20px auto;
            }
            @keyframes spin {
                0% { transform: rotate(0deg); }
                100% { transform: rotate(360deg); }
            }
            .success {
                color: #2e7d32;
                font-weight: 500;
            }
            .user-info {
                background: #f0f9ff;
                padding: 15px;
                border-radius: 6px;
                margin: 20px 0;
            }
            .user-info p {
                margin: 5px 0;
            }
            .token-box {
                background: #f5f5f5;
                border: 2px solid #e0e0e0;
                border-radius: 6px;
                padding: 15px;
                margin: 20px 0;
                font-family: 'Courier New', monospace;
                font-size: 12px;
                word-break: break-all;
            }
            .copy-button {
                background: #2563eb;
                color: white;
                border: none;
                padding: 12px 24px;
                border-radius: 6px;
                cursor: pointer;
                font-size: 14px;
                font-weight: 500;
                width: 100%;
                margin-top: 10px;
            }
            .copy-button:hover {
                background: #1d4ed8;
            }
            .copied {
                background: #2e7d32 !important;
            }
            .instructions {
                background: #fff3cd;
                border-left: 4px solid #ffc107;
                padding: 15px;
                margin: 20px 0;
            }
            .error {
                background: #ffebee;
                color: #c62828;
                padding: 15px;
                border-radius: 6px;
                margin: 20px 0;
            }
        </style>
    </head>
    <body>
        <div class="card">
            <!-- Loading state -->
            <div id="loadingState">
                <div class="loading">
                    <div class="spinner"></div>
                    <p>Checking authentication...</p>
                </div>
            </div>

            <!-- Not signed in state -->
            <div id="signInState" class="hidden">
                <h1>🔐 Sign In Required</h1>
                <p>You need to sign in to FoundryOps to get your token for Google Sheets.</p>
                <div class="instructions">
                    <strong>📋 Instructions:</strong>
                    <ol>
                        <li>Sign in to your FoundryOps account using the form below</li>
                        <li>Once signed in, your token will appear automatically</li>
                        <li>Copy the token and paste it into Google Sheets</li>
                    </ol>
                </div>
                <div id="clerkSignIn"></div>
            </div>

            <!-- Token display state -->
            <div id="tokenState" class="hidden">
                <h1>✅ Authentication Successful</h1>
                <p class="success">Your token has been generated!</p>

                <div class="user-info">
                    <p><strong>Email:</strong> <span id="userEmail">Loading...</span></p>
                    <p><strong>User ID:</strong> <span id="userId">Loading...</span></p>
                </div>

                <div class="instructions">
                    <strong>📋 Next Steps:</strong>
                    <ol>
                        <li>Click the "Copy Token" button below</li>
                        <li>Return to Google Sheets</li>
                        <li>Paste the token when prompted</li>
                        <li>You can close this window after copying</li>
                    </ol>
                </div>

                <div class="token-box" id="tokenBox">Loading token...</div>

                <button class="copy-button" id="copyBtn" onclick="copyToken()">
                    📋 Copy Token to Clipboard
                </button>

                <p style="color: #666; font-size: 14px; margin-top: 15px;">
                    ⏱️ This token expires in 30 days. Generate a new one anytime by visiting this page.
                </p>
            </div>

            <!-- Error state -->
            <div id="errorState" class="hidden">
                <h1>❌ Error</h1>
                <div class="error" id="errorMessage"></div>
            </div>
        </div>

        <script>
            // For dev mode - just show the dev token
            const isDev = window.location.hostname === 'localhost' ||
                          window.location.hostname === '127.0.0.1' ||
                          window.location.hostname === 'dev.foundryops.io';

            if (isDev) {
                // Dev mode: show dev token immediately
                document.getElementById('loadingState').classList.add('hidden');
                document.getElementById('tokenState').classList.remove('hidden');

                document.getElementById('userEmail').textContent = 'dev@example.com';
                document.getElementById('userId').textContent = 'dev-user';
                document.getElementById('tokenBox').textContent = 'dev-token';

                window.copyToken = function() {
                    const tokenText = document.getElementById('tokenBox').textContent;
                    const button = document.getElementById('copyBtn');

                    navigator.clipboard.writeText(tokenText).then(() => {
                        button.textContent = '✓ Copied to Clipboard!';
                        button.classList.add('copied');
                        setTimeout(() => {
                            button.textContent = '📋 Copy Token to Clipboard';
                            button.classList.remove('copied');
                        }, 2000);
                    });
                };

                // Auto-copy
                window.addEventListener('load', () => copyToken());
            } else {
                // Production: TODO - integrate with Clerk
                // For now, show error message
                document.getElementById('loadingState').classList.add('hidden');
                document.getElementById('errorState').classList.remove('hidden');
                document.getElementById('errorMessage').textContent =
                    'Clerk integration is not yet configured. Please contact support or use dev-token for testing.';
            }
        </script>
    </body>
    </html>
    """
    return Response(content=html, media_type="text/html")


@router.get("/sheets-token-ui-old")
async def get_sheets_token_ui_old(
    credentials: Optional[HTTPAuthorizationCredentials] = Depends(bearer_scheme),
) -> Response:
    """
    OLD VERSION - kept for reference.
    This version required Bearer token to be passed, which doesn't work for browser access.
    """
    if not credentials:
        # Return HTML sign-in page
        html = """
        <!DOCTYPE html>
        <html>
        <head>
            <title>FoundryOps - Authenticate for Google Sheets</title>
            <style>
                body {
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
                    max-width: 600px;
                    margin: 50px auto;
                    padding: 20px;
                    background: #f5f5f5;
                }
                .card {
                    background: white;
                    padding: 30px;
                    border-radius: 8px;
                    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
                }
                h1 { color: #333; margin-top: 0; }
                .error { color: #d32f2f; }
                .button {
                    display: inline-block;
                    background: #2563eb;
                    color: white;
                    padding: 12px 24px;
                    border-radius: 6px;
                    text-decoration: none;
                    margin-top: 20px;
                }
                .button:hover { background: #1d4ed8; }
                ol { line-height: 1.8; }
            </style>
        </head>
        <body>
            <div class="card">
                <h1>🔐 Authentication Required</h1>
                <p class="error">You need to sign in to FoundryOps first.</p>
                <p>Follow these steps:</p>
                <ol>
                    <li>Click the button below to sign in</li>
                    <li>After signing in, return to this page</li>
                    <li>Copy the token that appears</li>
                    <li>Paste it into Google Sheets</li>
                </ol>
                <a href="https://dev.foundryops.io" class="button">Sign In to FoundryOps</a>
            </div>
        </body>
        </html>
        """
        return Response(content=html, media_type="text/html")

    # Validate session and get token
    try:
        identity = await get_current_identity(credentials)
    except HTTPException:
        html = """
        <!DOCTYPE html>
        <html>
        <head>
            <title>FoundryOps - Session Expired</title>
            <style>
                body {
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
                    max-width: 600px;
                    margin: 50px auto;
                    padding: 20px;
                    background: #f5f5f5;
                }
                .card {
                    background: white;
                    padding: 30px;
                    border-radius: 8px;
                    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
                }
                h1 { color: #333; margin-top: 0; }
                .error { color: #d32f2f; }
                .button {
                    display: inline-block;
                    background: #2563eb;
                    color: white;
                    padding: 12px 24px;
                    border-radius: 6px;
                    text-decoration: none;
                    margin-top: 20px;
                }
            </style>
        </head>
        <body>
            <div class="card">
                <h1>⏱️ Session Expired</h1>
                <p class="error">Your authentication session has expired.</p>
                <p>Please sign in again to get a fresh token.</p>
                <a href="https://dev.foundryops.io" class="button">Sign In Again</a>
            </div>
        </body>
        </html>
        """
        return Response(content=html, media_type="text/html")

    token = credentials.credentials
    log.info(f"[AUTH] Generated Sheets token UI for user {identity['user_id']}")

    # Return HTML page with token
    html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <title>FoundryOps - Your Token</title>
        <style>
            body {{
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
                max-width: 700px;
                margin: 50px auto;
                padding: 20px;
                background: #f5f5f5;
            }}
            .card {{
                background: white;
                padding: 30px;
                border-radius: 8px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            }}
            h1 {{
                color: #333;
                margin-top: 0;
            }}
            .success {{
                color: #2e7d32;
                font-weight: 500;
            }}
            .user-info {{
                background: #f0f9ff;
                padding: 15px;
                border-radius: 6px;
                margin: 20px 0;
            }}
            .user-info p {{
                margin: 5px 0;
            }}
            .token-box {{
                background: #f5f5f5;
                border: 2px solid #e0e0e0;
                border-radius: 6px;
                padding: 15px;
                margin: 20px 0;
                font-family: 'Courier New', monospace;
                font-size: 12px;
                word-break: break-all;
                position: relative;
            }}
            .copy-button {{
                background: #2563eb;
                color: white;
                border: none;
                padding: 12px 24px;
                border-radius: 6px;
                cursor: pointer;
                font-size: 14px;
                font-weight: 500;
                width: 100%;
                margin-top: 10px;
            }}
            .copy-button:hover {{
                background: #1d4ed8;
            }}
            .copy-button:active {{
                background: #1e40af;
            }}
            .copied {{
                background: #2e7d32 !important;
            }}
            .instructions {{
                background: #fff3cd;
                border-left: 4px solid #ffc107;
                padding: 15px;
                margin: 20px 0;
            }}
            .instructions ol {{
                margin: 10px 0;
                padding-left: 20px;
            }}
            .expiry {{
                color: #666;
                font-size: 14px;
                margin-top: 15px;
            }}
        </style>
    </head>
    <body>
        <div class="card">
            <h1>✅ Authentication Successful</h1>
            <p class="success">Your token has been generated!</p>

            <div class="user-info">
                <p><strong>Email:</strong> {identity.get('email', 'N/A')}</p>
                <p><strong>User ID:</strong> {identity['user_id']}</p>
                <p><strong>Organization:</strong> {identity['org_id']}</p>
            </div>

            <div class="instructions">
                <strong>📋 Next Steps:</strong>
                <ol>
                    <li>Click the "Copy Token" button below</li>
                    <li>Return to Google Sheets</li>
                    <li>Paste the token when prompted</li>
                    <li>You can close this window after copying</li>
                </ol>
            </div>

            <div class="token-box" id="tokenBox">{token}</div>

            <button class="copy-button" id="copyBtn" onclick="copyToken()">
                📋 Copy Token to Clipboard
            </button>

            <p class="expiry">⏱️ This token expires in 30 days. You can generate a new one anytime by visiting this page.</p>
        </div>

        <script>
            function copyToken() {{
                const tokenText = document.getElementById('tokenBox').textContent;
                const button = document.getElementById('copyBtn');

                navigator.clipboard.writeText(tokenText).then(() => {{
                    button.textContent = '✓ Copied to Clipboard!';
                    button.classList.add('copied');

                    setTimeout(() => {{
                        button.textContent = '📋 Copy Token to Clipboard';
                        button.classList.remove('copied');
                    }}, 2000);
                }}).catch(err => {{
                    // Fallback for older browsers
                    const textArea = document.createElement('textarea');
                    textArea.value = tokenText;
                    document.body.appendChild(textArea);
                    textArea.select();
                    document.execCommand('copy');
                    document.body.removeChild(textArea);

                    button.textContent = '✓ Copied!';
                    button.classList.add('copied');
                }});
            }}

            // Auto-copy on page load (user-friendly)
            window.addEventListener('load', () => {{
                copyToken();
            }});
        </script>
    </body>
    </html>
    """

    return Response(content=html, media_type="text/html")


@router.get("/sheets-long-token")
async def get_sheets_long_token(
    credentials: HTTPAuthorizationCredentials = Depends(bearer_scheme),
) -> Dict[str, Any]:
    """
    Generate a long-lived JWT token for Google Sheets (30 days).

    Clerk session tokens expire quickly (5-60 minutes). This endpoint generates
    our own HS256 JWT tokens that last 30 days for a better Sheets UX.

    Flow:
    1. User signs in with Clerk (gets short-lived session token)
    2. Calls this endpoint with Clerk token
    3. We validate the Clerk token
    4. We generate our own HS256 token that lasts 30 days
    5. User stores this long-lived token in Google Sheets

    Returns:
        {
            "token": "eyJhbGc...",     # Long-lived JWT (30 days)
            "user_id": "user_xxx",
            "org_id": "org_xxx",
            "email": "user@example.com",
            "expires_in": 2592000,     # 30 days in seconds
            "expires_at": "2025-11-13T...",
            "token_type": "sheets-long-token"
        }
    """
    if not credentials:
        raise HTTPException(
            status_code=401,
            detail="Not authenticated. Please sign in with Clerk first.",
        )

    # Validate the Clerk token and get identity
    try:
        identity = await get_current_identity(credentials)
    except HTTPException as e:
        log.warning(f"[SHEETS_LONG_TOKEN] Clerk token validation failed: {e.detail}")
        raise HTTPException(
            status_code=401,
            detail={
                "error": "invalid_clerk_token",
                "message": "Could not validate your Clerk session. Please sign in again.",
                "instructions": [
                    "1. Open https://dev.foundryops.io",
                    "2. Sign in with Clerk",
                    "3. Return here to get a new token",
                ],
            },
        )

    # Extract identity info
    user_id = identity["user_id"]
    org_id = identity["org_id"]
    email = identity.get("email", "")

    if not org_id:
        raise HTTPException(
            status_code=401,
            detail="No organization selected. Please select an organization in FoundryOps.",
        )

    # Generate our own long-lived token (30 days)
    now = datetime.utcnow()
    expires_at = now + timedelta(days=30)

    payload = {
        "sub": user_id,  # Standard JWT claim for user ID
        "user_id": user_id,
        "org_id": org_id,
        "email": email,
        "iat": int(now.timestamp()),  # Issued at
        "exp": int(expires_at.timestamp()),  # Expires
        "type": "sheets-long-token",  # Distinguish from Clerk tokens
        "iss": "foundryops",  # Our issuer
        "aud": "google-sheets-addon",  # Audience
    }

    secret = JWT_SECRET_KEY
    if not secret:
        # Generate a random secret for development
        log.warning(
            "[SHEETS_LONG_TOKEN] JWT_SECRET_KEY not set, generating random secret"
        )
        secret = secrets.token_urlsafe(32)

    long_token = jwt.encode(payload, secret, algorithm=JWT_ALGORITHM)

    log.info(
        f"[SHEETS_LONG_TOKEN] Generated 30-day token for user {user_id} (org: {org_id})"
    )

    return {
        "token": long_token,
        "user_id": user_id,
        "org_id": org_id,
        "email": email,
        "expires_in": 30 * 24 * 60 * 60,  # 30 days in seconds
        "expires_at": expires_at.isoformat(),
        "token_type": "sheets-long-token",
        "instructions": "Copy this token and paste it into Google Sheets. It will last for 30 days.",
    }


@router.get("/sheets-long-token-ui")
async def get_sheets_long_token_ui(request: Request) -> Response:
    """
    Browser-friendly UI for generating long-lived Google Sheets tokens.

    This page:
    1. Loads Clerk SDK
    2. Checks if user is signed in
    3. If not signed in: Shows Clerk sign-in form
    4. If signed in: Automatically exchanges Clerk token for long-lived token
    5. Displays the 30-day token with copy button

    Flow:
    1. User visits this page in browser
    2. Signs in with Clerk (if not already)
    3. Page gets Clerk session token
    4. Page calls /api/v1/auth/sheets-long-token with Clerk token
    5. Page displays the long-lived token
    6. User copies token and pastes into Google Sheets
    """
    from fmatch.shared.settings import get_settings
    from pathlib import Path

    settings = get_settings()
    clerk_key = getattr(settings, "CLERK_PUBLISHABLE_KEY", "")
    clerk_issuer = getattr(settings, "CLERK_ISSUER", "")

    # Extract domain from issuer
    clerk_domain = (
        clerk_issuer.replace("https://", "").replace("http://", "")
        if clerk_issuer
        else ""
    )

    # Load HTML template
    html_path = Path(__file__).parent / "sheets_long_token_ui.html"
    with open(html_path, "r", encoding="utf-8") as f:
        html = f.read()

    # Replace placeholders
    html = html.replace("{{CLERK_PUBLISHABLE_KEY}}", clerk_key)
    html = html.replace("{{CLERK_DOMAIN}}", clerk_domain)

    return Response(content=html, media_type="text/html")


# ─────────────────────────────────────────────────────────────────────────────
# Seamless Polling-based Auth Flow for Google Sheets
# Eliminates the manual copy/paste token workflow
# ─────────────────────────────────────────────────────────────────────────────


@router.post("/sheets-auth-init")
async def sheets_auth_init() -> Dict[str, Any]:
    """
    Initialize a seamless auth session for Google Sheets.

    This is called by the Apps Script to start the authentication flow.
    Returns a short auth code that the user's browser will use to complete auth.

    Flow:
    1. Apps Script calls this endpoint to get a code
    2. Apps Script opens browser popup to /sheets-auth-callback?code=XXX
    3. User signs in with Clerk in the popup
    4. Popup stores the token and shows "success" message
    5. Apps Script polls /sheets-auth-poll?code=XXX to get the token
    6. When token is returned, auth is complete (no copy/paste!)

    Returns:
        {
            "code": "A3X9K2",
            "expires_in": 300,
            "poll_url": "/api/v1/auth/sheets-auth-poll?code=A3X9K2",
            "callback_url": "/api/v1/auth/sheets-auth-callback?code=A3X9K2"
        }
    """
    code = _generate_auth_code()

    # Store the pending session (token will be null until user completes auth)
    await _auth_sessions.set(f"sheets_auth:{code}", {"status": "pending", "token": None})

    log.info(f"[SHEETS_AUTH] Initialized auth session with code {code}")

    return {
        "code": code,
        "expires_in": 300,
        "poll_url": f"/api/v1/auth/sheets-auth-poll?code={code}",
        "callback_url": f"/api/v1/auth/sheets-auth-callback?code={code}",
    }


@router.get("/sheets-auth-callback")
async def sheets_auth_callback(request: Request, code: str) -> Response:
    """
    Browser page where user completes Clerk sign-in.

    After successful sign-in, this page:
    1. Gets the Clerk session token
    2. Exchanges it for a long-lived Sheets token
    3. Stores the token against the auth code
    4. Shows "Success! You can close this window"

    The Apps Script polling will then pick up the token.
    """
    from fmatch.shared.settings import get_settings
    from pathlib import Path

    # Verify the code exists and is pending
    session = await _auth_sessions.get(f"sheets_auth:{code}")
    if not session:
        return Response(
            content="""
            <!DOCTYPE html>
            <html>
            <head><title>Session Expired</title></head>
            <body style="font-family: -apple-system, sans-serif; max-width: 500px; margin: 50px auto; text-align: center;">
                <h1>⏱️ Session Expired</h1>
                <p>This authentication link has expired. Please return to Google Sheets and click "Sign In" again.</p>
            </body>
            </html>
            """,
            media_type="text/html",
        )

    settings = get_settings()
    clerk_key = getattr(settings, "CLERK_PUBLISHABLE_KEY", "") or ""
    clerk_issuer = getattr(settings, "CLERK_ISSUER", "") or ""
    clerk_domain = (
        clerk_issuer.replace("https://", "").replace("http://", "")
        if clerk_issuer
        else ""
    )

    # Load the callback HTML template
    html_path = Path(__file__).parent / "sheets_auth_callback.html"
    with open(html_path, "r", encoding="utf-8") as f:
        html = f.read()

    html = html.replace("{{CLERK_PUBLISHABLE_KEY}}", clerk_key)
    html = html.replace("{{CLERK_DOMAIN}}", clerk_domain)
    html = html.replace("{{AUTH_CODE}}", code)

    return Response(content=html, media_type="text/html")


@router.post("/sheets-auth-complete")
async def sheets_auth_complete(
    code: str,
    credentials: HTTPAuthorizationCredentials = Depends(bearer_scheme),
) -> Dict[str, Any]:
    """
    Called by the browser callback page after successful Clerk sign-in.

    This endpoint:
    1. Validates the Clerk token
    2. Generates a long-lived Sheets token
    3. Stores it against the auth code for polling pickup

    Args:
        code: The auth code from /sheets-auth-init
        credentials: The Clerk Bearer token from the signed-in user
    """
    # Verify the session exists
    session = await _auth_sessions.get(f"sheets_auth:{code}")
    if not session:
        raise HTTPException(status_code=404, detail="Auth session not found or expired")

    if session.get("status") == "complete":
        raise HTTPException(status_code=400, detail="Auth session already completed")

    # Validate the Clerk token
    try:
        identity = await get_current_identity(credentials)
    except HTTPException as e:
        log.warning(f"[SHEETS_AUTH] Token validation failed for code {code}: {e.detail}")
        raise HTTPException(status_code=401, detail="Invalid Clerk token")

    user_id = identity["user_id"]
    org_id = identity.get("org_id")
    email = identity.get("email", "")

    if not org_id:
        raise HTTPException(
            status_code=401,
            detail="No organization selected. Please select an organization in FoundryOps first.",
        )

    # Generate long-lived Sheets token
    secret = JWT_SECRET_KEY
    if not secret:
        raise HTTPException(status_code=500, detail="JWT_SECRET_KEY not configured")

    ttl_seconds = int(os.getenv("SHEETS_TOKEN_TTL_SECONDS", "2592000"))  # 30 days
    now = datetime.utcnow()
    expires_at = now + timedelta(seconds=ttl_seconds)

    payload = {
        "sub": user_id,
        "user_id": user_id,
        "org_id": org_id,
        "email": email,
        "iss": "foundryops",
        "aud": "google-sheets-addon",
        "iat": int(now.timestamp()),
        "exp": int(expires_at.timestamp()),
    }

    alg = JWT_ALGORITHM or "HS256"
    sheets_token = jwt.encode(payload, secret, algorithm=alg)

    # Store the completed session with token
    await _auth_sessions.set(
        f"sheets_auth:{code}",
        {
            "status": "complete",
            "token": sheets_token,
            "user_id": user_id,
            "org_id": org_id,
            "email": email,
            "expires_at": expires_at.isoformat() + "Z",
        },
    )

    log.info(f"[SHEETS_AUTH] Completed auth for code {code}, user {user_id}")

    return {"ok": True, "message": "Authentication complete"}


@router.get("/sheets-auth-poll")
async def sheets_auth_poll(code: str) -> Dict[str, Any]:
    """
    Poll for auth completion. Called by Apps Script.

    Returns:
        - If pending: {"status": "pending"}
        - If complete: {"status": "complete", "token": "...", "email": "...", ...}
        - If expired/invalid: {"status": "expired"}

    After returning a complete status, the session is deleted to prevent reuse.
    """
    session = await _auth_sessions.get(f"sheets_auth:{code}")

    if not session:
        return {"status": "expired"}

    if session.get("status") == "pending":
        return {"status": "pending"}

    if session.get("status") == "complete":
        # Delete the session after successful retrieval (one-time use)
        # We do this by setting an already-expired entry
        await _auth_sessions.set(f"sheets_auth:{code}", {"status": "consumed"})

        return {
            "status": "complete",
            "token": session["token"],
            "user_id": session.get("user_id"),
            "org_id": session.get("org_id"),
            "email": session.get("email"),
            "expires_at": session.get("expires_at"),
        }

    return {"status": "expired"}
