"""Faisal Car Bazar - Comprehensive backend API tests."""
import os
import uuid
import pytest
import requests

BASE_URL = os.environ.get("REACT_APP_BACKEND_URL", "https://premium-auto-bazaar.preview.emergentagent.com").rstrip("/")
API = f"{BASE_URL}/api"

ADMIN_EMAIL = os.environ.get("ADMIN_EMAIL", "admin@faisalcarbazar.com")
ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "")


@pytest.fixture(scope="session")
def session():
    s = requests.Session()
    s.headers.update({"Content-Type": "application/json"})
    return s


@pytest.fixture(scope="session")
def token(session):
    r = session.post(f"{API}/auth/login", json={"email": ADMIN_EMAIL, "password": ADMIN_PASSWORD})
    assert r.status_code == 200, f"login failed: {r.text}"
    return r.json()["access_token"]


@pytest.fixture(scope="session")
def auth_headers(token):
    return {"Authorization": f"Bearer {token}"}


# ---------- Health ----------
def test_health(session):
    r = session.get(f"{API}/")
    assert r.status_code == 200
    assert r.json().get("status") == "ok"


# ---------- Cars (public) ----------
def test_list_cars_paginated(session):
    r = session.get(f"{API}/cars")
    assert r.status_code == 200
    d = r.json()
    for key in ["items", "total", "total_pages", "page", "page_size"]:
        assert key in d
    assert isinstance(d["items"], list)
    assert d["total"] >= 10


def test_filter_options(session):
    r = session.get(f"{API}/cars/filters/options")
    assert r.status_code == 200
    d = r.json()
    for key in ["brands", "fuel_types", "transmissions", "years"]:
        assert key in d and isinstance(d[key], list)
    assert len(d["brands"]) > 0


def test_filter_by_brand(session):
    r = session.get(f"{API}/cars", params={"brand": "BMW"})
    assert r.status_code == 200
    items = r.json()["items"]
    assert len(items) >= 1
    for i in items:
        assert i["brand"].lower() == "bmw"


def test_filter_by_fuel_and_transmission(session):
    r = session.get(f"{API}/cars", params={"fuel_type": "Diesel", "transmission": "Automatic"})
    assert r.status_code == 200
    for i in r.json()["items"]:
        assert i["fuel_type"] == "Diesel" and i["transmission"] == "Automatic"


def test_filter_year_price_range(session):
    r = session.get(f"{API}/cars", params={"year_min": 2020, "year_max": 2022, "price_min": 1000000, "price_max": 5000000})
    assert r.status_code == 200
    for i in r.json()["items"]:
        assert 2020 <= i["year"] <= 2022
        assert 1000000 <= i["price"] <= 5000000


def test_search_and_sort(session):
    r = session.get(f"{API}/cars", params={"search": "Mercedes", "sort": "price_desc"})
    assert r.status_code == 200
    items = r.json()["items"]
    assert len(items) >= 1
    prices = [i["price"] for i in items]
    assert prices == sorted(prices, reverse=True)


def test_status_and_featured_filter(session):
    r1 = session.get(f"{API}/cars", params={"status": "sold"})
    assert r1.status_code == 200
    for i in r1.json()["items"]:
        assert i["status"] == "sold"
    r2 = session.get(f"{API}/cars", params={"featured": "true"})
    assert r2.status_code == 200
    for i in r2.json()["items"]:
        assert i["featured"] is True


def test_get_single_car(session):
    r = session.get(f"{API}/cars")
    car_id = r.json()["items"][0]["id"]
    r2 = session.get(f"{API}/cars/{car_id}")
    assert r2.status_code == 200
    assert r2.json()["id"] == car_id


def test_get_car_not_found(session):
    r = session.get(f"{API}/cars/nonexistent-id")
    assert r.status_code == 404


# ---------- Gallery ----------
def test_gallery_list(session):
    r = session.get(f"{API}/gallery")
    assert r.status_code == 200
    items = r.json()["items"]
    assert len(items) > 0
    assert "title" in items[0] and "image_url" in items[0]


def test_gallery_category_filter(session):
    r = session.get(f"{API}/gallery", params={"category": "delivery"})
    assert r.status_code == 200
    for i in r.json()["items"]:
        assert i["category"] == "delivery"


# ---------- Owner ----------
def test_get_owner(session):
    r = session.get(f"{API}/owner")
    assert r.status_code == 200
    d = r.json()
    assert d["name"] and d["bio"] and "_id" not in d


# ---------- Auth ----------
def test_login_success(session):
    r = session.post(f"{API}/auth/login", json={"email": ADMIN_EMAIL, "password": ADMIN_PASSWORD})
    assert r.status_code == 200
    d = r.json()
    assert d["access_token"] and d["email"] == ADMIN_EMAIL


def test_login_wrong_password(session):
    r = session.post(f"{API}/auth/login", json={"email": ADMIN_EMAIL, "password": "wrong"})
    assert r.status_code == 401


def test_me_with_token(session, auth_headers):
    r = session.get(f"{API}/auth/me", headers=auth_headers)
    assert r.status_code == 200
    assert r.json()["email"] == ADMIN_EMAIL


def test_me_without_token(session):
    s = requests.Session()
    r = s.get(f"{API}/auth/me")
    assert r.status_code == 401


# ---------- Admin Cars CRUD ----------
def test_admin_create_update_delete_car(session, auth_headers):
    payload = {
        "name": "TEST_Honda Civic",
        "brand": "Honda",
        "model": "Civic VX",
        "year": 2019,
        "price": 1100000,
        "kilometers": 40000,
        "fuel_type": "Petrol",
        "transmission": "Manual",
        "color": "White",
        "description": "Test car",
        "images": [],
        "status": "available",
        "featured": False,
    }
    r = session.post(f"{API}/admin/cars", json=payload, headers=auth_headers)
    assert r.status_code == 200, r.text
    car = r.json()
    cid = car["id"]
    assert car["name"] == "TEST_Honda Civic"

    # Get
    r2 = session.get(f"{API}/cars/{cid}")
    assert r2.status_code == 200

    # Update
    r3 = session.put(f"{API}/admin/cars/{cid}", json={"price": 1050000, "status": "sold"}, headers=auth_headers)
    assert r3.status_code == 200
    assert r3.json()["price"] == 1050000
    assert r3.json()["status"] == "sold"

    # Verify persistence
    r3b = session.get(f"{API}/cars/{cid}")
    assert r3b.json()["price"] == 1050000

    # Delete
    r4 = session.delete(f"{API}/admin/cars/{cid}", headers=auth_headers)
    assert r4.status_code == 200

    # Verify gone
    r5 = session.get(f"{API}/cars/{cid}")
    assert r5.status_code == 404


def test_admin_cars_require_auth(session):
    s = requests.Session()
    r = s.post(f"{API}/admin/cars", json={"name": "x", "brand": "x", "model": "x", "year": 2020, "price": 1, "kilometers": 1, "fuel_type": "Petrol", "transmission": "Manual"})
    assert r.status_code == 401


def test_admin_stats(session, auth_headers):
    r = session.get(f"{API}/admin/stats", headers=auth_headers)
    assert r.status_code == 200
    d = r.json()
    for k in ["total_cars", "available_cars", "sold_cars", "sell_submissions", "contact_submissions"]:
        assert k in d


def test_admin_stats_no_auth(session):
    s = requests.Session()
    r = s.get(f"{API}/admin/stats")
    assert r.status_code == 401


# ---------- Sell ----------
def test_sell_submission(session):
    payload = {
        "name": "TEST_Seller",
        "mobile": "9999999999",
        "brand": "Honda",
        "model": "City",
        "year": 2018,
        "kilometers": 50000,
        "expected_price": 600000,
        "message": "Test",
        "images": [],
    }
    r = session.post(f"{API}/sell-submissions", json=payload)
    assert r.status_code == 200
    assert r.json()["success"] is True


# ---------- Contact ----------
def test_contact(session):
    r = session.post(f"{API}/contact", json={"name": "TEST_User", "phone": "9999999999", "message": "hello"})
    assert r.status_code == 200
    assert r.json()["success"] is True


# ---------- Newsletter ----------
def test_newsletter_dedup(session):
    email = f"test_{uuid.uuid4().hex[:8]}@example.com"
    r1 = session.post(f"{API}/newsletter", json={"email": email})
    assert r1.status_code == 200
    assert not r1.json().get("already", False)
    r2 = session.post(f"{API}/newsletter", json={"email": email})
    assert r2.status_code == 200
    assert r2.json().get("already") is True


# ---------- Admin Gallery ----------
def test_admin_gallery_add_delete(session, auth_headers):
    r = session.post(f"{API}/admin/gallery", json={"title": "TEST_item", "image_url": "https://example.com/x.jpg", "category": "showroom"}, headers=auth_headers)
    assert r.status_code == 200
    gid = r.json()["id"]
    r2 = session.delete(f"{API}/admin/gallery/{gid}", headers=auth_headers)
    assert r2.status_code == 200


# ---------- Admin Owner ----------
def test_admin_update_owner(session, auth_headers):
    cur = session.get(f"{API}/owner").json()
    r = session.put(f"{API}/admin/owner", json={
        "name": cur["name"],
        "title": cur["title"],
        "bio": cur["bio"],
        "photo_url": cur["photo_url"],
        "years_experience": cur["years_experience"],
        "cars_delivered": cur["cars_delivered"],
        "happy_customers": cur["happy_customers"],
    }, headers=auth_headers)
    assert r.status_code == 200
    assert r.json()["success"] is True
