"""
Lenh `dsg fix-mp4` — cap nhat mp4 link cho cac video da co share link nhung chua co mp4.

Flow moi profile:
1. Mo Chrome, vao https://sora.chatgpt.com/drafts
2. Lay raw HTML, parse tat ca card co href /p/s_... (da share)
3. Hien thi tong so card tim duoc, yeu cau nhap start index va so luong xu ly
4. Voi moi card trong pham vi do:
   - Lay share link tu href /p/s_... -> URL day du
   - Lay video mp4 tu <video src="...">
5. Goi PATCH /sora-videos/update-mp4-by-share-link
6. Dong Chrome, sang profile tiep theo
"""
from __future__ import annotations

import html as html_lib
import re
import sys
import time

import click
import questionary

from ..api_client import update_mp4_by_share_link
from ..browser_launcher import close_chrome, launch_chrome_for_automation
from ..config import load_settings, validate_settings
from ..constants import CDP_PORT_BASE
from ..profile_manager import ensure_profile_exists
from .common import _BOLD

DRAFTS_URL = "https://sora.chatgpt.com/drafts"
BASE_URL = "https://sora.chatgpt.com"


# ---------------------------------------------------------------------------
# HTML parsing
# ---------------------------------------------------------------------------

def _get_shared_video_cards(page) -> list[dict]:
    """
    Scroll, lay raw HTML, parse tat ca card co href /p/s_... (da duoc share).
    Tra ve list dict: {index, share_link, video_src}
    """
    page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
    time.sleep(1.5)
    page.evaluate("window.scrollTo(0, 0)")
    time.sleep(0.5)

    html = page.content()
    cards_raw = re.split(r'(?=<div data-index="\d+")', html)

    results: list[dict] = []
    for card in cards_raw:
        idx_match = re.search(r'<div data-index="(\d+)"', card)
        if not idx_match:
            continue
        card_index = int(idx_match.group(1))

        # Chi lay card da share (href /p/s_...)
        href_match = re.search(r'<a\s+href="(/p/s_[^"]+)"', card)
        if not href_match:
            continue

        share_link = BASE_URL + href_match.group(1)

        src_match = re.search(r'<video\s+src="(https://[^"]+)"', card)
        video_src = html_lib.unescape(src_match.group(1)) if src_match else None

        results.append({
            "index": card_index,
            "share_link": share_link,
            "video_src": video_src,
        })

    return results


# ---------------------------------------------------------------------------
# Profile processor
# ---------------------------------------------------------------------------

def _process_profile_fix_mp4(
    profile: dict,
    profile_idx: int,
    settings: dict,
    counters: dict,
) -> None:
    """Mo Chrome cho 1 profile, fix mp4 cho cac card da share theo index."""
    profile_id = profile["id"]
    alias = profile.get("alias", profile_id)
    debug_port = CDP_PORT_BASE + profile_idx
    profile_path = ensure_profile_exists(profile_id)
    proc = pw = None

    try:
        proc, pw, _browser, _context, page = launch_chrome_for_automation(
            profile_path, debug_port
        )

        page.goto(DRAFTS_URL, wait_until="domcontentloaded", timeout=30_000)
        time.sleep(2)

        # Cho trang load: kiem tra moi 5s, toi da 30s
        cards: list[dict] = []
        waited = 0
        while waited <= 30:
            cards = _get_shared_video_cards(page)
            if cards:
                break
            if waited < 30:
                click.echo(f"  [{alias}] Chua co card, cho them 5s ({waited}/30s)...")
                time.sleep(5)
            waited += 5

        if not cards:
            click.echo(f"  [{alias}] Khong tim thay card nao da share.")
            return

        click.echo(f"  [{alias}] Tim thay {len(cards)} card da share (index {cards[0]['index']}–{cards[-1]['index']}).")

        # Hoi nguoi dung pham vi can xu ly (dung click.prompt de tranh conflict asyncio)
        try:
            start = click.prompt(
                f"  [{alias}] Bat dau tu index nao? (0–{len(cards)-1})",
                default=0,
                type=click.IntRange(0, len(cards) - 1),
            )
            count = click.prompt(
                f"  [{alias}] Xu ly bao nhieu card?",
                default=len(cards),
                type=click.IntRange(1, len(cards)),
            )
        except (click.Abort, ValueError):
            click.echo(f"\n  [{alias}] Da huy.")
            return

        subset = cards[start: start + count]
        click.echo(f"  [{alias}] Se xu ly {len(subset)} card (index {subset[0]['index']}–{subset[-1]['index']}).")

        for i, card in enumerate(subset, 1):
            share_link = card["share_link"]
            video_src = card["video_src"]
            click.echo(f"\n    [{alias}] ({i}/{len(subset)}) index={card['index']}")
            click.echo(f"    [{alias}] Share link : {share_link}")
            if video_src:
                click.echo(f"    [{alias}] MP4       : {video_src[:80]}...")
            else:
                click.echo(f"    [{alias}] MP4       : (khong tim thay trong HTML)")

            try:
                result = update_mp4_by_share_link(
                    share_link, video_src, settings["backend_key"]
                )
                updated = result.get("updated", "?")
                click.echo(f"    [{alias}] Da cap nhat {updated} ban ghi.")
                counters["done"] += 1
            except Exception as api_err:
                click.echo(f"    [{alias}] Loi API: {api_err}")
                counters["failed"] += 1

    except Exception as e:
        click.echo(f"  LOI [{alias}]: {e}")
    finally:
        if pw:
            try:
                pw.stop()
            except Exception:
                pass
        if proc:
            close_chrome(proc)
            click.echo(f"  Da dong Chrome: {alias}")


# ---------------------------------------------------------------------------
# CLI command
# ---------------------------------------------------------------------------

def cmd_fix_mp4() -> None:
    """Cap nhat mp4 link cho cac video da share nhung chua co mp4."""
    settings = load_settings()
    try:
        validate_settings(settings)
    except ValueError as e:
        click.echo(f"Loi cau hinh: {e}", err=True)
        sys.exit(1)

    profiles = settings["profiles"]
    if not profiles:
        click.echo("Chua co profile nao. Chay `dsg setup` truoc.")
        sys.exit(1)

    if len(profiles) == 1:
        selected = profiles
    else:
        choices = [
            questionary.Choice(
                title=f"{p.get('alias', p['id'])} ({p['id']})", value=p, checked=False
            )
            for p in profiles
        ]
        selected = questionary.checkbox(
            "Chon profile can fix mp4 (Space: chon/bo, Enter: xac nhan)",
            choices=choices,
        ).ask()
        if not selected:
            click.echo("Khong co profile nao duoc chon.")
            sys.exit(0)

    counters: dict = {"done": 0, "failed": 0}

    click.echo(f"\n{_BOLD}")
    click.echo("  SORA FIX MP4 TOOL")
    click.echo(_BOLD)
    click.echo(f"  Username  : {settings['username']}")
    click.echo(
        f"  Profiles  : {', '.join(p.get('alias', p['id']) for p in selected)}"
    )
    click.echo(_BOLD)

    for profile in selected:
        profile_idx = next(
            (i for i, p in enumerate(profiles) if p["id"] == profile["id"]), 0
        )
        click.echo(f"\n  Profile: {profile.get('alias', profile['id'])}")
        _process_profile_fix_mp4(profile, profile_idx, settings, counters)

    click.echo(f"\n{_BOLD}")
    click.echo("  HOAN TAT")
    click.echo(_BOLD)
    click.echo(f"  Cap nhat thanh cong : {counters['done']}")
    click.echo(f"  Loi                 : {counters['failed']}")
    click.echo(_BOLD)


def register_fix_mp4(main: click.Group) -> None:
    main.command("fix-mp4")(cmd_fix_mp4)
