import uuid

import pytest
from httpx import AsyncClient


USER_PAYLOAD = {
    "email": "guest.merge.user@inphb.ci",
    "motDePasse": "TestPass123!",
    "nom": "Guest",
    "prenom": "Merge",
}

SIGNALEMENT_PAYLOAD = {
    "titre": "Signalement invité",
    "description": "Description guest",
    "type": "HARCELEMENT_MORAL",
    "modeIdentification": "ANONYME",
}


async def _create_guest_session(client: AsyncClient) -> str:
    response = await client.post(
        "/api/v1/guest/sessions",
        json={"telephone": "+2250700000000", "deviceFingerprint": "fp-device-001"},
    )
    assert response.status_code == 201
    return response.json()["data"]["guestId"]


async def _get_user_token(client: AsyncClient) -> str:
    await client.post("/api/v1/auth/signup", json=USER_PAYLOAD)
    login = await client.post(
        "/api/v1/auth/login",
        json={"email": USER_PAYLOAD["email"], "motDePasse": USER_PAYLOAD["motDePasse"]},
    )
    assert login.status_code == 200
    return login.json()["data"]["token"]


@pytest.mark.asyncio
async def test_create_guest_session(client: AsyncClient):
    guest_id = await _create_guest_session(client)
    assert guest_id


@pytest.mark.asyncio
async def test_guest_signalement_create_list_and_detail(client: AsyncClient):
    guest_id = await _create_guest_session(client)

    create = await client.post(
        "/api/v1/signalements/",
        json=SIGNALEMENT_PAYLOAD,
        headers={"X-Guest-Id": guest_id},
    )
    assert create.status_code == 201
    data = create.json()["data"]
    assert data["sourceActeur"] == "GUEST"
    assert data["acteurId"] == guest_id

    list_response = await client.get(
        "/api/v1/signalements/guest/me",
        headers={"X-Guest-Id": guest_id},
    )
    assert list_response.status_code == 200
    assert list_response.json()["data"]["total"] >= 1

    signalement_id = data["id"]
    detail = await client.get(
        f"/api/v1/signalements/{signalement_id}",
        headers={"X-Guest-Id": guest_id},
    )
    assert detail.status_code == 200
    assert detail.json()["data"]["sourceActeur"] == "GUEST"


@pytest.mark.asyncio
async def test_guest_merge_preview(client: AsyncClient):
    guest_id = await _create_guest_session(client)
    token = await _get_user_token(client)

    preview = await client.get(
        f"/api/v1/guest/sessions/{guest_id}/merge-preview",
        headers={"Authorization": f"Bearer {token}"},
    )
    assert preview.status_code == 200
    data = preview.json()["data"]
    assert data["guestId"] == guest_id
    assert data["canMerge"] is True


@pytest.mark.asyncio
async def test_guest_merge_idempotent_replay(client: AsyncClient):
    guest_id = await _create_guest_session(client)
    token = await _get_user_token(client)
    idem_key = str(uuid.uuid4())

    first = await client.post(
        f"/api/v1/guest/sessions/{guest_id}/merge",
        json={"acceptPolicy": "MERGE_ALL", "resolutions": []},
        headers={"Authorization": f"Bearer {token}", "Idempotency-Key": idem_key},
    )
    assert first.status_code == 200
    first_data = first.json()["data"]
    assert first_data["merged"] is True

    replay = await client.post(
        f"/api/v1/guest/sessions/{guest_id}/merge",
        json={"acceptPolicy": "MERGE_ALL", "resolutions": []},
        headers={"Authorization": f"Bearer {token}", "Idempotency-Key": idem_key},
    )
    assert replay.status_code == 200
    replay_data = replay.json()["data"]

    assert replay_data["merged"] is True
    assert replay_data["guestId"] == first_data["guestId"]
    assert replay_data["userId"] == first_data["userId"]
