"""
pytest 共用 Fixtures
提供測試用的資料庫 Session、測試客戶端等
"""
import sys
import os
from pathlib import Path

# 確保 backend 根目錄在 Python path 中
sys.path.insert(0, str(Path(__file__).parent.parent))

# 在導入任何 app 模組前，先將 PostgreSQL JSONB 替換為 JSON (SQLite 相容)
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy import JSON
import sqlalchemy.dialects.postgresql as pg_dialect
pg_dialect.JSONB = JSON

import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool

from app.db.base import Base
from app.db.session import get_db
from app.main import app

# ============================================================
# 測試資料庫 (使用 SQLite in-memory)
# ============================================================
SQLALCHEMY_DATABASE_URL = "sqlite://"

engine = create_engine(
    SQLALCHEMY_DATABASE_URL,
    connect_args={"check_same_thread": False},
    poolclass=StaticPool,
)
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)


@pytest.fixture(scope="function")
def db():
    """提供測試用的資料庫 Session (每個測試獨立)"""
    Base.metadata.create_all(bind=engine)
    session = TestingSessionLocal()
    try:
        yield session
    finally:
        session.close()
        Base.metadata.drop_all(bind=engine)


@pytest.fixture(scope="function")
def client(db):
    """提供測試用的 FastAPI TestClient"""
    def override_get_db():
        try:
            yield db
        finally:
            pass

    app.dependency_overrides[get_db] = override_get_db
    with TestClient(app) as c:
        yield c
    app.dependency_overrides.clear()


# ============================================================
# 測試資料 Fixtures
# ============================================================

@pytest.fixture
def sample_business_unit(db):
    """建立測試用事業部"""
    from app.models.business_unit import BusinessUnit
    bu = BusinessUnit(
        tenant_id=1,
        name="智能研發服務事業部",
        code="SMART",
        email_domain="lab.taipei",
        description="測試事業部",
        is_active=True,
    )
    db.add(bu)
    db.commit()
    db.refresh(bu)
    return bu


@pytest.fixture
def sample_department(db, sample_business_unit):
    """建立測試用部門"""
    from app.models.department import Department
    dept = Department(
        tenant_id=1,
        business_unit_id=sample_business_unit.id,
        name="資訊部",
        code="IT",
        is_active=True,
    )
    db.add(dept)
    db.commit()
    db.refresh(dept)
    return dept


@pytest.fixture
def sample_employee(db, sample_business_unit):
    """建立測試用員工"""
    from app.models.employee import Employee
    import datetime
    emp = Employee(
        tenant_id=1,
        employee_id="EMP001",
        username_base="test.user",
        legal_name="測試用戶",
        english_name="Test User",
        hire_date=datetime.date.today(),
        status="active",
    )
    db.add(emp)
    db.commit()
    db.refresh(emp)
    return emp
