import os

# Must run before app imports so test settings apply.
os.environ.setdefault("DATABASE_URL", "sqlite:///:memory:")
os.environ.setdefault("SCHEDULER_ENABLED", "false")
os.environ.setdefault("SECRET_KEY", "test-secret-key-for-jwt-signing-minimum-32chars")
os.environ.setdefault("LOG_JSON", "false")
os.environ.setdefault("AUTH_RATE_LIMIT_REQUESTS", "1000")
os.environ.setdefault("AUTH_RATE_LIMIT_WINDOW_SECONDS", "60")

import pytest
from datetime import date, timedelta
from decimal import Decimal

from fastapi.testclient import TestClient
from sqlalchemy.orm import Session

from app.core.config import get_settings
from app.core.security import get_password_hash
from app.db.base import Base
from app.db.session import engine, SessionLocal
from app.main import app
from app.api.deps import get_db
from app.models.agency import Agency
from app.models.customer import Customer
from app.models.enums import PaymentStatus, PolicyStatus, UserRole
from app.models.policy import Policy
from app.models.user import User
from app.models.vehicle import Vehicle
from app.utils.rate_limit import auth_rate_limiter

get_settings.cache_clear()


@pytest.fixture(autouse=True)
def reset_auth_rate_limiter():
    auth_rate_limiter.reset()
    yield
    auth_rate_limiter.reset()


@pytest.fixture(scope="session", autouse=True)
def create_test_database():
    import app.models  # noqa: F401

    Base.metadata.create_all(bind=engine)
    yield
    Base.metadata.drop_all(bind=engine)


@pytest.fixture
def db() -> Session:
    session = SessionLocal()
    for table in reversed(Base.metadata.sorted_tables):
        session.execute(table.delete())
    session.commit()
    yield session
    session.rollback()
    session.close()


@pytest.fixture
def seed_data(db: Session):
    agency = Agency(name="Test Agency", phone="9999999999", email="test@agency.local")
    db.add(agency)
    db.flush()

    admin = User(
        agency_id=agency.id,
        email="admin@test.com",
        full_name="Test Admin",
        hashed_password=get_password_hash("Test@12345"),
        role=UserRole.ADMIN,
        is_active=True,
    )
    db.add(admin)

    customer = Customer(agency_id=agency.id, name="Ramesh Kumar", mobile="9876543210")
    db.add(customer)
    db.flush()

    vehicle = Vehicle(customer_id=customer.id, registration_number="MH12AB1234", vehicle_type="car")
    db.add(vehicle)
    db.flush()

    policy = Policy(
        agency_id=agency.id,
        customer_id=customer.id,
        vehicle_id=vehicle.id,
        policy_number="POL-TEST-001",
        policy_end_date=date.today() + timedelta(days=20),
        total_commission=Decimal("1000.00"),
        total_paid=Decimal("0.00"),
        pending_amount=Decimal("1000.00"),
        payment_status=PaymentStatus.PENDING,
        status=PolicyStatus.ACTIVE,
    )
    db.add(policy)
    db.commit()
    db.refresh(policy)
    return {"agency": agency, "admin": admin, "customer": customer, "vehicle": vehicle, "policy": policy}


@pytest.fixture
def client(db: Session):
    def override_get_db():
        yield db

    app.dependency_overrides[get_db] = override_get_db
    with TestClient(app) as test_client:
        yield test_client
    app.dependency_overrides.clear()


@pytest.fixture
def auth_headers(client: TestClient, seed_data):
    response = client.post("/api/v1/auth/login", json={"email": "admin@test.com", "password": "Test@12345"})
    assert response.status_code == 200
    token = response.json()["access_token"]
    return {"Authorization": f"Bearer {token}"}
