import uuid
import pytest
from fastapi import status
from app.database import get_database
from app.repositories.session_repository import get_session_by_id

def test_init_session_success(client):
    # 1. Register a tenant first
    domain = f"shop-{uuid.uuid4().hex[:6]}.com"
    reg_resp = client.post("/api/v1/tenant/register", json={
        "domain": domain,
        "name": "Session Test Store"
    })
    assert reg_resp.status_code == status.HTTP_201_CREATED
    site_id = reg_resp.json()["siteId"]
    
    # 2. Call session init with valid siteId and matching Origin header
    headers = {"Origin": f"http://{domain}"}
    init_resp = client.post("/api/v1/session/init", json={"siteId": site_id}, headers=headers)
    
    assert init_resp.status_code == status.HTTP_201_CREATED
    data = init_resp.json()
    assert "sessionId" in data
    assert data["sessionId"].startswith("sess_")

@pytest.mark.anyio
async def test_init_session_with_logged_in_user(client):
    domain = f"user-{uuid.uuid4().hex[:6]}.com"
    reg_resp = client.post("/api/v1/tenant/register", json={
        "domain": domain,
        "name": "User Identity Store"
    })
    site_id = reg_resp.json()["siteId"]
    
    headers = {"Origin": f"http://{domain}"}
    user_payload = {
        "siteId": site_id,
        "user": {
            "id": "usr_test_101",
            "name": "John Visitor",
            "email": "john.visitor@example.com"
        }
    }
    init_resp = client.post("/api/v1/session/init", json=user_payload, headers=headers)
    assert init_resp.status_code == status.HTTP_201_CREATED
    session_id = init_resp.json()["sessionId"]

    # Verify session document in MongoDB contains user identity
    db = get_database()
    session_doc = await get_session_by_id(db, session_id)
    assert session_doc is not None
    assert session_doc["userId"] == "usr_test_101"
    assert session_doc["userName"] == "John Visitor"
    assert session_doc["userEmail"] == "john.visitor@example.com"

@pytest.mark.anyio
async def test_init_session_x_forwarded_for_ip_capture(client):
    domain = f"ip-{uuid.uuid4().hex[:6]}.com"
    reg_resp = client.post("/api/v1/tenant/register", json={
        "domain": domain,
        "name": "IP Capture Store"
    })
    site_id = reg_resp.json()["siteId"]
    
    headers = {
        "Origin": f"http://{domain}",
        "X-Forwarded-For": "203.0.113.195, 70.41.3.18"
    }
    init_resp = client.post("/api/v1/session/init", json={"siteId": site_id}, headers=headers)
    assert init_resp.status_code == status.HTTP_201_CREATED
    session_id = init_resp.json()["sessionId"]

    # Verify session document in MongoDB contains first IP from X-Forwarded-For
    db = get_database()
    session_doc = await get_session_by_id(db, session_id)
    assert session_doc is not None
    assert session_doc["ipAddress"] == "203.0.113.195"

def test_init_session_unknown_site_id(client):
    headers = {"Origin": "http://example.com"}
    response = client.post("/api/v1/session/init", json={"siteId": "site_nonexistent_999"}, headers=headers)
    assert response.status_code == status.HTTP_404_NOT_FOUND
    assert "Tenant not found" in response.json()["detail"]

def test_init_session_unauthorized_origin(client):
    domain = f"authorized-{uuid.uuid4().hex[:6]}.com"
    reg_resp = client.post("/api/v1/tenant/register", json={
        "domain": domain,
        "name": "Authorized Store"
    })
    site_id = reg_resp.json()["siteId"]
    
    unauthorized_headers = {"Origin": "http://unauthorized-attacker.com"}
    response = client.post("/api/v1/session/init", json={"siteId": site_id}, headers=unauthorized_headers)
    
    assert response.status_code == status.HTTP_403_FORBIDDEN
    assert "not authorized" in response.json()["detail"]

def test_init_session_validation_error(client):
    headers = {"Origin": "http://example.com"}
    response = client.post("/api/v1/session/init", json={"siteId": ""}, headers=headers)
    assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
