import json
import os
import tempfile
from unittest.mock import patch, MagicMock

import pytest

from app import db as db_module
from app import card_writer


@pytest.fixture
def tmp_db(monkeypatch):
    fd, path = tempfile.mkstemp(suffix=".db")
    os.close(fd)
    monkeypatch.setattr(db_module, "DB_PATH", path)
    db_module.init_db()
    yield path
    import gc
    gc.collect()
    for ext in ("", "-wal", "-shm"):
        try:
            os.remove(path + ext)
        except OSError:
            pass


SAMPLE_LLM_JSON = {
    "cover_copy": {"headline": "금리 인상 단행", "body": "왜 지금?", "accent_color": "#0F62FE"},
    "body_copies": [
        {"headline": f"포인트 {i+1}", "body": f"본문 {i+1}"} for i in range(8)
    ],
    "cta_copy": {"headline": "정리", "body": "바로 확인", "cta": "팔로우"},
    "suggested_caption": "금리에 대해 알아보자",
    "hashtags": ["#금리", "#경제"],
}


def _fake_messages_create(*_args, **_kwargs):
    msg = MagicMock()
    block = MagicMock()
    block.text = json.dumps(SAMPLE_LLM_JSON, ensure_ascii=False)
    msg.content = [block]
    return msg


def test_write_slate_persists_full_payload(tmp_db, monkeypatch):
    db_module.add_news_article({
        "category": "economy", "title": "기준금리 인상 단행",
        "link": "https://example.com/1", "summary": "한국은행 발표",
    })
    fake_client = MagicMock()
    fake_client.messages.create = _fake_messages_create
    monkeypatch.setattr(card_writer, "_client", lambda: fake_client)

    sid = card_writer.write_slate(keyword="기준금리", category="economy")
    slate = db_module.get_card_slate(sid)
    assert slate["status"] == "draft"
    body_copies = json.loads(slate["body_copies"])
    assert len(body_copies) == 8
    assert body_copies[0]["headline"] == "포인트 1"
    assert json.loads(slate["cover_copy"])["accent_color"] == "#0F62FE"


def test_write_slate_raises_on_invalid_json(tmp_db, monkeypatch):
    fake_client = MagicMock()
    bad_msg = MagicMock()
    bad_block = MagicMock()
    bad_block.text = "not json"
    bad_msg.content = [bad_block]
    fake_client.messages.create.return_value = bad_msg
    monkeypatch.setattr(card_writer, "_client", lambda: fake_client)

    with pytest.raises(ValueError):
        card_writer.write_slate(keyword="x", category="economy")
