"""PATCH /api/users/me profile API."""
from datetime import datetime, timezone
from unittest.mock import AsyncMock, MagicMock
from uuid import uuid4

import pytest
from fastapi.testclient import TestClient

from src.domain.auth.models import User
from src.main import app


@pytest.fixture
def client():
    return TestClient(app)


def test_users_me_patch_in_openapi(client: TestClient):
    schema = client.app.openapi()
    assert "/api/users/me" in schema["paths"]
    assert "patch" in schema["paths"]["/api/users/me"]


@pytest.mark.asyncio
async def test_patch_users_me_updates_via_repository():
    """Ensure PATCH handler calls ``UserRepository.update_profile`` with normalized fields."""
    from src.domain.auth.users_router import patch_current_user_profile
    from src.domain.auth.schemas import UserProfileUpdate

    uid = uuid4()
    now = datetime.now(timezone.utc)

    mock_user = User(
        id=uid,
        email="x@y.com",
        first_name="Old",
        last_name=None,
        display_name=None,
        phone=None,
        company=None,
        avatar_url=None,
        ui_theme="system",
        email_verified_at=now,
        last_login_at=None,
        created_at=now,
        updated_at=now,
    )

    updated_user = User(
        id=uid,
        email="x@y.com",
        first_name="New",
        last_name=None,
        display_name=None,
        phone=None,
        company=None,
        avatar_url=None,
        ui_theme="system",
        email_verified_at=now,
        last_login_at=None,
        created_at=now,
        updated_at=now,
    )

    with pytest.MonkeyPatch.context() as mp:
        from src.domain.auth import users_router as ur

        mock_repo = MagicMock()
        mock_repo.update_profile = AsyncMock(return_value=updated_user)
        mock_repo.get_by_id = AsyncMock(return_value=mock_user)

        def fake_repo_ctor(db):
            return mock_repo

        mp.setattr(ur, "UserRepository", fake_repo_ctor)

        out = await patch_current_user_profile(
            UserProfileUpdate(first_name="  New  "),
            user=mock_user,
            db=MagicMock(),
        )
        assert out.first_name == "New"
        mock_repo.update_profile.assert_awaited_once()
        call_kw = mock_repo.update_profile.await_args
        assert call_kw[0][0] == uid
        assert call_kw[1]["first_name"] == "New"


@pytest.mark.asyncio
async def test_patch_users_me_passes_ui_theme_to_repository():
    from src.domain.auth.users_router import patch_current_user_profile
    from src.domain.auth.schemas import UserProfileUpdate

    uid = uuid4()
    now = datetime.now(timezone.utc)

    mock_user = User(
        id=uid,
        email="x@y.com",
        first_name=None,
        last_name=None,
        display_name=None,
        phone=None,
        company=None,
        avatar_url=None,
        ui_theme="system",
        email_verified_at=now,
        last_login_at=None,
        created_at=now,
        updated_at=now,
    )

    updated_user = User(
        id=uid,
        email="x@y.com",
        first_name=None,
        last_name=None,
        display_name=None,
        phone=None,
        company=None,
        avatar_url=None,
        ui_theme="dark",
        email_verified_at=now,
        last_login_at=None,
        created_at=now,
        updated_at=now,
    )

    with pytest.MonkeyPatch.context() as mp:
        from src.domain.auth import users_router as ur

        mock_repo = MagicMock()
        mock_repo.update_profile = AsyncMock(return_value=updated_user)
        mock_repo.get_by_id = AsyncMock(return_value=mock_user)

        def fake_repo_ctor(db):
            return mock_repo

        mp.setattr(ur, "UserRepository", fake_repo_ctor)

        out = await patch_current_user_profile(
            UserProfileUpdate(ui_theme="dark"),
            user=mock_user,
            db=MagicMock(),
        )
        assert out.ui_theme == "dark"
        mock_repo.update_profile.assert_awaited_once()
        assert mock_repo.update_profile.await_args[1]["ui_theme"] == "dark"
