# backend/app/automation/suggester.py
# 반복 패턴 탐지 → automation_suggestion. notification.triaged 구독 + 수동 scan 둘 다 지원.
from __future__ import annotations

import uuid

from sqlmodel import Session, select

from ..models import AutomationRunLog, AutomationSuggestion
from .event_bus import Event, EventBus
from .events import AUTOMATION_SUGGESTED, NOTIFICATION_TRIAGED

# 데모용 결정적 패턴 규칙: (감지 텍스트 부분일치, 제안)
PATTERNS = [
    {
        "match": "다이제스트",
        "pattern": "저녁 다이제스트를 자주 쓰시네요.",
        "offer": {
            "name": "아침에도 다이제스트",
            "cat": "mail",
            "trigger": "08:00",
            "cond": None,
            "action": "밤사이 메일 묶음 브리핑",
        },
    },
]


def scan(s: Session, bus: EventBus | None = None) -> list[AutomationSuggestion]:
    """run_log 를 훑어 반복 패턴이 임계 이상이면 제안 생성(중복 방지).
    생성된 제안마다 automation.suggested 발행(bus 가 주어지면)."""
    logs = s.exec(select(AutomationRunLog)).all()
    existing = {x.offer_name for x in s.exec(select(AutomationSuggestion)).all()}
    created: list[AutomationSuggestion] = []
    for pat in PATTERNS:
        hits = [log for log in logs if pat["match"] in (log.text or "")]
        if len(hits) >= 3 and pat["offer"]["name"] not in existing:  # 임계=3
            o = pat["offer"]
            sug = AutomationSuggestion(
                id="asug-" + uuid.uuid4().hex[:8],
                pattern=pat["pattern"],
                offer_name=o["name"],
                offer_cat=o["cat"],
                offer_trigger=o["trigger"],
                offer_cond=o["cond"],
                offer_action=o["action"],
                status="open",
            )
            s.add(sug)
            created.append(sug)
    s.commit()
    if bus:
        for sug in created:
            bus.publish(
                AUTOMATION_SUGGESTED,
                {"suggestion_id": sug.id, "offer_name": sug.offer_name, "pattern": sug.pattern},
            )
    return created


def register(bus: EventBus, session_factory) -> None:
    """버스에 suggester 핸들러 등록 — notification.triaged 구독.
    phase-9 알림 트리아지의 '나중에' 반복 패턴을 입력으로 scan → automation.suggested 체인."""

    def on_triaged(ev: Event) -> None:
        with session_factory() as s:
            scan(s, bus)

    bus.subscribe(NOTIFICATION_TRIAGED, on_triaged)
