from __future__ import annotations

from fastapi import HTTPException, status
from sqlalchemy.orm import Session

from app.models import User, UserRole
from app.schemas import ProfileUpdate
from app.security import hash_password


def _non_empty_text(value: str | None, field_label: str) -> str:
    text = (value or "").strip()
    if not text:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"{field_label} is required and cannot be blank.",
        )
    return text


def serialize_user_public(user: User, _db: Session | None = None):
    from app.schemas import RoleEnum, UserPublic
    from app.services.admin_service import media_public_url

    role = user.role.value if isinstance(user.role, UserRole) else str(user.role)
    image_url = media_public_url(getattr(user, "profile_image", None))
    return UserPublic(
        id=user.id,
        email=user.email,
        full_name=user.full_name,
        phone_number=user.phone_number,
        address=user.address,
        postal_code=user.postal_code,
        profile_image=getattr(user, "profile_image", None),
        profile_image_url=image_url,
        has_profile_image=bool(getattr(user, "profile_image", None)),
        role=RoleEnum(role),
        is_active=user.is_active,
        email_verified=bool(user.email_verified),
        created_at=user.created_at,
    )


def update_user_profile(db: Session, user: User, body: ProfileUpdate) -> User:
    if body.email is not None:
        email = str(body.email).strip()
        if not email:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Email is required and cannot be blank.",
            )
        if email != user.email:
            user.email = email
    if body.full_name is not None:
        user.full_name = _non_empty_text(body.full_name, "Full name")
    if body.phone_number is not None:
        user.phone_number = _non_empty_text(body.phone_number, "Phone number")
    if body.address is not None:
        user.address = _non_empty_text(body.address, "Address")
    if body.postal_code is not None:
        user.postal_code = _non_empty_text(body.postal_code, "Postal code")
    if body.password is not None:
        password = (body.password or "").strip()
        if password:
            user.hashed_password = hash_password(password)

    db.commit()
    db.refresh(user)
    return user
