from __future__ import annotations

from fastapi import APIRouter, Depends, File, Request, UploadFile

from app.core.audit.service import AuditService
from app.core.auth.dependencies import set_dashboard_error_format, validate_dashboard_session
from app.core.exceptions import DashboardBadRequestError, DashboardConflictError, DashboardNotFoundError
from app.dependencies import AccountsContext, get_accounts_context
from app.modules.accounts.repository import AccountIdentityConflictError
from app.modules.accounts.schemas import (
    AccountDeleteResponse,
    AccountImportResponse,
    AccountPauseResponse,
    AccountReactivateResponse,
    AccountsResponse,
    AccountSummary,
    AccountTrendsResponse,
    PlatformIdentityCreateRequest,
    PlatformIdentityUpdateRequest,
)
from app.modules.accounts.service import (
    InvalidAuthJsonError,
    PlatformIdentityConflictError,
    PlatformIdentityNotFoundError,
    PlatformIdentityPrerequisiteError,
)

router = APIRouter(
    prefix="/api/accounts",
    tags=["dashboard"],
    dependencies=[Depends(validate_dashboard_session), Depends(set_dashboard_error_format)],
)


@router.get("", response_model=AccountsResponse)
async def list_accounts(
    context: AccountsContext = Depends(get_accounts_context),
) -> AccountsResponse:
    accounts = await context.service.list_accounts()
    return AccountsResponse(accounts=accounts)


@router.get("/{account_id}/trends", response_model=AccountTrendsResponse)
async def get_account_trends(
    account_id: str,
    context: AccountsContext = Depends(get_accounts_context),
) -> AccountTrendsResponse:
    result = await context.service.get_account_trends(account_id)
    if not result:
        raise DashboardNotFoundError("Account not found", code="account_not_found")
    return result


@router.post("/import", response_model=AccountImportResponse)
async def import_account(
    request: Request,
    auth_json: UploadFile = File(...),
    context: AccountsContext = Depends(get_accounts_context),
) -> AccountImportResponse:
    raw = await auth_json.read()
    try:
        response = await context.service.import_account(raw)
        AuditService.log_async(
            "account_created",
            actor_ip=request.client.host if request.client else None,
            details={"account_id": response.account_id},
        )
        return response
    except InvalidAuthJsonError as exc:
        raise DashboardBadRequestError("Invalid auth.json payload", code="invalid_auth_json") from exc
    except AccountIdentityConflictError as exc:
        raise DashboardConflictError(str(exc), code="duplicate_identity_conflict") from exc


@router.post("/platform", response_model=AccountImportResponse)
async def create_platform_identity(
    request: Request,
    payload: PlatformIdentityCreateRequest,
    context: AccountsContext = Depends(get_accounts_context),
) -> AccountImportResponse:
    try:
        response = await context.service.create_platform_identity(payload)
    except PlatformIdentityConflictError as exc:
        raise DashboardConflictError(str(exc), code="platform_identity_conflict") from exc
    except PlatformIdentityPrerequisiteError as exc:
        raise DashboardBadRequestError(str(exc), code="platform_identity_prerequisite_failed") from exc
    except ValueError as exc:
        raise DashboardBadRequestError(str(exc), code="platform_identity_validation_failed") from exc
    AuditService.log_async(
        "platform_identity_created",
        actor_ip=request.client.host if request.client else None,
        details={"account_id": response.account_id},
    )
    return response


@router.patch("/platform/{account_id}", response_model=AccountSummary)
async def update_platform_identity(
    request: Request,
    account_id: str,
    payload: PlatformIdentityUpdateRequest,
    context: AccountsContext = Depends(get_accounts_context),
) -> AccountSummary:
    try:
        response = await context.service.update_platform_identity(account_id, payload)
    except PlatformIdentityConflictError as exc:
        raise DashboardConflictError(str(exc), code="platform_identity_conflict") from exc
    except PlatformIdentityNotFoundError as exc:
        raise DashboardNotFoundError(str(exc), code="account_not_found") from exc
    except ValueError as exc:
        raise DashboardBadRequestError(str(exc), code="platform_identity_validation_failed") from exc
    AuditService.log_async(
        "platform_identity_updated",
        actor_ip=request.client.host if request.client else None,
        details={"account_id": account_id},
    )
    return response


@router.post("/{account_id}/reactivate", response_model=AccountReactivateResponse)
async def reactivate_account(
    account_id: str,
    context: AccountsContext = Depends(get_accounts_context),
) -> AccountReactivateResponse:
    success = await context.service.reactivate_account(account_id)
    if not success:
        raise DashboardNotFoundError("Account not found", code="account_not_found")
    return AccountReactivateResponse(status="reactivated")


@router.post("/{account_id}/pause", response_model=AccountPauseResponse)
async def pause_account(
    account_id: str,
    context: AccountsContext = Depends(get_accounts_context),
) -> AccountPauseResponse:
    success = await context.service.pause_account(account_id)
    if not success:
        raise DashboardNotFoundError("Account not found", code="account_not_found")
    return AccountPauseResponse(status="paused")


@router.delete("/{account_id}", response_model=AccountDeleteResponse)
async def delete_account(
    request: Request,
    account_id: str,
    context: AccountsContext = Depends(get_accounts_context),
) -> AccountDeleteResponse:
    success = await context.service.delete_account(account_id)
    if not success:
        raise DashboardNotFoundError("Account not found", code="account_not_found")
    AuditService.log_async(
        "account_deleted",
        actor_ip=request.client.host if request.client else None,
        details={"account_id": account_id},
    )
    return AccountDeleteResponse(status="deleted")
