import logging

from fastapi import APIRouter, Depends, Request, status
from fastapi.responses import PlainTextResponse, RedirectResponse, Response
from sqlalchemy.orm import Session

from app.config import Settings
from app.dependencies import (
    get_app_settings,
    get_db,
    get_current_auth_session,
    get_ticktick_client,
)
from app.integrations.ticktick import TickTickAuthError, TickTickClient, TickTickConfigError, TickTickRequestError
from app.services.auth import AuthenticatedSession
from app.services.config_page import save_config_value

router = APIRouter(tags=["ticktick"])
logger = logging.getLogger(__name__)


@router.get("/ticktick/auth/start")
def start_ticktick_auth(
    current_auth: AuthenticatedSession | None = Depends(get_current_auth_session),
    ticktick_client: TickTickClient = Depends(get_ticktick_client),
) -> Response:
    if current_auth is None:
        return RedirectResponse(url="/login", status_code=status.HTTP_303_SEE_OTHER)

    try:
        authorization_url = ticktick_client.build_authorization_url()
    except TickTickConfigError as exc:
        logger.warning("Rejected TickTick OAuth start due to incomplete configuration: %s", exc)
        return PlainTextResponse("TickTick integration is not configured", status_code=400)

    return RedirectResponse(url=authorization_url, status_code=status.HTTP_303_SEE_OTHER)


@router.get("/ticktick/auth/code")
def handle_ticktick_auth_code(
    request: Request,
    auth_db_session: Session = Depends(get_db),
    settings: Settings = Depends(get_app_settings),
    ticktick_client: TickTickClient = Depends(get_ticktick_client),
) -> Response:
    code = request.query_params.get("code", "")
    state = request.query_params.get("state", "")

    if not code or not state:
        return RedirectResponse(
            url="/config?ticktick_oauth=invalid-callback",
            status_code=status.HTTP_303_SEE_OTHER,
        )

    try:
        token = ticktick_client.exchange_authorization_code(code=code, state=state)
        save_config_value(
            auth_db_session,
            env_name="TICKTICK_TOKEN",
            value=token,
            bootstrap_settings=settings,
        )
    except TickTickAuthError as exc:
        logger.warning("Rejected TickTick OAuth callback due to invalid state: %s", exc)
        return RedirectResponse(
            url="/config?ticktick_oauth=invalid-state",
            status_code=status.HTTP_303_SEE_OTHER,
        )
    except (TickTickConfigError, TickTickRequestError, ValueError) as exc:
        logger.warning("TickTick OAuth callback failed: %s", exc)
        return RedirectResponse(
            url="/config?ticktick_oauth=failed",
            status_code=status.HTTP_303_SEE_OTHER,
        )

    return RedirectResponse(
        url="/config?ticktick_oauth=success",
        status_code=status.HTTP_303_SEE_OTHER,
    )