import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool

from app.main import app
from app.database import Base2, Base3
from app.dependencies import get_db2, get_db3

from sqlalchemy import event
from sqlalchemy.engine import Engine

# Konfigurasi database in-memory SQLite untuk testing
SQLALCHEMY_DATABASE_URL = "sqlite:///:memory:"

engine = create_engine(
    SQLALCHEMY_DATABASE_URL,
    connect_args={"check_same_thread": False},
    poolclass=StaticPool,
)

@event.listens_for(engine, "connect")
def do_connect(dbapi_connection, connection_record):
    # Bypass PostgreSQL "public" schema error in SQLite by attaching a memory DB named "public"
    cursor = dbapi_connection.cursor()
    cursor.execute("ATTACH DATABASE ':memory:' AS public")
    cursor.close()

TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# Override fungsi dependensi get_db2 dan get_db3
def override_get_db():
    try:
        db = TestingSessionLocal()
        yield db
    finally:
        db.close()

app.dependency_overrides[get_db2] = override_get_db
app.dependency_overrides[get_db3] = override_get_db

@pytest.fixture(scope="session", autouse=True)
def setup_database():
    # Setup: Buat semua tabel sebelum tests berjalan
    Base2.metadata.create_all(bind=engine)
    Base3.metadata.create_all(bind=engine)
    yield
    # Teardown: Hapus tabel setelah semua test selesai
    Base2.metadata.drop_all(bind=engine)
    Base3.metadata.drop_all(bind=engine)

@pytest.fixture(scope="module")
def client():
    # Return TestClient instance
    with TestClient(app) as c:
        yield c

@pytest.fixture(scope="function")
def db_session():
    # Memberikan sesi DB khusus untuk unit test tanpa HTTP layer
    db = TestingSessionLocal()
    try:
        yield db
    finally:
        db.close()

@pytest.fixture(scope="function")
def authenticated_client(client):
    from app.main import app
    from app.utils.dependencies import get_current_user
    
    # Buat mock user object yang memiliki atribut yang dibutuhkan
    mock_user = type("User", (), {
        "id": 1,
        "username": "test_dse",
        "role": 5, # Role DSE
        "brand": "IOH",
        "territory_id": 1,
        "is_active": 1
    })
    
    app.dependency_overrides[get_current_user] = lambda: mock_user
    yield client
    app.dependency_overrides.pop(get_current_user, None)
