from __future__ import annotations

from sqlalchemy import create_engine
from sqlalchemy.orm import Session, sessionmaker
from sqlalchemy.pool import StaticPool

from app.db.base import Base
from app.schemas.auth import LoginRequest
from app.schemas.settings import SettingsWrite
from app.services.auth import AuthService
from app.services.employee import EmployeeService
from app.services.settings import SettingsService


def build_session() -> Session:
    engine = create_engine(
        "sqlite+pysqlite:///:memory:",
        connect_args={"check_same_thread": False},
        poolclass=StaticPool,
    )
    Base.metadata.create_all(bind=engine)
    session_factory = sessionmaker(bind=engine, autoflush=False, autocommit=False)
    return session_factory()


def test_employee_can_login_with_seed_default_password() -> None:
    with build_session() as db:
        employee = EmployeeService(db).list_employees()[0]
        result = AuthService(db).login(
            LoginRequest(username=employee.email, password="123456")
        )

        assert result.ok is True
        assert result.user.username == employee.email
        assert result.user.name == employee.name
        assert result.user.roleCodes
        assert result.user.isAdmin is False


def test_admin_can_login_with_database_password() -> None:
    with build_session() as db:
        settings_service = SettingsService(db)
        payload = settings_service.get_settings_snapshot().model_dump()
        payload["adminForm"]["adminAccount"] = "superadmin"
        payload["adminForm"]["newPassword"] = "admin123"
        payload["adminForm"]["confirmPassword"] = "admin123"
        settings_service.save_settings_snapshot(SettingsWrite(**payload))

        result = AuthService(db).login(
            LoginRequest(username="superadmin", password="admin123")
        )

        assert result.ok is True
        assert result.user.username == "superadmin"
        assert result.user.isAdmin is True
        assert result.user.roleCodes == ["manager"]


def test_disabled_employee_cannot_login() -> None:
    with build_session() as db:
        service = EmployeeService(db)
        employee = service.list_employees()[0]
        service.disable_employee(employee.id)

        try:
            AuthService(db).login(LoginRequest(username=employee.email, password="123456"))
        except ValueError as exc:
            assert "账号或密码错误" in str(exc)
        else:
            raise AssertionError("disabled employee login should be rejected")
