"""task-2536 회귀: 유휴 base 명시 라벨 (회장 §결정 2026-05-10 fix D).

검증 5건:
1. _compute_team_idle_base — 가장 최근 completed end_time 기준 정확
2. get_teams_info — 유휴 dev sub_team에 idle_base 부착
3. _compute_team_idle_base — base 누락(completed 0건) 시 None graceful
4. _enrich_member_status — idle 멤버에 idle_base 부착
5. spec 박제 일관성 — traffic-light-spec.md §8 idle_base 규칙 박제

영역 격리: data_loader 시그널 병합 로직(task-2534) 절대 수정 안 함.
chat=6937032012 격리.
"""

import json
import os
import sys
from datetime import datetime, timedelta
from pathlib import Path

import pytest

# task-2536: WORKSPACE_ROOT env var 우선 (worktree 격리 환경에서도 작동)
_WORKSPACE_ROOT = os.environ.get("WORKSPACE_ROOT", "/home/jay/workspace")
if _WORKSPACE_ROOT not in sys.path:
    sys.path.insert(0, _WORKSPACE_ROOT)
from dashboard.data_loader import DataLoader  # type: ignore[import-not-found]  # noqa: E402

CHAT_ID = "6937032012"  # 회장 §명시 격리


@pytest.fixture
def workspace_with_org(tmp_path: Path):
    """org-structure + task-timers 최소 fixture.

    dev1-team / dev2-team 두 sub_team + members.json
    """
    memory = tmp_path / "memory"
    memory.mkdir()
    (memory / "events").mkdir()

    org = {
        "structure": {
            "columns": {
                "teams": [
                    {
                        "team_id": "development-office",
                        "team_name": "개발실",
                        "sub_teams": [
                            {
                                "sub_team_id": "dev1-team",
                                "sub_team_name": "개발1팀",
                                "lead": {"id": "hermes", "name": "헤르메스"},
                                "members": [{"id": "dev1-m1", "name": "팀원A"}],
                            },
                            {
                                "sub_team_id": "dev2-team",
                                "sub_team_name": "개발2팀",
                                "lead": {"id": "odin", "name": "오딘"},
                                "members": [{"id": "dev2-m1", "name": "팀원B"}],
                            },
                        ],
                    }
                ]
            },
            "rows": {"centers": []},
        }
    }
    (memory / "organization-structure.json").write_text(
        json.dumps(org, ensure_ascii=False), encoding="utf-8"
    )

    # 기본 빈 파일들
    (memory / "tech-debt.json").write_text(json.dumps({"items": []}), encoding="utf-8")
    (memory / "ci-status.json").write_text(json.dumps({}), encoding="utf-8")
    (memory / "events" / "member-status.json").write_text(
        json.dumps({"members": {"hermes": {"status": "idle"}, "odin": {"status": "idle"}}}),
        encoding="utf-8",
    )
    (memory / "events" / "bot-activity.json").write_text(
        json.dumps({"bots": {}}), encoding="utf-8"
    )
    (memory / "todo.json").write_text(json.dumps({"items": []}), encoding="utf-8")
    return tmp_path


def _write_tasks(workspace: Path, tasks: dict):
    (workspace / "memory" / "task-timers.json").write_text(
        json.dumps({"tasks": tasks}, ensure_ascii=False), encoding="utf-8"
    )


# ── 1. _compute_team_idle_base — 가장 최근 completed end_time 기준 ───────────


def test_compute_team_idle_base_returns_latest_completed(workspace_with_org):
    """3개 completed task 중 end_time이 가장 최근인 것이 base로 선택돼야 한다."""
    older = (datetime.now() - timedelta(hours=120)).isoformat()
    middle = (datetime.now() - timedelta(hours=85)).isoformat()
    newest = (datetime.now() - timedelta(hours=40)).isoformat()
    _write_tasks(
        workspace_with_org,
        {
            "task-old": {
                "team_id": "dev1-team",
                "status": "completed",
                "end_time": older,
            },
            "task-mid": {
                "team_id": "dev1-team",
                "status": "completed",
                "end_time": middle,
            },
            "task-new": {
                "team_id": "dev1-team",
                "status": "completed",
                "end_time": newest,
            },
        },
    )
    loader = DataLoader(workspace_with_org)
    loader.reload_all()
    base = loader._compute_team_idle_base("dev1-team")
    assert base is not None
    assert base["task_id"] == "task-new"
    assert base["ts"] == newest
    # idle_hours: floor((now - newest) / 3600) ≈ 40
    assert 39 <= base["idle_hours"] <= 41


# ── 2. get_teams_info — 유휴 dev sub_team에 idle_base 부착 ──────────────────


def test_get_teams_info_attaches_idle_base_to_idle_subteam(workspace_with_org):
    """dev sub_team이 유휴(running 0)일 때 sub_info["idle_base"]가 채워져야 한다."""
    end_ts = (datetime.now() - timedelta(hours=85)).isoformat()
    _write_tasks(
        workspace_with_org,
        {
            "task-2470": {
                "team_id": "dev1-team",
                "status": "completed",
                "end_time": end_ts,
            }
            # dev2-team: completed 없음 → idle_base = None
        },
    )
    loader = DataLoader(workspace_with_org)
    loader.reload_all()
    teams = loader.get_teams_info()

    # dev sub_teams는 development-office 하위 members 안에 있음
    dev_office = next((t for t in teams if t["team_id"] == "development-office"), None)
    assert dev_office is not None

    sub_dev1 = next((m for m in dev_office["members"] if m.get("sub_team_id") == "dev1-team"), None)
    sub_dev2 = next((m for m in dev_office["members"] if m.get("sub_team_id") == "dev2-team"), None)
    assert sub_dev1 is not None and sub_dev2 is not None

    # dev1: idle_base 부착
    assert "idle_base" in sub_dev1
    assert sub_dev1["idle_base"] is not None
    assert sub_dev1["idle_base"]["task_id"] == "task-2470"

    # dev2: completed 없음 → None 부착 (graceful)
    assert "idle_base" in sub_dev2
    assert sub_dev2["idle_base"] is None


# ── 3. base 누락 시 None graceful (회귀 #3 — task spec 명시) ──────────────────


def test_compute_team_idle_base_returns_none_when_no_completed(workspace_with_org):
    """completed task가 0건인 팀에 대해 None 반환 (signal 병합 깨지지 않음)."""
    _write_tasks(workspace_with_org, {})  # 빈 task-timers
    loader = DataLoader(workspace_with_org)
    loader.reload_all()

    assert loader._compute_team_idle_base("dev1-team") is None
    assert loader._compute_team_idle_base("nonexistent-team") is None
    assert loader._compute_team_idle_base(None) is None
    assert loader._compute_team_idle_base("") is None


# ── 4. _enrich_member_status — idle 멤버에 idle_base 부착 ────────────────────


def test_enrich_member_status_attaches_idle_base_to_idle_member(workspace_with_org):
    """team에 running 0건 + member status=idle → member.idle_base 부착."""
    end_ts = (datetime.now() - timedelta(hours=12)).isoformat()
    _write_tasks(
        workspace_with_org,
        {
            "task-prev": {
                "team_id": "dev1-team",
                "status": "completed",
                "end_time": end_ts,
            }
        },
    )
    loader = DataLoader(workspace_with_org)
    loader.reload_all()
    enriched = loader._enrich_member_status()
    members = enriched.get("members", {})

    # hermes (dev1-team lead): idle_base 부착 (status=idle from fixture)
    assert "hermes" in members
    assert "idle_base" in members["hermes"]
    assert members["hermes"]["idle_base"] is not None
    assert members["hermes"]["idle_base"]["task_id"] == "task-prev"


# ── 5. spec 박제 일관성 — traffic-light-spec.md §8 ─────────────────────────


def test_spec_idle_base_section_is_pinned():
    """traffic-light-spec.md에 §8 유휴 base 명시 규칙이 박제되어야 한다.

    회장 §결정 2026-05-10 fix D 박제 검증 — spec과 코드가 분리되지 않도록.
    """
    spec_path = Path("/home/jay/workspace/.worktrees/task-2536-dev2/memory/specs/traffic-light-spec.md")
    if not spec_path.exists():
        # 본 파일이 main에서 직접 실행될 경우 (worktree 아닌 환경)
        spec_path = Path("/home/jay/workspace/memory/specs/traffic-light-spec.md")
    assert spec_path.exists(), f"spec 파일 누락: {spec_path}"
    body = spec_path.read_text(encoding="utf-8")

    # §8 헤더
    assert "## 8. 유휴 base 명시 규칙" in body
    # task-2536 명시
    assert "task-2536" in body
    # 라벨 표시 형식
    assert "since task-2470 13:59" in body or "85h since" in body
    # base 누락 시 graceful
    assert "?" in body and "graceful" in body
    # 시그널 병합 금지 명시
    assert "signal 병합 로직 수정" in body or "병합 X" in body
    # 회장 §결정 2026-05-10 fix D 명시
    assert "fix D" in body
    # chat 격리 검증 (테스트 자체)
    assert CHAT_ID == "6937032012"
