import uuid
from pathlib import Path

import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from gnexus_creds.auth import actor_from_request
from gnexus_creds.db import Base, get_db
from gnexus_creds.main import create_app
from gnexus_creds.models import User
from gnexus_creds.services import Actor, ensure_user_key


@pytest.fixture()
def session_factory(tmp_path: Path):
    engine = create_engine(
        f"sqlite+pysqlite:///{tmp_path / 'test.db'}",
        connect_args={"check_same_thread": False},
    )
    Base.metadata.create_all(engine)
    yield sessionmaker(bind=engine, autoflush=False, expire_on_commit=False)
    engine.dispose()


@pytest.fixture()
def db_session(session_factory):
    with session_factory() as session:
        yield session


@pytest.fixture()
def user(db_session):
    row = User(
        id=uuid.uuid4(),
        auth_subject="auth-user-1",
        email="user@example.test",
        display_name="Test User",
        locale="en",
        status="enabled",
        system_role="admin",
        profile={},
    )
    db_session.add(row)
    db_session.flush()
    ensure_user_key(db_session, row)
    db_session.commit()
    return row


@pytest.fixture()
def actor(user):
    return Actor(user=user, channel="ui")


@pytest.fixture()
def app(session_factory, actor):
    app = create_app()

    async def override_db():
        with session_factory() as session:
            yield session

    async def override_actor():
        return actor

    app.dependency_overrides[get_db] = override_db
    app.dependency_overrides[actor_from_request] = override_actor
    return app


@pytest.fixture()
def auth_app(session_factory):
    app = create_app()

    async def override_db():
        with session_factory() as session:
            yield session

    app.dependency_overrides[get_db] = override_db
    return app
