import os
from typing import Generator

os.environ.setdefault("WEB_SENTINEL_POSTGRES_URL", "sqlite:///./test_admin.db")
os.environ.setdefault("WEB_SENTINEL_ADMIN_JWT_SECRET", "test-secret")

from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from admin.backend.app.database import get_session
from admin.backend.app.main import create_app
from admin.backend.app.models import Base
from admin.backend.app.models.admin_user import AdminUser
from admin.backend.app.models.license import License
from admin.backend.app.security import hash_password

engine = create_engine(os.environ["WEB_SENTINEL_POSTGRES_URL"], future=True)
TestingSessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False, future=True)

Base.metadata.create_all(bind=engine)


def override_session() -> Generator:
    db = TestingSessionLocal()
    try:
        yield db
    finally:
        db.close()


app = create_app()
app.dependency_overrides[get_session] = override_session
client = TestClient(app)


def setup_module() -> None:
    Base.metadata.create_all(bind=engine)
    with TestingSessionLocal() as session:
        session.query(License).delete()
        session.query(AdminUser).delete()
        session.add(
            AdminUser(
                email="sysop@web-sentinel.com",
                hashed_password=hash_password("secret"),
                role="super-admin",
            )
        )
        session.add(
            License(
                email="existing@example.com",
                api_key="ws_live_existing",
                tier="PRO",
                status="active",
                max_domains=50,
                max_users=5,
            )
        )
        session.commit()


def teardown_module() -> None:
    Base.metadata.drop_all(bind=engine)


def _login(email: str = "sysop@web-sentinel.com", password: str = "secret") -> str:
    response = client.post(
        "/api/v1/auth/login",
        data={"username": email, "password": password},
        headers={"Content-Type": "application/x-www-form-urlencoded"},
    )
    assert response.status_code == 200
    return response.json()["access_token"]


def test_list_filters_and_details():
    token = _login()
    response = client.get("/api/v1/licenses/", headers={"Authorization": f"Bearer {token}"})
    assert response.status_code == 200
    data = response.json()
    assert data["total"] >= 1
    assert any(item["api_key"] == "ws_live_existing" for item in data["items"])

    filtered = client.get(
        "/api/v1/licenses/",
        params={"status": "active", "email": "existing@example.com"},
        headers={"Authorization": f"Bearer {token}"},
    )
    assert filtered.status_code == 200
    filtered_data = filtered.json()
    assert filtered_data["total"] == 1
    assert filtered_data["items"][0]["email"] == "existing@example.com"

    detail = client.get(
        "/api/v1/licenses/ws_live_existing",
        headers={"Authorization": f"Bearer {token}"},
    )
    assert detail.status_code == 200
    assert detail.json()["email"] == "existing@example.com"


def test_create_update_export_and_delete_license():
    token = _login()
    payload = {
        "email": "new@example.com",
        "tier": "starter",
        "status": "active",
        "max_domains": 20,
        "max_users": 2,
        "stripe_customer_id": "cus_123",
    }
    created = client.post(
        "/api/v1/licenses/",
        json=payload,
        headers={"Authorization": f"Bearer {token}"},
    )
    assert created.status_code == 201
    created_payload = created.json()
    api_key = created_payload["api_key"]
    assert created_payload["stripe_customer_id"] == "cus_123"

    updated = client.patch(
        f"/api/v1/licenses/{api_key}",
        json={"status": "suspended", "stripe_subscription_id": "sub_456"},
        headers={"Authorization": f"Bearer {token}"},
    )
    assert updated.status_code == 200
    updated_payload = updated.json()
    assert updated_payload["status"] == "suspended"
    assert updated_payload["stripe_subscription_id"] == "sub_456"

    export_json = client.get(
        "/api/v1/licenses/export",
        params={"format": "json"},
        headers={"Authorization": f"Bearer {token}"},
    )
    assert export_json.status_code == 200
    data_json = export_json.json()
    assert data_json["count"] >= 2
    assert any(item["api_key"] == api_key for item in data_json["items"])

    export_csv = client.get(
        "/api/v1/licenses/export",
        params={"format": "csv", "status": "suspended"},
        headers={"Authorization": f"Bearer {token}"},
    )
    assert export_csv.status_code == 200
    assert "content" in export_csv.json()

    history = client.get(
        f"/api/v1/licenses/{api_key}/history",
        headers={"Authorization": f"Bearer {token}"},
    )
    assert history.status_code == 200

    deleted = client.delete(
        f"/api/v1/licenses/{api_key}",
        headers={"Authorization": f"Bearer {token}"},
    )
    assert deleted.status_code == 204

    missing = client.get(
        f"/api/v1/licenses/{api_key}",
        headers={"Authorization": f"Bearer {token}"},
    )
    assert missing.status_code == 404
