# retoor <retoor@molodetz.nl>

import pytest
from uuid import uuid4
from datetime import datetime, timedelta, timezone
from tests.conftest import BASE_URL, assert_share_copies
from devplacepy.database import get_table
from devplacepy.utils import make_combined_slug
def _seed_news_paginated(count):
    news_table = get_table("news")
    base = datetime.now(timezone.utc)
    marker = uuid4().hex[:8]
    titles = []
    for i in range(count):
        uid = str(uuid4())
        title = f"Pag News {marker} {i:02d}"
        titles.append(title)
        news_table.insert(
            {
                "deleted_at": None,
                "deleted_by": None,
                "uid": uid,
                "slug": make_combined_slug(title, uid),
                "title": title,
                "external_id": f"pag_{marker}_{i}",
                "grade": 10,
                "status": "published",
                "show_on_landing": 0,
                "source_name": "PagSource",
                "url": "https://example.com",
                "description": "paginated news",
                "synced_at": (base - timedelta(seconds=i)).isoformat(),
            }
        )
    return titles
def seed_news():
    news_table = get_table("news")
    for i in range(3):
        eid = f"test_news_{i}"
        if news_table.find_one(external_id=eid):
            continue
        uid = str(uuid4())
        title = f"News Test Article {i}"
        slug = make_combined_slug(title, uid)
        news_table.insert(
            {
                "deleted_at": None,
                "deleted_by": None,
                "uid": uid,
                "slug": slug,
                "title": title,
                "external_id": eid,
                "grade": 8 + i,
                "status": "published",
                "show_on_landing": 1,
                "source_name": "TestSource",
                "synced_at": datetime.now(timezone.utc).isoformat(),
                "description": f"Description for test article {i}.",
            }
        )
@pytest.fixture
def news_article(app_server):
    seed_news()
    article = get_table("news").find_one(external_id="test_news_0")
    return article
import requests
from tests.conftest import BASE_URL
def _seed_news_seo():
    from datetime import datetime, timezone
    from devplacepy.database import get_table
    from devplacepy.utils import generate_uid, make_combined_slug

    uid = generate_uid()
    title = f"SEO Test News Article {uid.split('-')[-1]}"
    slug = make_combined_slug(title, uid)
    get_table("news").insert(
        {
            "deleted_at": None,
            "deleted_by": None,
            "uid": uid,
            "slug": slug,
            "title": title,
            "description": "A seeded news article for SEO tests.",
            "content": "Body content for the seeded article.",
            "url": "https://example.com/article",
            "source_name": "ExampleSource",
            "status": "published",
            "synced_at": datetime.now(timezone.utc).isoformat(),
            "show_on_landing": 0,
            "grade": 8,
        }
    )
    return slug, uid
def _seed_owner():
    from datetime import datetime, timezone
    from uuid import uuid4
    from devplacepy.database import get_table

    uid = str(uuid4())
    get_table("users").insert(
        {
            "uid": uid,
            "username": f"seo_{uid[:8]}",
            "terms_version": "1",
            "email": f"{uid[:8]}@seo.test",
            "password_hash": "x",
            "role": "Member",
            "is_active": True,
            "created_at": datetime.now(timezone.utc).isoformat(),
        }
    )
    return uid
def _seed_post_seo(image=None):
    from datetime import datetime, timezone
    from uuid import uuid4
    from devplacepy.database import get_table
    from devplacepy.utils import make_combined_slug

    owner = _seed_owner()
    uid = str(uuid4())
    slug = make_combined_slug("SEO Detail Post", uid)
    get_table("posts").insert(
        {
            "deleted_at": None,
            "deleted_by": None,
            "uid": uid,
            "user_uid": owner,
            "slug": slug,
            "title": "SEO Detail Post",
            "content": "Body text for the SEO detail post.",
            "topic": "general",
            "project_uid": None,
            "image": image,
            "stars": 0,
            "created_at": datetime.now(timezone.utc).isoformat(),
        }
    )
    return slug, uid
def _seed_gist():
    from datetime import datetime, timezone
    from uuid import uuid4
    from devplacepy.database import get_table
    from devplacepy.utils import make_combined_slug

    owner = _seed_owner()
    uid = str(uuid4())
    slug = make_combined_slug("SEO Detail Gist", uid)
    get_table("gists").insert(
        {
            "deleted_at": None,
            "deleted_by": None,
            "uid": uid,
            "user_uid": owner,
            "slug": slug,
            "title": "SEO Detail Gist",
            "description": "Gist description for SEO tests.",
            "source_code": "print('seo')",
            "language": "python",
            "stars": 0,
            "created_at": datetime.now(timezone.utc).isoformat(),
        }
    )
    return slug, uid
def _seed_project():
    from datetime import datetime, timezone
    from uuid import uuid4
    from devplacepy.database import get_table
    from devplacepy.utils import make_combined_slug

    owner = _seed_owner()
    uid = str(uuid4())
    slug = make_combined_slug("SEO Detail Project", uid)
    get_table("projects").insert(
        {
            "deleted_at": None,
            "deleted_by": None,
            "uid": uid,
            "user_uid": owner,
            "slug": slug,
            "title": "SEO Detail Project",
            "description": "Project description for SEO tests.",
            "project_type": "software",
            "platforms": "Linux",
            "status": "Released",
            "stars": 0,
            "created_at": datetime.now(timezone.utc).isoformat(),
        }
    )
    return slug, uid
def _seed_news_image(news_uid):
    from devplacepy.database import get_table

    get_table("news_images").insert(
        {
            "deleted_at": None,
            "deleted_by": None,
            "news_uid": news_uid,
            "url": "https://example.com/seo-news-image.jpg",
            "is_placeholder": 0,
        }
    )
def _seed_feed_posts(count):
    from datetime import datetime, timezone, timedelta
    from uuid import uuid4
    from devplacepy.database import get_table
    from devplacepy.utils import make_combined_slug

    owner = _seed_owner()
    topic = f"seopag{owner[:8]}"
    base = datetime(2026, 1, 1, tzinfo=timezone.utc)
    posts = get_table("posts")
    for i in range(count):
        uid = str(uuid4())
        posts.insert(
            {
                "deleted_at": None,
                "deleted_by": None,
                "uid": uid,
                "user_uid": owner,
                "slug": make_combined_slug(f"seo pag {i}", uid),
                "title": None,
                "content": f"seo pag post {i}",
                "topic": topic,
                "project_uid": None,
                "image": None,
                "stars": 0,
                "created_at": (base - timedelta(seconds=i)).isoformat(),
            }
        )
    return topic


def test_news_detail_share_button(page, news_article):
    slug = news_article.get("slug") or news_article["uid"]
    page.goto(f"{BASE_URL}/news/{slug}", wait_until="domcontentloaded")
    assert_share_copies(page, "/news/")


def test_news_listing_loads(page, app_server):
    seed_news()
    page.goto(f"{BASE_URL}/news", wait_until="domcontentloaded")
    assert page.is_visible("text=Developer News")
    assert page.is_visible("text=News Test Article")


def test_news_listing_authenticated(alice):
    page, _ = alice
    seed_news()
    page.goto(f"{BASE_URL}/news", wait_until="domcontentloaded")
    assert page.is_visible("text=Developer News")


def test_news_detail_loads(page, news_article):
    slug = news_article.get("slug") or news_article["uid"]
    page.goto(f"{BASE_URL}/news/{slug}", wait_until="domcontentloaded")
    assert page.is_visible("text=News Test Article")
    assert page.is_visible("text=Comments")


def test_news_detail_404(page, app_server):
    page.goto(f"{BASE_URL}/news/nonexistent-article", wait_until="domcontentloaded")
    assert page.is_visible("text=not found", timeout=5000)


def test_news_comment(alice, news_article):
    page, _ = alice
    slug = news_article.get("slug") or news_article["uid"]
    page.goto(f"{BASE_URL}/news/{slug}", wait_until="domcontentloaded")
    page.fill("textarea[name='content']", "Test comment on news article")
    page.click("button:has-text('Post')")
    page.wait_for_url(f"{BASE_URL}/news/{slug}**", wait_until="domcontentloaded")
    assert page.is_visible("text=Test comment on news article")


def test_news_pagination_first_page(page, app_server):
    _seed_news_paginated(30)
    page.goto(f"{BASE_URL}/news", wait_until="domcontentloaded")
    assert page.locator(".news-card").count() == 25
    assert page.is_visible(".load-more-wrap")


def test_news_pagination_load_more(page, app_server):
    titles = _seed_news_paginated(30)
    page.goto(f"{BASE_URL}/news", wait_until="domcontentloaded")
    newest = titles[0]
    assert page.is_visible(f".news-card-title:has-text('{newest}')")
    page.click(".load-more-wrap a")
    page.wait_for_url(lambda url: "before=" in url, wait_until="domcontentloaded")
    assert not page.is_visible(f".news-card-title:has-text('{newest}')")
    assert page.locator(".news-card").count() >= 1


def test_news_detail_guest(page, news_article):
    slug = news_article.get("slug") or news_article["uid"]
    page.goto(f"{BASE_URL}/news/{slug}", wait_until="domcontentloaded")
    assert page.is_visible("text=News Test Article")
    assert page.is_visible("text=Comments")
    assert page.is_visible("text=Read on TestSource")


def test_news_detail_has_newsarticle_schema(page, app_server):
    slug, _ = _seed_news_seo()
    page.goto(f"{BASE_URL}/news/{slug}", wait_until="domcontentloaded")
    scripts = page.locator('script[type="application/ld+json"]')
    text = " ".join(scripts.nth(i).text_content() for i in range(scripts.count()))
    assert "NewsArticle" in text
    assert (
        page.locator('meta[property="og:type"]').get_attribute("content") == "article"
    )


def test_news_detail_image_has_alt_text(page, app_server):
    slug, uid = _seed_news_seo()
    _seed_news_image(uid)
    page.goto(f"{BASE_URL}/news/{slug}", wait_until="domcontentloaded")
    alt = page.locator(".news-detail-image img").get_attribute("alt")
    assert alt and alt.strip()


def _seed_news_with_comments():
    owner = str(uuid4())
    get_table("users").insert(
        {
            "uid": owner,
            "username": f"ncseed_{owner[:8]}",
            "terms_version": "1",
            "email": f"{owner[:8]}@nc.seed",
            "password_hash": "x",
            "role": "Member",
            "is_active": True,
            "created_at": datetime.now(timezone.utc).isoformat(),
        }
    )
    uid = str(uuid4())
    marker = f"newscom-{uid[:8]}"
    get_table("news").insert(
        {
            "deleted_at": None,
            "deleted_by": None,
            "uid": uid,
            "slug": make_combined_slug(marker, uid),
            "title": marker,
            "description": "News with comment hierarchy.",
            "content": "Body.",
            "url": "https://example.com/nc",
            "source_name": "NCSource",
            "external_id": f"nc_{uid[:8]}",
            "status": "published",
            "show_on_landing": 0,
            "grade": 10,
            "synced_at": datetime.now(timezone.utc).isoformat(),
        }
    )
    parent = str(uuid4())
    base = datetime.now(timezone.utc)
    rows = [
        (f"{marker}-excluded", str(uuid4()), None, -2),
        (f"{marker}-flat", str(uuid4()), None, -1),
        (f"{marker}-parent", parent, None, 0),
        (f"{marker}-reply", str(uuid4()), parent, 1),
    ]
    comments = get_table("comments")
    for content, cuid, par, off in rows:
        comments.insert(
            {
                "deleted_at": None,
                "deleted_by": None,
                "uid": cuid,
                "target_type": "news",
                "target_uid": uid,
                "user_uid": owner,
                "content": content,
                "parent_uid": par,
                "created_at": (base + timedelta(seconds=off)).isoformat(),
            }
        )
    return marker


def test_news_list_preserves_comment_hierarchy(page, app_server):
    from playwright.sync_api import expect

    marker = _seed_news_with_comments()
    page.goto(f"{BASE_URL}/news", wait_until="domcontentloaded")
    card = page.locator(".news-card").filter(has_text=marker).first
    card.wait_for(state="visible")
    previews = card.locator(".post-card-comments .comment-text")
    expect(previews).to_have_count(3)
    expect(card.locator(".post-card-comments")).not_to_contain_text(f"{marker}-excluded")
    nested = card.locator(".post-card-comments .comment-replies .comment-text")
    expect(nested).to_contain_text(f"{marker}-reply")
