"""Migration for REDEEMED bug fix in Miami-Dade Clerk scraper.

Steps:
1. ALTER TABLE deals ADD COLUMN auction_status (if not exists).
2. Re-parse all cached Miami-Dade HTML using the new parser to get a SET of
   live case_numbers (i.e., cases that did NOT have a dead status).
3. For each miami_dade_clerk deal in deals.db:
   - If case_number in live set → update auction_status to the live status.
   - If NOT in live set → it's likely a dead case (REDEEMED/CANCELED/etc) that
     the old parser kept. Mark it auction_status='Dismissed (re-parse)' so
     the search UI filters it out.
"""
from __future__ import annotations
import io, sys, glob
from pathlib import Path
from collections import defaultdict

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))

from deals_db import init_db, _get_conn
from scrapers.miami_dade_clerk import _parse_cases_from_html


def add_column_if_missing(conn, table: str, col: str, coltype: str = "TEXT"):
    cols = [r["name"] for r in conn.execute(f"PRAGMA table_info({table})").fetchall()]
    if col not in cols:
        conn.execute(f"ALTER TABLE {table} ADD COLUMN {col} {coltype}")
        return True
    return False


def main() -> int:
    init_db()
    conn = _get_conn()

    # ─── Step 1: ALTER TABLE ───────────────────────────────────────────────
    added = add_column_if_missing(conn, "deals", "auction_status", "TEXT")
    print(f"Step 1: auction_status column {'ADDED' if added else 'already exists'}")

    # ─── Step 2: Re-parse cached HTML to get live case set ─────────────────
    print()
    print("Step 2: Re-parsing cached Miami-Dade HTML...")
    cached_files = sorted(glob.glob(str(ROOT / ".cache/scrapers/miami_dade_clerk/*.html")))
    print(f"  cached HTMLs found: {len(cached_files)}")

    live_case_to_status: dict[str, str] = {}
    files_processed = 0
    for f in cached_files:
        html = Path(f).read_text(encoding="utf-8")
        if len(html) < 20_000:
            continue  # skip "no results" placeholder pages
        files_processed += 1
        cases = _parse_cases_from_html(html)
        for case in cases:
            cn = case.get("case_number")
            if cn and cn not in live_case_to_status:
                live_case_to_status[cn] = case.get("auction_status") or "scheduled"
    print(f"  files processed: {files_processed}")
    print(f"  live case_numbers extracted: {len(live_case_to_status)}")

    # ─── Step 3: Compare with deals.db ─────────────────────────────────────
    print()
    print("Step 3: Matching against deals.db...")
    rows = conn.execute(
        "SELECT id, case_number, address, listing_price, deal_type FROM deals "
        "WHERE source = 'miami_dade_clerk'"
    ).fetchall()
    print(f"  deals in db (miami_dade_clerk): {len(rows)}")

    live_updates = 0
    dead_updates = 0
    no_cache_match = 0  # case was in db but not in any cached HTML (cache expired or different date)
    samples = {"live": [], "dead": [], "no_cache": []}

    for r in rows:
        cn = r["case_number"]
        if not cn:
            continue
        if cn in live_case_to_status:
            status = live_case_to_status[cn]
            conn.execute("UPDATE deals SET auction_status = ? WHERE id = ?",
                         (status, r["id"]))
            live_updates += 1
            if len(samples["live"]) < 3:
                samples["live"].append((cn, r["address"], status))
        else:
            # Case was in db but NOT found in current cache.
            # Two possibilities:
            #  (a) cached HTML is stale or doesn't cover this date — case may still be live
            #  (b) case was REDEEMED/CANCELED — old parser kept it, new one filters
            # Conservative: mark as 'Dismissed (re-parse miss)' so it filters out.
            # If user wants them back, can be undone by changing status manually.
            conn.execute(
                "UPDATE deals SET auction_status = ? WHERE id = ?",
                ("Dismissed (re-parse miss)", r["id"]),
            )
            dead_updates += 1
            if len(samples["dead"]) < 5:
                samples["dead"].append((cn, r["address"], r["deal_type"]))

    print(f"\n  Live (updated with current status):  {live_updates}")
    print(f"  Dismissed (not in cache, filtered):  {dead_updates}")

    # ─── Step 4: Show samples ──────────────────────────────────────────────
    print()
    print("Samples of LIVE updates:")
    for cn, addr, status in samples["live"]:
        print(f"  {cn:<25} status={status:<15} addr={(addr or '?')[:50]}")

    print()
    print("Samples of DISMISSED (filtered) deals:")
    for cn, addr, dtype in samples["dead"]:
        print(f"  {cn:<25} type={dtype:<10} addr={(addr or '?')[:50]}")

    # ─── Step 5: Verify totals ─────────────────────────────────────────────
    print()
    print("=== Final state ===")
    rows = conn.execute("""
        SELECT auction_status, COUNT(*) AS n
        FROM deals
        WHERE source = 'miami_dade_clerk'
        GROUP BY auction_status
    """).fetchall()
    for r in rows:
        print(f"  status={r['auction_status']}: {r['n']}")

    # Search-time count (mimicking what user sees)
    visible = conn.execute("""
        SELECT COUNT(*) AS n FROM deals
        WHERE source='miami_dade_clerk'
          AND COALESCE(LOWER(auction_status), '') NOT IN
              ('redeemed', 'canceled', 'cancelled', 'sold', 'closed',
               'title transferred', 'withdrawn', 'dismissed',
               'dismissed (re-parse miss)')
    """).fetchone()["n"]
    print(f"\n  Visible in search results (post-filter): {visible}")

    return 0


if __name__ == "__main__":
    sys.exit(main())
