# FILE: src/apps/pages/router.py
from typing import Literal

from fastapi import APIRouter, Body, Depends, File, UploadFile
from pydantic import ValidationError as PydanticValidationError
from sqlalchemy.ext.asyncio import AsyncSession

from src.apps.pages.schemas.page_content import SLUG_SCHEMAS
from src.apps.pages.services.page_content_service import PageContentService
from src.core.constants import UserRole
from src.core.dependencies import require_min_role
from src.core.exceptions import ValidationError
from src.core.schemas.response import success
from src.database.session import get_db

router = APIRouter(prefix="/pages", tags=["Pages CMS"])

PageSlug = Literal["global", "find", "availability", "map", "contact"]


async def _user_display_name(db: AsyncSession, user_id) -> str | None:
    if user_id is None:
        return None
    from src.apps.auth.models.user import User
    from sqlalchemy import select

    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    if not user:
        return None
    return f"{user.first_name} {user.last_name}".strip()


@router.get("/{slug}", response_model=dict)
async def get_page_content(
    slug: PageSlug,
    current_user=Depends(require_min_role(UserRole.STAFF)),
    db: AsyncSession = Depends(get_db),
):
    row = await PageContentService.get(db, current_user.tenant_id, slug)
    if row is None:
        return success(data={
            "page_slug": slug, "content": {}, "updated_at": None,
            "updated_by": None, "updated_by_name": None,
        })
    updated_by_name = await _user_display_name(db, row.updated_by)
    return success(data={
        "page_slug": row.page_slug,
        "content": row.content,
        "updated_at": row.updated_at.isoformat() if row.updated_at else None,
        "updated_by": str(row.updated_by) if row.updated_by else None,
        "updated_by_name": updated_by_name,
    })


@router.put("/{slug}", response_model=dict)
async def update_page_content(
    slug: PageSlug,
    body: dict = Body(...),
    current_user=Depends(require_min_role(UserRole.MANAGER)),
    db: AsyncSession = Depends(get_db),
):
    schema = SLUG_SCHEMAS[slug]
    try:
        validated = schema.model_validate(body)
    except PydanticValidationError as exc:
        errors = [
            {"field": ".".join(str(p) for p in e["loc"]), "message": e["msg"]}
            for e in exc.errors()
        ]
        raise ValidationError("Invalid page content", errors=errors) from exc

    row = await PageContentService.upsert(
        db, current_user.tenant_id, slug, validated.model_dump(), current_user.id
    )
    updated_by_name = await _user_display_name(db, row.updated_by)
    return success(
        data={
            "page_slug": row.page_slug,
            "content": row.content,
            "updated_at": row.updated_at.isoformat() if row.updated_at else None,
            "updated_by": str(row.updated_by) if row.updated_by else None,
            "updated_by_name": updated_by_name,
        },
        message="Page content saved.",
    )


@router.post("/map/upload-image", response_model=dict)
async def upload_map_image(
    file: UploadFile = File(...),
    current_user=Depends(require_min_role(UserRole.MANAGER)),
):
    content = await file.read()
    key = await PageContentService.upload_map_image(current_user.tenant_id, content, file.filename or "")
    url = _s3_url(key)
    return success(data={"url": url}, message="Image uploaded successfully")


@router.post("/map/upload-pdf", response_model=dict)
async def upload_map_pdf(
    lang: Literal["en", "fr"],
    file: UploadFile = File(...),
    current_user=Depends(require_min_role(UserRole.MANAGER)),
):
    content = await file.read()
    key = await PageContentService.upload_map_pdf(current_user.tenant_id, content, lang)
    url = _s3_url(key)
    return success(data={"url": url}, message="PDF uploaded successfully")


def _s3_url(key: str) -> str:
    from src.core.config import settings

    if settings.CLOUDFRONT_DOCUMENTS_URL:
        return f"{settings.CLOUDFRONT_DOCUMENTS_URL}/{key}"
    return f"https://{settings.S3_DOCUMENTS_BUCKET}.s3.amazonaws.com/{key}"
