from __future__ import annotations

from pathlib import Path

from sqlalchemy import create_engine, inspect

import app.models  # noqa: F401
from app.models.base import Base


MINIAPP_TABLES = {
    "attendance_points",
    "personnel",
    "person_roles",
    "person_attendance_points",
    "products",
    "equipment",
    "work_schedules",
    "work_sessions",
    "work_session_devices",
    "production_reports",
    "production_report_items",
    "report_audit_logs",
    "mold_lock_feedbacks",
    "device_qrcodes",
    "device_qrcode_batch_tasks",
    "notices",
    "notice_points",
    "reconciliation_ledger_entries",
}

REQUIRED_ERP_TABLES = {
    "sys_department",
    "hr_employee",
    "sys_role",
    "sys_permission",
    "sys_role_permission",
    "sys_user",
    "sys_user_role",
    "sys_system_config",
    "sys_ai_assistant_config",
    "md_unit",
    "md_item_category",
    "md_item",
    "md_material",
    "md_product",
    "md_bom",
    "md_bom_item",
    "wh_warehouse",
    "wh_location",
    "wh_stock_lot",
    "wh_stock_balance",
    "wh_inventory_txn",
    "pp_material_issue",
    "pp_material_issue_item",
    "pp_production_batch_ledger",
    "pp_production_batch_ledger_txn",
    "document_archives",
}


def _erp_model_table_names() -> set[str]:
    models_dir = Path(__file__).resolve().parents[1] / "app" / "models"
    table_names: set[str] = set()
    for model_file in models_dir.glob("*.py"):
        if model_file.name in {"__init__.py", "base.py", "miniapp.py"}:
            continue
        for line in model_file.read_text(encoding="utf-8").splitlines():
            stripped = line.strip()
            if stripped.startswith("__tablename__"):
                table_names.add(stripped.split("=", 1)[1].strip().strip("\"'"))
    return table_names


def test_app_models_registers_erp_and_miniapp_tables() -> None:
    expected_tables = _erp_model_table_names() | REQUIRED_ERP_TABLES | MINIAPP_TABLES

    missing_tables = expected_tables - set(Base.metadata.tables)

    assert missing_tables == set()


def test_reset_table_groups_are_registered_in_metadata() -> None:
    from app.services.system_initializer import ACCOUNT_RESET_TABLES, BUSINESS_RESET_TABLES, MINIAPP_RESET_TABLES, SKELETON_TABLES

    expected_tables = set(BUSINESS_RESET_TABLES) | set(MINIAPP_RESET_TABLES) | set(ACCOUNT_RESET_TABLES) | set(SKELETON_TABLES)

    assert expected_tables.issubset(set(Base.metadata.tables))


def test_registered_models_create_all_in_sqlite_memory() -> None:
    engine = create_engine("sqlite:///:memory:")

    Base.metadata.create_all(engine)

    created_tables = set(inspect(engine).get_table_names())
    assert (MINIAPP_TABLES | REQUIRED_ERP_TABLES).issubset(created_tables)
