"""Stake a fill-only claim for each leaf category with exactly one article.

Through `topic_claims`, the same service the route calls, so the limit check
and the link-writing are the code that is tested rather than a second copy.
`--apply` to write; without it, nothing is written.
"""
import sys

from app.database import SessionLocal
from app.models.article import Article, ArticleTopicClaim
from app.models.question_category import QuestionCategory
from app.services import topic_claims

APPLY = "--apply" in sys.argv
db = SessionLocal()

# Leaf categories with exactly one published article.
rows = db.execute(topic_claims.sa_text("""
    select c.id, c.name, min(a.id)
      from question_categories c
      join articles a on a.category_id = c.id
       and a.deleted_at is null and a.status = 'published'
     where c.parent_id is not null
     group by c.id, c.name
    having count(a.id) = 1
     order by c.name
""") if hasattr(topic_claims, "sa_text") else None).all() if False else None

from sqlalchemy import text as sa_text  # noqa: E402
rows = db.execute(sa_text("""
    select c.id, c.name, min(a.id) as article_id
      from question_categories c
      join articles a on a.category_id = c.id
       and a.deleted_at is null and a.status = 'published'
     where c.parent_id is not null
     group by c.id, c.name
    having count(a.id) = 1
     order by c.name
""")).all()

total_would, total_made, staked, skipped = 0, 0, 0, []
for cat_id, cat_name, article_id in rows:
    claim = db.query(ArticleTopicClaim).filter_by(
        article_id=article_id, category_id=cat_id, section_id=None).first()
    like = claim or type("L", (), {
        "article_id": article_id, "category_id": cat_id, "section_id": None,
        "include_subtopics": True, "fill_only": True})()
    priced = topic_claims.preview(db, like)
    if priced["would_link"] == 0:
        continue
    if priced["would_link"] > topic_claims.MAX_LINKS_PER_CLAIM:
        skipped.append((cat_id, cat_name, priced["would_link"]))
        continue
    total_would += priced["would_link"]
    staked += 1
    if APPLY:
        if claim is None:
            claim = ArticleTopicClaim(
                article_id=article_id, category_id=cat_id, section_id=None,
                include_subtopics=True, fill_only=True, user_id=None)
            db.add(claim)
            db.commit()
            db.refresh(claim)
        total_made += topic_claims.apply(db, claim)

print(f"categories: {len(rows)}  with gaps to fill: {staked}")
print(f"would link: {total_would}   linked: {total_made}   applied: {APPLY}")
for row in skipped:
    print("over the limit, skipped:", row)
db.close()
