"""Backend tests for the new POST /api/parties/bulk-delete and bulk-restore endpoints."""
import os
import time
import pytest
import requests

BASE = os.environ.get("REACT_APP_BACKEND_URL", "https://offline-billing-pro-2.preview.emergentagent.com").rstrip("/")
ADMIN_EMAIL = os.environ.get("TEST_ADMIN_EMAIL", "regalmarketing2024@gmail.com")
ADMIN_PASSWORD = os.environ.get("TEST_ADMIN_PASSWORD", "Rvasa@#9955")


def _s():
    s = requests.Session()
    s.headers.update({"Content-Type": "application/json"})
    return s


@pytest.fixture(scope="module")
def admin():
    s = _s()
    r = s.post(f"{BASE}/api/auth/login", json={"email": ADMIN_EMAIL, "password": ADMIN_PASSWORD}, timeout=20)
    body = r.json()
    if body.get("requires_wa_otp"):
        pytest.skip("Admin has wa_otp_enabled — disable before running")
    assert r.status_code == 200, r.text
    return s


@pytest.fixture(scope="module")
def company_id(admin):
    r = admin.get(f"{BASE}/api/companies", timeout=20)
    cos = r.json()
    if not cos:
        pytest.skip("No companies")
    return cos[0]["id"]


@pytest.fixture
def four_parties(admin, company_id):
    """Create 4 throwaway parties, yield their ids, no cleanup needed
    (bulk-delete tests delete them themselves)."""
    ids = []
    ts = int(time.time() * 1000)
    for i in range(4):
        r = admin.post(
            f"{BASE}/api/parties?company_id={company_id}",
            json={"name": f"BulkTest {ts}-{i}", "type": "customer", "phone": f"99999{i:05d}"},
            timeout=20,
        )
        assert r.status_code == 200, r.text
        ids.append(r.json()["id"])
    return ids


class TestBulkDelete:
    def test_requires_auth(self):
        r = _s().post(f"{BASE}/api/parties/bulk-delete", json={"ids": ["x"]}, timeout=20)
        assert r.status_code == 401

    def test_requires_admin(self):
        # Anonymous gets 401 — proxy for "admin required" since staff seeding is tricky in this env.
        r = _s().post(f"{BASE}/api/parties/bulk-delete", json={"ids": ["x"]}, timeout=20)
        assert r.status_code in (401, 403)

    def test_empty_ids_rejected(self, admin):
        r = admin.post(f"{BASE}/api/parties/bulk-delete", json={"ids": []}, timeout=20)
        assert r.status_code == 422
        assert "ids" in r.json().get("detail", "").lower() or "ids" in str(r.json())

    def test_unknown_ids_counted_as_skipped(self, admin):
        fake = "0" * 24
        r = admin.post(f"{BASE}/api/parties/bulk-delete", json={"ids": [fake]}, timeout=20)
        assert r.status_code == 200
        d = r.json()
        assert d["moved"] == 0
        assert d["skipped"] == 1

    def test_bulk_delete_and_restore_roundtrip(self, admin, four_parties, company_id):
        ids = four_parties
        # 1. Bulk delete all 4
        r = admin.post(f"{BASE}/api/parties/bulk-delete", json={"ids": ids}, timeout=20)
        assert r.status_code == 200, r.text
        d = r.json()
        assert d["moved"] == 4

        # 2. Confirm they're no longer in parties list
        plist = admin.get(f"{BASE}/api/parties", params={"company_id": company_id}, timeout=20).json()
        remaining = [p for p in plist if p["id"] in ids]
        assert len(remaining) == 0

        # 3. Bulk restore
        r2 = admin.post(f"{BASE}/api/parties/bulk-restore", json={"ids": ids}, timeout=20)
        assert r2.status_code == 200, r2.text
        assert r2.json()["restored"] == 4

        # 4. Confirm they're back
        plist2 = admin.get(f"{BASE}/api/parties", params={"company_id": company_id}, timeout=20).json()
        restored = [p for p in plist2 if p["id"] in ids]
        assert len(restored) == 4

        # 5. Final cleanup — delete one-by-one
        for pid in ids:
            admin.delete(f"{BASE}/api/parties/{pid}", timeout=20)

    def test_partial_failure(self, admin, four_parties):
        """Mix real ids with fake — moved=4, skipped=1."""
        ids = four_parties + ["0" * 24]
        r = admin.post(f"{BASE}/api/parties/bulk-delete", json={"ids": ids}, timeout=20)
        assert r.status_code == 200
        d = r.json()
        assert d["moved"] == 4
        assert d["skipped"] == 1
        # Cleanup
        admin.post(f"{BASE}/api/parties/bulk-restore", json={"ids": four_parties}, timeout=20)
        for pid in four_parties:
            admin.delete(f"{BASE}/api/parties/{pid}", timeout=20)
