"""
日程冲突检测器。

检测同一批事件中时间重叠的事件对。全天事件不参与检测。

规则：
  - A.start < B.end AND A.end > B.start → 有重叠
  - 紧接场景（间隔 < 5 分钟）→ 额外警告（is_tight=True）
"""

from __future__ import annotations

import sys
from dataclasses import dataclass
from datetime import timedelta
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent))

from gcal.models import CalendarEvent

_TIGHT_MINUTES = 5   # 间隔小于此值视为"紧接"


@dataclass
class ConflictPair:
    a: CalendarEvent
    b: CalendarEvent
    overlap_minutes: int   # 0 表示紧接但不重叠
    is_tight: bool = False # True = 无重叠但间隔 < 5 分钟

    def format_text(self) -> str:
        ta = f"{self.a.start.strftime('%H:%M')}–{self.a.end.strftime('%H:%M')}"
        tb = f"{self.b.start.strftime('%H:%M')}–{self.b.end.strftime('%H:%M')}"
        if self.is_tight:
            gap = int((self.b.start - self.a.end).total_seconds() / 60)
            return (
                f"⚡ 紧接：【{self.a.summary}】({ta}) 结束后仅 {gap} 分钟"
                f"【{self.b.summary}】({tb}) 就开始"
            )
        return (
            f"⚠️ 冲突：【{self.a.summary}】({ta})"
            f" 与 【{self.b.summary}】({tb})"
            f" 重叠 {self.overlap_minutes} 分钟"
        )


def detect_conflicts(
    events: list[CalendarEvent],
    tight_minutes: int = _TIGHT_MINUTES,
) -> list[ConflictPair]:
    """
    检测时间重叠或紧接的事件对。

    返回结果按事件开始时间升序排列。
    仅检测有确定时间的事件（跳过全天事件）。
    """
    timed = [
        e for e in events
        if not e.is_all_day and e.start is not None and e.end is not None
    ]
    timed.sort(key=lambda e: e.start)

    pairs: list[ConflictPair] = []
    for i in range(len(timed)):
        for j in range(i + 1, len(timed)):
            a, b = timed[i], timed[j]

            # b 开始已超过 a 结束 + tight window → 不可能再有冲突/紧接
            if b.start >= a.end + timedelta(minutes=tight_minutes):
                break

            if b.start < a.end:
                # 有重叠
                overlap_start = max(a.start, b.start)
                overlap_end   = min(a.end,   b.end)
                overlap_min   = int((overlap_end - overlap_start).total_seconds() / 60)
                if overlap_min > 0:
                    pairs.append(ConflictPair(a=a, b=b, overlap_minutes=overlap_min))
            else:
                # 无重叠但间隔 < tight_minutes
                pairs.append(ConflictPair(a=a, b=b, overlap_minutes=0, is_tight=True))

    return pairs


def format_conflicts_section(pairs: list[ConflictPair]) -> str:
    """将冲突列表格式化为 Markdown 通知文本。"""
    if not pairs:
        return ""
    lines = ["⚠️ **发现日程冲突：**", ""]
    for p in pairs:
        lines.append(f"- {p.format_text()}")
    lines.append("")
    lines.append("建议：检查 Google Calendar 并调整时间安排。")
    return "\n".join(lines)
