"""تست‌های OTP و ثبت‌نام خودکار."""
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")
    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)


async def test_otp_request_and_verify_new_user(client):
    mobile = "09123456789"
    req = await client.post(
        "/api/v1/auth/otp/request",
        json={"mobile": mobile, "context": "admin"},
    )
    assert req.status_code == 200
    assert req.json()["expires_in"] == 120

    verify = await client.post(
        "/api/v1/auth/otp/verify",
        json={"mobile": mobile, "code": "1234", "context": "admin"},
    )
    assert verify.status_code == 200
    data = verify.json()
    assert data["is_new_user"] is True
    assert data["role"] == "pending_tenant_admin"
    assert "access_token" in data
    assert "refresh_token" in data


async def test_otp_verify_existing_user(client):
    mobile = "09111111111"
    await client.post("/api/v1/auth/otp/request", json={"mobile": mobile})
    first = await client.post(
        "/api/v1/auth/otp/verify",
        json={"mobile": mobile, "code": "1234"},
    )
    assert first.json()["is_new_user"] is True

    await client.post("/api/v1/auth/otp/request", json={"mobile": mobile})
    second = await client.post(
        "/api/v1/auth/otp/verify",
        json={"mobile": mobile, "code": "1234"},
    )
    assert second.status_code == 200
    assert second.json()["is_new_user"] is False


async def test_otp_verify_invalid_code(client):
    mobile = "09222222222"
    await client.post("/api/v1/auth/otp/request", json={"mobile": mobile})
    resp = await client.post(
        "/api/v1/auth/otp/verify",
        json={"mobile": mobile, "code": "000000"},
    )
    assert resp.status_code == 401


async def test_otp_request_skips_unexpired_code(client):
    mobile = "09444444444"
    first = await client.post("/api/v1/auth/otp/request", json={"mobile": mobile})
    assert first.status_code == 200
    assert first.json()["skipped"] is False

    second = await client.post("/api/v1/auth/otp/request", json={"mobile": mobile})
    assert second.status_code == 200
    body = second.json()
    assert body["skipped"] is True
    assert body["message"] == "کد قبلاً ارسال شده"

    forced = await client.post(
        "/api/v1/auth/otp/request",
        json={"mobile": mobile, "force_sms": True},
    )
    assert forced.status_code == 200
    assert forced.json()["skipped"] is False


async def test_platform_admin_mobile_gets_admin_role(client, monkeypatch):
    from app.core.config import get_settings, settings

    monkeypatch.setenv("PLATFORM_ADMIN_MOBILES", "09155105404")
    get_settings.cache_clear()
    fresh = get_settings()
    monkeypatch.setattr(settings, "platform_admin_mobiles", fresh.platform_admin_mobiles)

    mobile = "09155105404"
    await client.post("/api/v1/auth/otp/request", json={"mobile": mobile})
    verify = await client.post(
        "/api/v1/auth/otp/verify",
        json={"mobile": mobile, "code": "1234"},
    )
    assert verify.status_code == 200
    assert verify.json()["role"] == "platform_admin"


async def test_admin_tenant_with_otp_token(client):
    mobile = "09333333333"
    await client.post("/api/v1/auth/otp/request", json={"mobile": mobile})
    auth = await client.post(
        "/api/v1/auth/otp/verify",
        json={"mobile": mobile, "code": "1234"},
    )
    token = auth.json()["access_token"]
    headers = {"Authorization": f"Bearer {token}"}

    created = await client.post(
        "/api/v1/admin/tenants",
        json={"name": "My Shop", "slug": "my-shop"},
        headers=headers,
    )
    assert created.status_code == 201
    body = created.json()
    assert body["slug"] == "my-shop"
    assert body["owner_user_id"] == auth.json()["user_id"]

    listed = await client.get("/api/v1/admin/tenants", headers=headers)
    assert listed.status_code == 200
    assert listed.json()["meta"]["total_items"] == 1
