import os
import json
import tempfile

import pytest

from app import db as db_module


@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
    # Close all SQLite WAL files before removal (needed on Windows)
    import gc
    gc.collect()
    for ext in ("", "-wal", "-shm"):
        try:
            os.remove(path + ext)
        except FileNotFoundError:
            pass


def test_init_db_creates_seven_tables(tmp_db):
    with db_module._conn() as conn:
        rows = conn.execute(
            "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"
        ).fetchall()
    names = sorted(r[0] for r in rows if not r[0].startswith("sqlite_"))
    assert names == sorted([
        "news_articles", "trending_keywords", "card_slates",
        "card_assets", "generation_tasks", "prompt_templates",
        "account_preferences",
    ])


def test_news_article_roundtrip(tmp_db):
    aid = db_module.add_news_article({
        "category": "economy",
        "title": "금리 인상 발표",
        "link": "https://example.com/1",
        "summary": "한국은행이 기준금리를 인상했다.",
        "pub_date": "2026-05-15T08:00:00",
    })
    assert isinstance(aid, int)
    rows = db_module.list_news_articles(category="economy", days=7)
    assert len(rows) == 1
    assert rows[0]["title"] == "금리 인상 발표"


def test_trending_keyword_roundtrip(tmp_db):
    kid = db_module.add_trending_keyword({
        "keyword": "기준금리",
        "category": "economy",
        "score": 0.87,
        "articles_count": 12,
    })
    assert isinstance(kid, int)
    items = db_module.list_trending_keywords(category="economy", used=False)
    assert items[0]["score"] == pytest.approx(0.87)


def test_card_slate_with_assets(tmp_db):
    sid = db_module.add_card_slate({
        "keyword": "기준금리",
        "category": "economy",
        "cover_copy": {"headline": "금리 인상", "body": "왜?", "accent_color": "#0F62FE"},
        "body_copies": [{"headline": f"H{i}", "body": f"B{i}"} for i in range(8)],
        "cta_copy": {"headline": "정리", "body": "바로 확인", "cta": "팔로우"},
        "suggested_caption": "금리에 대해 알아보자",
        "hashtags": ["#금리", "#경제"],
    })
    db_module.add_card_asset(sid, page_index=1, file_path="/tmp/01.png", file_hash="abc")
    slate = db_module.get_card_slate(sid)
    assert slate["status"] == "draft"
    assert json.loads(slate["body_copies"])[0]["headline"] == "H0"
    assets = db_module.list_card_assets(sid)
    assert assets[0]["page_index"] == 1


def test_generation_task_lifecycle(tmp_db):
    tid = db_module.create_task("collect", {"category": "economy"})
    db_module.update_task(tid, status="processing", progress=50, message="..")
    db_module.update_task(tid, status="succeeded", progress=100, message="ok", result_id=123)
    t = db_module.get_task(tid)
    assert t["status"] == "succeeded"
    assert t["result_id"] == 123


def test_prompt_template_upsert(tmp_db):
    db_module.upsert_prompt_template("slate_writer", "v1 template", "writer")
    db_module.upsert_prompt_template("slate_writer", "v2 template", "writer")
    pt = db_module.get_prompt_template("slate_writer")
    assert pt["template"] == "v2 template"
