#!/usr/bin/env python3
"""
Backfill sx_content from lexical JSON for all posts that have lexical but no sx_content.

Usage:
    python -m blog.scripts.backfill_sx_content [--dry-run]
"""
from __future__ import annotations

import argparse
import asyncio
import sys

from sqlalchemy import select, and_
from sqlalchemy.ext.asyncio import AsyncSession


async def backfill(dry_run: bool = False) -> int:
    from shared.db.session import get_session
    from models.ghost_content import Post
    from bp.blog.ghost.lexical_to_sx import lexical_to_sx

    converted = 0
    errors = 0

    async with get_session() as sess:
        stmt = select(Post).where(
            and_(
                Post.lexical.isnot(None),
                Post.lexical != "",
                (Post.sx_content.is_(None)) | (Post.sx_content == ""),
            )
        )
        result = await sess.execute(stmt)
        posts = result.scalars().all()

        print(f"Found {len(posts)} posts to convert")

        for post in posts:
            try:
                sx = lexical_to_sx(post.lexical)
                if dry_run:
                    print(f"  [DRY RUN] {post.slug}: {len(sx)} chars")
                else:
                    post.sx_content = sx
                    print(f"  Converted: {post.slug} ({len(sx)} chars)")
                converted += 1
            except Exception as e:
                print(f"  ERROR: {post.slug}: {e}", file=sys.stderr)
                errors += 1

        if not dry_run:
            await sess.commit()

    print(f"\nDone: {converted} converted, {errors} errors")
    return converted


def main():
    parser = argparse.ArgumentParser(description="Backfill sx_content from lexical JSON")
    parser.add_argument("--dry-run", action="store_true", help="Don't write to database")
    args = parser.parse_args()

    asyncio.run(backfill(dry_run=args.dry_run))


if __name__ == "__main__":
    main()
