"""تست‌های فاز ۳: onboarding و فعال‌سازی workspace (tenant)."""
from __future__ import annotations

import pytest


@pytest.fixture(autouse=True)
def enable_auth(monkeypatch):
    monkeypatch.setenv("AUTH_REQUIRED", "true")
    monkeypatch.setenv("JWT_SECRET", "test-jwt-secret")
    monkeypatch.setenv("PLATFORM_BASE_DOMAIN", "localhost")
    from app.core.config import get_settings, settings

    get_settings.cache_clear()
    fresh = get_settings()
    monkeypatch.setattr(settings, "auth_required", True)
    monkeypatch.setattr(settings, "jwt_secret", fresh.jwt_secret)
    monkeypatch.setattr(settings, "platform_base_domain", fresh.platform_base_domain)


async def _login(client, mobile: str) -> dict:
    await client.post("/api/v1/auth/otp/request", json={"mobile": mobile})
    resp = await client.post(
        "/api/v1/auth/otp/verify", json={"mobile": mobile, "code": "1234"}
    )
    assert resp.status_code == 200
    data = resp.json()
    return {"Authorization": f"Bearer {data['access_token']}"}, data["user_id"]


async def test_me_requires_onboarding_for_new_user(client):
    headers, user_id = await _login(client, "09121110001")

    resp = await client.get("/api/v1/me", headers=headers)
    assert resp.status_code == 200
    data = resp.json()
    assert data["user_id"] == user_id
    assert data["onboarding_required"] is True
    assert data["current_tenant_id"] is None
    assert data["memberships"] == []


async def test_full_onboarding_flow(client):
    headers, user_id = await _login(client, "09121110002")

    create = await client.post(
        "/api/v1/onboarding/tenant",
        json={
            "business_name": "کافه تربت",
            "slug": "cafe-torbat-2",
            "business_type": "cafe",
            "default_locale": "fa-IR",
            "timezone": "Asia/Tehran",
        },
        headers=headers,
    )
    assert create.status_code == 201, create.text
    body = create.json()
    tenant_id = body["tenant"]["id"]
    assert body["tenant"]["status"] == "pending_activation"
    assert body["tenant"]["onboarding_completed"] is False
    assert body["role"] == "tenant_owner"
    assert body["is_owner"] is True
    assert body["plan_code"] == "FREE"
    assert body["primary_domain"] == "cafe-torbat-2.localhost"
    assert body["domains"][0]["domain_type"] == "subdomain"
    assert body["domains"][0]["is_verified"] is True

    # اگر دوباره تلاش کنیم tenant دیگری بسازیم روی همین slug، باید خطای تکراری بگیریم.
    dup = await client.post(
        "/api/v1/onboarding/tenant",
        json={"business_name": "X", "slug": "cafe-torbat-2"},
        headers=headers,
    )
    assert dup.status_code == 409
    assert dup.json()["error"]["code"] == "slug_taken"

    branding = await client.patch(
        f"/api/v1/onboarding/tenant/{tenant_id}/branding",
        json={"primary_color": "#112233", "secondary_color": "#445566"},
        headers=headers,
    )
    assert branding.status_code == 200
    assert branding.json()["tenant"]["primary_color"] == "#112233"

    domain = await client.patch(
        f"/api/v1/onboarding/tenant/{tenant_id}/domain",
        json={"custom_domain": "cafe2.example.com"},
        headers=headers,
    )
    assert domain.status_code == 200
    hosts = [d["domain"] for d in domain.json()["domains"]]
    assert "cafe2.example.com" in hosts

    complete = await client.post(
        f"/api/v1/onboarding/tenant/{tenant_id}/complete", headers=headers
    )
    assert complete.status_code == 200
    completed_body = complete.json()
    assert completed_body["tenant"]["status"] == "active"
    assert completed_body["tenant"]["onboarding_completed"] is True

    me = await client.get("/api/v1/me", headers=headers)
    me_data = me.json()
    assert me_data["onboarding_required"] is False
    assert me_data["current_tenant_id"] == tenant_id
    assert len(me_data["memberships"]) == 1
    assert me_data["memberships"][0]["role"] == "tenant_owner"

    current = await client.get("/api/v1/tenant/current", headers=headers)
    assert current.status_code == 200
    assert current.json()["tenant"]["id"] == tenant_id

    my_tenants = await client.get("/api/v1/me/tenants", headers=headers)
    assert my_tenants.status_code == 200
    slugs = [t["tenant_slug"] for t in my_tenants.json()]
    assert "cafe-torbat-2" in slugs


async def test_onboarding_tenant_requires_auth(client):
    resp = await client.post(
        "/api/v1/onboarding/tenant",
        json={"business_name": "X", "slug": "no-auth-tenant"},
    )
    assert resp.status_code == 401


async def test_branding_forbidden_for_non_member(client):
    headers_owner, _ = await _login(client, "09121110003")
    create = await client.post(
        "/api/v1/onboarding/tenant",
        json={"business_name": "Owner Co", "slug": "owner-co"},
        headers=headers_owner,
    )
    tenant_id = create.json()["tenant"]["id"]

    headers_other, _ = await _login(client, "09121110004")
    resp = await client.patch(
        f"/api/v1/onboarding/tenant/{tenant_id}/branding",
        json={"primary_color": "#000000"},
        headers=headers_other,
    )
    assert resp.status_code == 403


async def test_complete_fails_without_required_fields(client):
    headers, _ = await _login(client, "09121110005")
    create = await client.post(
        "/api/v1/onboarding/tenant",
        json={"business_name": "بدون برند", "slug": "no-brand-co"},
        headers=headers,
    )
    tenant_id = create.json()["tenant"]["id"]

    # بدون تنظیم برندینگ کامل هم می‌توان تکمیل کرد (فیلدهای برندینگ اختیاری‌اند)،
    # اما تکمیل روی tenant دیگری که عضو آن نیستیم باید 403/404 بدهد.
    other_headers, _ = await _login(client, "09121110006")
    resp = await client.post(
        f"/api/v1/onboarding/tenant/{tenant_id}/complete", headers=other_headers
    )
    assert resp.status_code == 403

    ok = await client.post(
        f"/api/v1/onboarding/tenant/{tenant_id}/complete", headers=headers
    )
    assert ok.status_code == 200
    assert ok.json()["tenant"]["status"] == "active"


async def test_tenant_switch_between_multiple_tenants(client):
    headers, user_id = await _login(client, "09121110007")

    first = await client.post(
        "/api/v1/onboarding/tenant",
        json={"business_name": "First Co", "slug": "first-co"},
        headers=headers,
    )
    first_id = first.json()["tenant"]["id"]

    second = await client.post(
        "/api/v1/onboarding/tenant",
        json={"business_name": "Second Co", "slug": "second-co"},
        headers=headers,
    )
    second_id = second.json()["tenant"]["id"]

    # اولین tenant ساخته‌شده به‌عنوان current انتخاب می‌شود (چون current_tenant_id قبلاً خالی بود)؛
    # ساخت tenant دوم آن را تغییر نمی‌دهد.
    me = await client.get("/api/v1/me", headers=headers)
    assert me.json()["current_tenant_id"] == first_id
    assert len(me.json()["memberships"]) == 2

    switch = await client.post(
        "/api/v1/tenant/switch", json={"tenant_id": second_id}, headers=headers
    )
    assert switch.status_code == 200
    assert switch.json()["tenant"]["id"] == second_id

    current = await client.get("/api/v1/tenant/current", headers=headers)
    assert current.json()["tenant"]["id"] == second_id


async def test_tenant_switch_forbidden_for_non_member(client):
    headers_owner, _ = await _login(client, "09121110008")
    create = await client.post(
        "/api/v1/onboarding/tenant",
        json={"business_name": "Solo Co", "slug": "solo-co"},
        headers=headers_owner,
    )
    tenant_id = create.json()["tenant"]["id"]

    headers_other, _ = await _login(client, "09121110009")
    resp = await client.post(
        "/api/v1/tenant/switch", json={"tenant_id": tenant_id}, headers=headers_other
    )
    assert resp.status_code == 403
