# backend/app/services/meetings.py
# 회의 액션 → 작업 실체화(federation) + 회의 데이터 조립.
from __future__ import annotations

import json
import uuid

from sqlmodel import Session, select

from ..automation.event_bus import bus
from ..models import (
    CalEvent,
    Meeting,
    MeetingAction,
    Prio,
    Project,
    Task,
    TaskStatus,
)

# cal-data.js who(표시명) → person id
WHO_TO_PERSON = {
    "나": "jiwoo",
    "현우": "hyunwoo",
    "민서": "minseo",
    "재호": "jaeho",
    "수아": "sua",
}
DEFAULT_PROJECT = "me"  # 회의 액션 기본 프로젝트(개인 일상)


def _person_id(who: str) -> str | None:
    return WHO_TO_PERSON.get(who.strip())


def _tid() -> str:
    return "mt-" + uuid.uuid4().hex[:8]


def materialize_action(s: Session, meeting_id: str, idx: int) -> tuple[MeetingAction, Task]:
    """회의 액션 1건 → task 생성 + materialized_task_id 연결."""
    action = s.exec(
        select(MeetingAction).where(
            MeetingAction.meeting_id == meeting_id, MeetingAction.idx == idx
        )
    ).first()
    if action is None:
        raise ValueError("action not found")
    if action.added and action.materialized_task_id:
        return action, s.get(Task, action.materialized_task_id)  # 멱등

    meeting = s.get(Meeting, meeting_id)
    ev = s.get(CalEvent, meeting.event_id) if meeting else None
    project_id = DEFAULT_PROJECT
    if ev and ev.cal in ("work", "meeting", "team"):
        project_id = "biz"  # 업무성 회의 → 경영 전략 루트(데모 결정성)
    if not s.get(Project, project_id):
        project_id = DEFAULT_PROJECT

    siblings = s.exec(
        select(Task).where(Task.project_id == project_id, Task.parent_id == None)  # noqa: E711
    ).all()
    order = max([t.sort_order for t in siblings] + [-1]) + 1
    ev_title = ev.title if ev else ""
    notes = f"<p>회의 <b>‘{ev_title}’</b>의 액션 아이템에서 아리가 만든 작업이에요.</p>"
    task = Task(
        id=_tid(),
        project_id=project_id,
        parent_id=None,
        title=action.text,
        status=TaskStatus.todo,
        assignee_id=_person_id(action.who),
        due=None,
        prio=Prio.normal,
        notes=notes,
        est="",
        sort_order=order,
    )
    s.add(task)
    action.added = True
    action.materialized_task_id = task.id
    s.add(action)
    s.commit()
    s.refresh(task)
    s.refresh(action)
    # task.created 발행 (phase-3 작업 보드/대시보드 갱신)
    bus.publish(
        "task.created",
        {"task_id": task.id, "source": "meeting", "meeting_id": meeting_id},
    )
    return action, task


def materialize_all(s: Session, meeting_id: str) -> list[tuple[MeetingAction, Task]]:
    """남은(added=False) 액션 전부 실체화 → '모두 작업으로'."""
    pending = s.exec(
        select(MeetingAction).where(
            MeetingAction.meeting_id == meeting_id, MeetingAction.added == False  # noqa: E712
        )
    ).all()
    pairs = [materialize_action(s, meeting_id, a.idx) for a in pending]
    if pairs:
        bus.publish(
            "meeting.ended",
            {
                "meeting_id": meeting_id,
                "action_ids": [a.id for a, _ in pairs],
                "task_ids": [t.id for _, t in pairs],
            },
        )
    return pairs


def assemble_meeting(s: Session, meeting_id: str) -> dict | None:
    """Meeting + actions → MeetingOut dict (JSON 펼침)."""
    m = s.get(Meeting, meeting_id)
    if not m:
        return None
    actions = s.exec(
        select(MeetingAction)
        .where(MeetingAction.meeting_id == meeting_id)
        .order_by(MeetingAction.idx)
    ).all()
    j = json.loads
    return dict(
        id=m.id,
        event_id=m.event_id,
        phase=m.phase.value if hasattr(m.phase, "value") else m.phase,
        one_on_one=m.one_on_one,
        meta=m.meta,
        starts_in=m.starts_in,
        summary=j(m.summary_json),
        decisions=j(m.decisions_json),
        agenda=j(m.agenda_json),
        last_meeting=j(m.last_meeting_json),
        last_actions=j(m.last_actions_json),
        insights=j(m.insights_json),
        docs=j(m.docs_json),
        person=j(m.person_json),
        promises=j(m.promises_json),
        signals=j(m.signals_json),
        talking_points=j(m.talking_points_json),
        actions=[
            dict(
                id=a.id,
                idx=a.idx,
                text=a.text,
                who=a.who,
                when=a.when_text,
                added=a.added,
                materialized_task_id=a.materialized_task_id,
            )
            for a in actions
        ],
    )
