"""User management routes"""
from fastapi import APIRouter, HTTPException
from db import get_database
from models import UserCreate, UserUpdate, User
from datetime import datetime
from typing import Optional
from bson import ObjectId
from bson.errors import InvalidId

router = APIRouter()


@router.post("/register", response_model=dict)
async def register_user(user_data: UserCreate):
    """
    Register or get user (idempotent).

    Uses upsert pattern to ensure one user per email.
    If user already exists, returns existing user.
    Called after Firebase Google Auth on frontend.
    """
    db = get_database()

    try:
        # Upsert: Update if exists, insert if not
        result = db.users.update_one(
            {"email": user_data.email},
            {
                "$setOnInsert": {
                    "email": user_data.email,
                    "displayName": user_data.displayName or user_data.email.split("@")[0],
                    "photoURL": user_data.photoURL,
                    "theme": "light",
                    "createdAt": datetime.utcnow()
                },
                "$set": {
                    "updatedAt": datetime.utcnow()
                }
            },
            upsert=True
        )

        # Fetch the user (either newly created or existing)
        user = db.users.find_one({"email": user_data.email})
        if not user:
            raise HTTPException(
                status_code=500, detail="Failed to retrieve user after upsert")

        return {
            "id": str(user["_id"]),
            "email": user["email"],
            "displayName": user["displayName"],
            "photoURL": user.get("photoURL"),
            "theme": user.get("theme", "light"),
            "backgroundImage": user.get("backgroundImage"),
            "backgroundImages": user.get("backgroundImages", []),
            "reminder": user.get("reminder"),
            "createdAt": user["createdAt"].isoformat(),
            "updatedAt": user["updatedAt"].isoformat(),
            "message": "User registered successfully" if result.upserted_id else "User already exists"
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=500, detail=f"Registration failed: {str(e)}")


@router.get("/by-email/{email}", response_model=dict)
async def get_user_by_email(email: str):
    """Get user profile by email (called after Firebase Auth)."""
    db = get_database()

    try:
        user = db.users.find_one({"email": email})
        if not user:
            raise HTTPException(status_code=404, detail="User not found")

        return {
            "id": str(user["_id"]),
            "email": user["email"],
            "displayName": user.get("displayName"),
            "photoURL": user.get("photoURL"),
            "theme": user.get("theme", "light"),
            "backgroundImage": user.get("backgroundImage"),
            "backgroundImages": user.get("backgroundImages", []),
            "reminder": user.get("reminder"),
            "tutorial": user.get("tutorial"),
            "createdAt": user["createdAt"].isoformat(),
            "updatedAt": user["updatedAt"].isoformat()
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=500, detail=f"Failed to fetch user: {str(e)}")


@router.get("/{user_id}", response_model=dict)
async def get_user_by_id(user_id: str):
    """Get user profile by ID."""
    db = get_database()

    try:
        user_oid = ObjectId(user_id)
    except InvalidId:
        raise HTTPException(status_code=400, detail="Invalid user ID format")

    try:
        user = db.users.find_one({"_id": user_oid})
        if not user:
            raise HTTPException(status_code=404, detail="User not found")

        return {
            "id": str(user["_id"]),
            "email": user["email"],
            "displayName": user.get("displayName"),
            "photoURL": user.get("photoURL"),
            "theme": user.get("theme", "light"),
            "backgroundImage": user.get("backgroundImage"),
            "backgroundImages": user.get("backgroundImages", []),
            "createdAt": user["createdAt"].isoformat(),
            "updatedAt": user["updatedAt"].isoformat()
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=500, detail=f"Failed to fetch user: {str(e)}")


@router.put("/{user_id}", response_model=dict)
async def update_user(user_id: str, user_data: UserUpdate):
    """Update user profile."""
    db = get_database()

    try:
        user_oid = ObjectId(user_id)
    except InvalidId:
        raise HTTPException(status_code=400, detail="Invalid user ID format")

    try:
        # Prepare update data (exclude None values)
        update_data = user_data.model_dump(exclude_unset=True)
        update_data["updatedAt"] = datetime.utcnow()

        result = db.users.update_one(
            {"_id": user_oid},
            {"$set": update_data}
        )

        if result.matched_count == 0:
            raise HTTPException(status_code=404, detail="User not found")

        # Fetch and return updated user
        user = db.users.find_one({"_id": user_oid})
        return {
            "id": str(user["_id"]),
            "email": user["email"],
            "displayName": user.get("displayName"),
            "photoURL": user.get("photoURL"),
            "theme": user.get("theme", "light"),
            "backgroundImage": user.get("backgroundImage"),
            "backgroundImages": user.get("backgroundImages", []),
            "tutorial": user.get("tutorial"),
            "createdAt": user["createdAt"].isoformat(),
            "updatedAt": user["updatedAt"].isoformat(),
            "message": "User updated successfully"
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Update failed: {str(e)}")


@router.delete("/{user_id}")
async def delete_user(user_id: str):
    """Delete user account and all associated data."""
    db = get_database()

    try:
        user_oid = ObjectId(user_id)
    except InvalidId:
        raise HTTPException(status_code=400, detail="Invalid user ID format")

    try:
        # Delete user
        user_result = db.users.delete_one({"_id": user_oid})
        if user_result.deleted_count == 0:
            raise HTTPException(status_code=404, detail="User not found")

        # Delete all user's entries
        entry_result = db.entries.delete_many({"userId": user_oid})

        return {
            "message": "User deleted successfully",
            "user_deleted": user_result.deleted_count,
            "entries_deleted": entry_result.deleted_count
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=500, detail=f"Deletion failed: {str(e)}")
