# backend/tests/test_proactive.py — 능동 감지 + 수락 실체화
from sqlmodel import select

from app.models import CalEvent, FinanceCategory, FocusBlock, ProactiveCard, Task
from app.worker.jobs.proactive import run_proactive


def test_meeting_streak_card(session):
    s, _ = session
    for i, t in enumerate([("10:00", "11:00"), ("11:00", "12:00"), ("13:00", "14:00")]):
        s.add(CalEvent(id=f"te{i}", day=9, start=t[0], end=t[1], title=f"회의{i}", cal="meeting"))
    s.commit()
    cards = run_proactive(s)
    streak = [c for c in cards if c.kind == "schedule"]
    assert streak and "미팅 3연속" in streak[0].title
    assert streak[0].action_kind == "focus_block"


def test_pricey_bill_card(session):
    s, _ = session
    s.add(FinanceCategory(id="cat-x", name="쇼핑", amt=298000, pct=120, icon="bag", over=True))
    s.commit()
    cards = run_proactive(s)
    bill = [c for c in cards if c.kind == "finance"]
    assert bill and "평소보다 많아요" in bill[0].title and bill[0].tone == "amber"


def test_run_proactive_idempotent(session):
    s, _ = session
    for i in range(3):
        s.add(
            CalEvent(
                id=f"te{i}", day=9, start=f"1{i}:00", end=f"1{i+1}:00", title="회의", cal="meeting"
            )
        )
    s.commit()
    run_proactive(s)
    run_proactive(s)  # 2회차
    streaks = s.exec(select(ProactiveCard).where(ProactiveCard.id == "pc-streak")).all()
    assert len(streaks) == 1  # 중복 생성 없음


def test_accept_focus_block_materializes(client, session):
    s, _ = session
    # 시드 pc1(schedule/focus_block) 수락 → FocusBlock 생성
    out = client.post("/api/proactive/pc1/accept").json()
    assert out["action_kind"] == "focus_block" and out["created_id"]
    s.expire_all()
    assert s.get(FocusBlock, out["created_id"]) is not None
    # 카드는 accepted → active 목록에서 사라짐
    active = client.get("/api/proactive").json()
    assert "pc1" not in [c["id"] for c in active]


def test_accept_task_materializes(client, session):
    s, _ = session
    out = client.post("/api/proactive/pc2/accept").json()
    assert out["action_kind"] == "task" and out["created_id"]
    s.expire_all()
    assert s.get(Task, out["created_id"]) is not None


def test_dismiss_proactive(client):
    assert client.post("/api/proactive/pc1/dismiss").json()["ok"] is True
    assert "pc1" not in [c["id"] for c in client.get("/api/proactive").json()]


def test_worker_run_endpoint(client):
    r = client.post("/api/worker/run/proactive").json()
    assert r["job"] == "proactive" and r["ok"] is True
    assert client.post("/api/worker/run/nope").status_code == 404
