import json
from datetime import datetime, date
from zoneinfo import ZoneInfo
from src.models import Article, Image, Issue, Setting


def test_create_article(db):
    article = Article(
        guid="https://example.com/?p=100",
        title="Test Article",
        author="Test Author",
        pub_date=datetime(2026, 4, 6, 12, 0, 0),
        categories=json.dumps(["Government"]),
        link="https://example.com/test",
        content_html="<p>Test content</p>",
    )
    db.session.add(article)
    db.session.commit()

    saved = Article.query.filter_by(guid="https://example.com/?p=100").first()
    assert saved is not None
    assert saved.title == "Test Article"
    assert saved.author == "Test Author"
    assert json.loads(saved.categories) == ["Government"]
    assert saved.fetched_at is not None


def test_article_guid_unique(db):
    a1 = Article(guid="dup", title="A", author="X", pub_date=datetime.now(),
                 categories="[]", link="http://a", content_html="")
    a2 = Article(guid="dup", title="B", author="Y", pub_date=datetime.now(),
                 categories="[]", link="http://b", content_html="")
    db.session.add(a1)
    db.session.commit()
    db.session.add(a2)
    try:
        db.session.commit()
        assert False, "Should have raised IntegrityError"
    except Exception:
        db.session.rollback()


def test_create_image(db):
    article = Article(guid="img-test", title="A", author="X",
                      pub_date=datetime.now(), categories="[]",
                      link="http://a", content_html="")
    db.session.add(article)
    db.session.commit()

    img = Image(
        article_id=article.id,
        original_url="https://example.com/photo.jpg",
        local_path="data/images/abc123.jpg",
        width=800,
        height=450,
    )
    db.session.add(img)
    db.session.commit()

    assert img.id is not None
    assert img.article.guid == "img-test"


def test_create_issue(db):
    issue = Issue(
        week_start=date(2026, 4, 6),
        week_end=date(2026, 4, 12),
        cover_method="text",
        cover_path="data/issues/cover.jpg",
        epub_path="data/issues/test.epub",
        article_ids=json.dumps([1, 2, 3]),
        excluded_article_ids=json.dumps([]),
        status="published",
    )
    db.session.add(issue)
    db.session.commit()
    assert issue.id is not None
    assert issue.created_at is not None


def test_setting_crud(db):
    Setting.set("fetch_interval", 2)
    assert Setting.get("fetch_interval") == 2
    assert Setting.get("nonexistent", default="fallback") == "fallback"

    Setting.set("fetch_interval", 4)
    assert Setting.get("fetch_interval") == 4


def test_article_default_fetched_at(db):
    article = Article(
        guid="https://example.com/?p=101",
        title="Test Article 2",
        author="Test Author",
        pub_date=datetime(2026, 4, 6, 12, 0, 0),
        categories="[]",
        link="https://example.com/test2",
        content_html="<p>Test content</p>",
    )
    db.session.add(article)
    db.session.commit()

    saved = Article.query.filter_by(guid="https://example.com/?p=101").first()
    assert saved.fetched_at.tzinfo is None
    # Should be close to current US/Eastern time
    local_now = datetime.now(ZoneInfo("America/New_York")).replace(tzinfo=None)
    diff = abs((local_now - saved.fetched_at).total_seconds())
    assert diff < 10


def test_issue_default_created_at(db):
    issue = Issue(
        week_start=date(2026, 4, 13),
        week_end=date(2026, 4, 19),
        cover_method="text",
        cover_path="data/issues/cover2.jpg",
        epub_path="data/issues/test2.epub",
        article_ids="[]",
        excluded_article_ids="[]",
        status="draft",
    )
    db.session.add(issue)
    db.session.commit()

    saved = Issue.query.filter_by(week_start=date(2026, 4, 13)).first()
    assert saved.created_at.tzinfo is None
    local_now = datetime.now(ZoneInfo("America/New_York")).replace(tzinfo=None)
    diff = abs((local_now - saved.created_at).total_seconds())
    assert diff < 10
