# -*- coding: utf-8 -*-
"""员工维度表（staff_info）单元测试：验证 P1、P2 正确性属性。"""
import logging
import os
import sys
from pathlib import Path

PROJECT_ROOT = Path(__file__).resolve().parents[2]
if str(PROJECT_ROOT) not in sys.path:
    sys.path.insert(0, str(PROJECT_ROOT))

os.environ.setdefault("ETL_SKIP_DOTENV", "1")

from tasks.ods.ods_tasks import (
    ODS_TASK_SPECS,
    ODS_TASK_CLASSES,
    ENABLED_ODS_CODES,
    SnapshotMode,
)
from api.client import DEFAULT_LIST_KEYS
from tasks.dwd.dwd_load_task import DwdLoadTask
from .task_test_utils import create_test_config, get_db_operations, FakeAPIClient


# ---------------------------------------------------------------------------
# P1：ODS 任务规格完整性
# ---------------------------------------------------------------------------

def _get_staff_spec():
    """从 ODS_TASK_SPECS 中提取 ODS_STAFF_INFO 规格。"""
    for spec in ODS_TASK_SPECS:
        if spec.code == "ODS_STAFF_INFO":
            return spec
    raise AssertionError("ODS_STAFF_INFO 未在 ODS_TASK_SPECS 中注册")


class TestP1OdsStaffInfoSpec:
    """P1：ODS 任务规格完整性验证。"""

    def test_code(self):
        assert _get_staff_spec().code == "ODS_STAFF_INFO"

    def test_table_name(self):
        assert _get_staff_spec().table_name == "ods.staff_info_master"

    def test_endpoint(self):
        assert _get_staff_spec().endpoint == "/PersonnelManagement/SearchSystemStaffInfo"

    def test_list_key(self):
        assert _get_staff_spec().list_key == "staffProfiles"

    def test_snapshot_mode(self):
        assert _get_staff_spec().snapshot_mode == SnapshotMode.FULL_TABLE

    def test_requires_window_false(self):
        assert _get_staff_spec().requires_window is False

    def test_time_fields_none(self):
        assert _get_staff_spec().time_fields is None

    def test_staff_profiles_in_default_list_keys(self):
        assert "staffProfiles" in DEFAULT_LIST_KEYS

    def test_ods_staff_info_in_enabled_codes(self):
        assert "ODS_STAFF_INFO" in ENABLED_ODS_CODES

    def test_task_class_registered(self):
        assert "ODS_STAFF_INFO" in ODS_TASK_CLASSES


# ---------------------------------------------------------------------------
# P2：DWD 映射完整性
# ---------------------------------------------------------------------------

class TestP2DwdStaffMapping:
    """P2：DWD 映射完整性验证。"""

    def test_dim_staff_table_map(self):
        assert DwdLoadTask.TABLE_MAP["dwd.dim_staff"] == "ods.staff_info_master"

    def test_dim_staff_ex_table_map(self):
        assert DwdLoadTask.TABLE_MAP["dwd.dim_staff_ex"] == "ods.staff_info_master"

    def test_dim_staff_has_staff_id_mapping(self):
        mappings = DwdLoadTask.FACT_MAPPINGS["dwd.dim_staff"]
        pk_map = [(dst, src) for dst, src, _ in mappings if dst == "staff_id"]
        assert len(pk_map) == 1
        assert pk_map[0][1] == "id"

    def test_dim_staff_ex_has_staff_id_mapping(self):
        mappings = DwdLoadTask.FACT_MAPPINGS["dwd.dim_staff_ex"]
        pk_map = [(dst, src) for dst, src, _ in mappings if dst == "staff_id"]
        assert len(pk_map) == 1
        assert pk_map[0][1] == "id"


# ---------------------------------------------------------------------------
# ODS 落地功能测试
# ---------------------------------------------------------------------------

def test_staff_info_ingest(tmp_path):
    """验证 ODS_STAFF_INFO 任务能正确落地员工数据。"""
    config = create_test_config("ONLINE", tmp_path / "archive", tmp_path / "temp")
    sample = [
        {
            "id": 3020236636900101,
            "staff_name": "葛芃",
            "mobile": "13811638071",
            "job": "店长",
            "staff_identity": 2,
            "status": 1,
            "leave_status": 0,
            "site_id": 2790685415443269,
            "tenant_id": 2790683160709957,
        }
    ]
    api = FakeAPIClient({"/PersonnelManagement/SearchSystemStaffInfo": sample})
    task_cls = ODS_TASK_CLASSES["ODS_STAFF_INFO"]

    with get_db_operations() as db_ops:
        task = task_cls(config, db_ops, api, logging.getLogger("test_staff_info"))
        result = task.execute()

    assert result["status"] == "SUCCESS"
    assert result["counts"]["fetched"] == 1
    row = db_ops.upserts[0]["rows"][0]
    assert row["id"] == 3020236636900101
    assert row["record_index"] == 0
    assert '"staff_name": "葛芃"' in row["payload"] or '"staff_name": "\\u845b\\u82c3"' in row["payload"]
