"""
Dropbox integration views for setup and OAuth callback.
"""

import json

from fastapi import Query, Request
from sqlalchemy.orm import Session

from app.models import UserIntegration
from app.utils.user_scope import get_current_owner_id
from app.views.base import APIRouter, Depends, get_db, require_login, settings, templates

router = APIRouter()


@router.get("/dropbox-setup")
@require_login
async def dropbox_setup_page(
    request: Request,
    integration_id: int | None = Query(None),
    db: Session = Depends(get_db),
):
    """
    Setup page for the Dropbox integration.

    When ``integration_id`` is provided the page operates in **user mode**:
    the OAuth wizard saves credentials to the named per-user integration
    record rather than to the global application settings.  Only the folder
    path from the integration's existing config is pre-populated; global
    admin credentials are never exposed in this mode.
    """
    if integration_id is not None:
        owner_id = get_current_owner_id(request)
        integration = (
            db.query(UserIntegration)
            .filter(UserIntegration.id == integration_id, UserIntegration.owner_id == owner_id)
            .first()
        )
        if integration:
            cfg: dict = {}
            if integration.config:
                try:
                    cfg = json.loads(integration.config)
                except (json.JSONDecodeError, TypeError):
                    cfg = {}
            # Support both "folder" (DROPBOX destination) and "folder_path" (WATCH_FOLDER source)
            folder_path = cfg.get("folder", cfg.get("folder_path", ""))
            return templates.TemplateResponse(
                "dropbox.html",
                {
                    "request": request,
                    "user_mode": True,
                    "is_configured": bool(integration.credentials),
                    "integration_id": integration_id,
                    "integration_name": integration.name,
                    "integration_type": integration.integration_type,
                    "folder_path": folder_path,
                    "app_key_value": "",
                    "app_secret_value": "",
                    "refresh_token_value": "",
                },
            )

    # ── Admin / global mode ──────────────────────────────────────────────────
    is_configured = bool(settings.dropbox_app_key and settings.dropbox_app_secret and settings.dropbox_refresh_token)

    return templates.TemplateResponse(
        "dropbox.html",
        {
            "request": request,
            "user_mode": False,
            "is_configured": is_configured,
            "app_key_value": settings.dropbox_app_key or "",
            "app_secret_value": settings.dropbox_app_secret if settings.dropbox_app_secret else "",
            "refresh_token_value": settings.dropbox_refresh_token if settings.dropbox_refresh_token else "",
            "folder_path": settings.dropbox_folder or "/Documents/Uploads",
            "integration_id": integration_id,
            "integration_name": None,
            "integration_type": None,
        },
    )


@router.get("/dropbox-callback")
@require_login
async def dropbox_callback(request: Request, code: str = None, error: str = None):
    """
    Callback endpoint for Dropbox OAuth flow.
    Automatically exchanges the code for a token and saves it to the configuration.
    """
    if error:
        return templates.TemplateResponse("dropbox_callback_error.html", {"request": request, "error": error})

    if not code:
        return templates.TemplateResponse(
            "dropbox_callback_error.html", {"request": request, "error": "No authorization code received from Dropbox"}
        )

    # Display the processing page with automatic token exchange
    # Note: We provide empty strings for app_key_value and app_secret_value
    # to prevent overriding what's in sessionStorage
    return templates.TemplateResponse(
        "dropbox_callback.html",
        {
            "request": request,
            "code": code,
            "app_key_value": "",  # The callback will prioritize sessionStorage values
            "app_secret_value": "",  # The callback will prioritize sessionStorage values
            "folder_path": "",  # The callback will prioritize sessionStorage values
        },
    )
