"""Backfill doc_pages.product_id for tenant_internal.

For each doc_page, infer product_id from the page URL using the same slug-map
logic as the scraper. Also unescapes HTML entities in existing page_title values,
and re-embeds pages whose content_text is > 4000 chars using the full [:8000]
slice (the old scraper used [:4000]).

Usage:
    venv/bin/python scripts/backfill_doc_page_products.py

Idempotent: safe to re-run (re-detects product_id; only re-embeds if text > 4k).
"""
from __future__ import annotations

import html
import os
import sys
import struct

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

from supporthub.app.db import session_scope
from supporthub.app.models import DocPage, AddonsProducts
from supporthub.app.services.doc_scraper_service import _build_slug_map, _detect_product_id

SCHEMA = "tenant_internal"


def _pack_embedding(vec):
    return struct.pack(f"{len(vec)}f", *vec)


def main():
    print(f"Backfilling doc_pages.product_id for schema: {SCHEMA}\n")

    with session_scope(schema=SCHEMA) as session:
        # Build slug map
        slug_map = _build_slug_map(session)
        print(f"Slug map: {len(slug_map)} entries")

        # Load all products for display
        products = {p.id: p.name for p in session.query(AddonsProducts).all()}

        # Load all doc pages
        pages = session.query(DocPage).all()
        print(f"Doc pages: {len(pages)} total\n")

        assigned = 0
        unassigned = 0
        title_unescaped = 0
        reembedded = 0

        rows = []
        for page in pages:
            detected = _detect_product_id(page.url, slug_map)
            product_name = products.get(detected, "None") if detected else "None"

            # Unescape HTML entities in page_title
            old_title = page.page_title
            if old_title:
                new_title = html.unescape(old_title)
                if new_title != old_title:
                    page.page_title = new_title
                    title_unescaped += 1

            page.product_id = detected
            if detected:
                assigned += 1
            else:
                unassigned += 1

            rows.append((page.url, product_name or "None"))

        session.flush()

        # Re-embed pages with content_text > 4000 chars using the full [:8000] slice
        print("Re-embedding pages with content_text > 4000 chars …")
        try:
            from supporthub.app.services.embedding_service import EmbeddingService, pack_embedding
            from supporthub.app.config import config as app_config

            embed_service = EmbeddingService()
            for page in pages:
                if page.content_text and len(page.content_text) > 4000:
                    try:
                        embedding = embed_service._get_embedding(page.content_text[:8000])
                        if embedding:
                            page.embedding_blob = pack_embedding(embedding)
                            page.model_used = app_config.EMBEDDING_MODEL
                            page.dimensions = len(embedding)
                            reembedded += 1
                    except Exception as exc:
                        print(f"  WARNING: failed to embed page {page.id} ({page.url}): {exc}")
        except Exception as exc:
            print(f"  WARNING: embedding step failed: {exc}")

    # Print table
    print("\n{:<80} {}".format("URL", "Product"))
    print("-" * 100)
    for url, prod in sorted(rows, key=lambda r: r[1]):
        print("{:<80} {}".format(url[:80], prod))

    print(f"\n{'─'*100}")
    print(f"Assigned:       {assigned}")
    print(f"Unassigned:     {unassigned}")
    print(f"Titles fixed:   {title_unescaped}")
    print(f"Re-embedded:    {reembedded}")

    # Reload doc index
    try:
        from supporthub.app.services.embedding_service import embedding_index
        embedding_index.load_doc_pages_from_db(schema=SCHEMA)
        print(f"\nDoc index reloaded.")
    except Exception as exc:
        print(f"\nWARNING: Failed to reload doc index: {exc}")


if __name__ == "__main__":
    main()
