"""
Data Service for Historical-2d Review Dashboard.
Extracts and structures project data from markdown and json files.
"""

import os
import re
import json
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent.parent
OUTPUT_DIR = BASE_DIR / "output"
EPISODES_DIR = BASE_DIR / "episodes"
DATA_DIR = BASE_DIR / "data"
ASSETS_DIR = BASE_DIR / "assets"
FEEDBACK_FILE = DATA_DIR / "producer_feedback.json"


def get_system_status():
    """Returns real-time system and hardware status."""
    ep01_seamless = EPISODES_DIR / "EP01_Cannae_216BC" / "06_Master_Output" / "EP01_Cannae_Master_Seamless.mp4"
    return {
        "studio": "Historical-2d",
        "project_scope": "historical-2d",
        "owner": "Seven Nguyen (Executive Producer)",
        "ceo": "Amy (Studio CEO & Lead Orchestrator)",
        "tailscale_ip": "100.121.197.18",
        "port": 1516,
        "access_url": "http://100.121.197.18:1516",
        "local_url": "http://localhost:1516",
        "cpu": "Dual Intel Xeon E5-2680 v4 (28 Cores / 56 Threads, 2.40 GHz)",
        "gpu": "NVIDIA GeForce GTX 1660 Super (6GB NVENC Turing)",
        "ram": "64 GB ECC DDR4",
        "timestamp": "2026-10-10T08:05:00+07:00",
        "status": "ONLINE",
        "video_master": {
            "name": "the_historical_vault_intro_master.mp4",
            "size_mb": round(os.path.getsize(OUTPUT_DIR / "the_historical_vault_intro_master.mp4") / (1024*1024), 2)
            if (OUTPUT_DIR / "the_historical_vault_intro_master.mp4").exists() else 0,
            "duration": "30.98s",
            "resolution": "1920x1080 (1080p@30fps NVENC)",
            "audio": "Dual Tracks (EN: Christopher Baritone / VI: NamMinh Epic) + Binaural War Drum Ambience (-14 LUFS)"
        },
        "ep01_master": {
            "name": "EP01_Cannae_Master_Seamless.mp4",
            "size_mb": round(os.path.getsize(ep01_seamless) / (1024*1024), 2) if ep01_seamless.exists() else 0,
            "duration": "271.90s (~4m32s)",
            "resolution": "1920x1080 (1080p@30fps NVENC)",
            "status": "COMPLETED & READY FOR REVIEW",
            "prologue": "cannae_prologue_master.mp4 (175.9s, 11.2 MB • English Historical Briefing)",
            "bridge": "cannae_cinematic_bridge.mp4 (5.0s, 10.8 MB • Match-Cut)",
            "tactical": "cannae_tactical_map_master.mp4 (60.0s, 29.5 MB • Soldier Icons)",
            "audio": "100% English Master Track (en-US-ChristopherNeural) + Pure Ambient Soundbed (-14.0 LUFS EBU R128)"
        }
    }


def get_intro_scenes():
    """Returns scene breakdown of the intro video."""
    return [
        {
            "scene": 1,
            "title": "Opening Hook & Host Introduction",
            "timecode": "00:00 - 00:06",
            "preview_img": "/media/output/final_snap_s1.jpg",
            "master_img": "/media/output/master_snap_s1.jpg",
            "pose": "Pose 1 (Authoritative Welcome)",
            "description": "Host Seven Nguyen xuất hiện tại War Room Tabletop, chào mừng khán giả tới The Historical Vault với phong cách Obsidian Gold điện ảnh.",
            "audio_cue": "War Drum Accent + Binaural Ambience Fade-in"
        },
        {
            "scene": 2,
            "title": "The Strategic Conundrum (Cannae Preview)",
            "timecode": "00:06 - 00:13",
            "preview_img": "/media/output/final_snap_s2.jpg",
            "master_img": "/media/output/master_snap_s2.jpg",
            "pose": "Pose 2 (Tactical Explanation)",
            "description": "Giới thiệu câu hỏi quân sự hóc búa của Hannibal: 50.000 quân Carthage chống lại 86.000 lính La Mã.",
            "audio_cue": "Voiceover: Hannibal's convex line dilemma"
        },
        {
            "scene": 3,
            "title": "Tactical Micro-Terrain & Encirclement Vector",
            "timecode": "00:13 - 00:19",
            "preview_img": "/media/output/final_snap_s3.jpg",
            "master_img": "/media/output/master_snap_s3.jpg",
            "pose": "Pose 3 (Analytical Breakdown)",
            "description": "Sa bàn nghiêng 3D hiển thị sông Aufidus và thung lũng Cannae. Đội hình biến đổi từ lồi sang lõm.",
            "audio_cue": "Bézier vector sound cue, high-precision tactical sweep"
        },
        {
            "scene": 4,
            "title": "War Room Command Rail & Casualty Metrics",
            "timecode": "00:19 - 00:25",
            "preview_img": "/media/output/final_snap_s4.jpg",
            "master_img": "/media/output/master_snap_s4.jpg",
            "pose": "Pose 4 (Command Presence)",
            "description": "Host Seven Nguyen đứng cạnh thanh ray chỉ huy (Command Rail), bộ đếm thương vong thời gian thực cán mốc 70.000 lính La Mã.",
            "audio_cue": "Deep sub-bass impact, casualty HUD alert"
        },
        {
            "scene": 5,
            "title": "Climax Call-to-Action & Channel Branding",
            "timecode": "00:25 - 00:30.98",
            "preview_img": "/media/output/final_snap_s5.jpg",
            "master_img": "/media/output/master_snap_s5.jpg",
            "pose": "Pose 6 (Decisive Call-to-Action)",
            "description": "Biểu tượng The Historical Vault tỏa sáng Chiaroscuro, lời kêu gọi đăng ký phân tích 30 chiến dịch lớn.",
            "audio_cue": "Crescendo orchestral war drums & outro sweep"
        }
    ]


def get_episodes_list():
    """Extracts all 30 episodes from MASTER_PRODUCTION_PLAN_30_EPISODES.md without regex backtracking."""
    plan_path = DATA_DIR / "MASTER_PRODUCTION_PLAN_30_EPISODES.md"
    episodes = []
    
    if plan_path.exists():
        with open(plan_path, "r", encoding="utf-8") as f:
            content = f.read()

        blocks = content.split("### Tập ")
        for block in blocks[1:]:
            lines = [l.strip() for l in block.split("\n") if l.strip()]
            if not lines:
                continue
            
            header = lines[0]
            # e.g. "01: Battle of Cannae (216 BC) – The Anatomy of a Perfect Encirclement"
            parts = header.split(":", 1)
            try:
                ep_num = int(parts[0].strip())
            except ValueError:
                continue
            ep_title = parts[1].strip() if len(parts) > 1 else header

            date = ""
            duration = ""
            rpm = ""
            tactics = ""

            for line in lines[1:]:
                if line.startswith("* **Niên đại:**"):
                    date = line.replace("* **Niên đại:**", "").strip()
                elif line.startswith("* **Thời lượng chuẩn:**"):
                    duration = line.replace("* **Thời lượng chuẩn:**", "").strip()
                elif line.startswith("* **Dự báo RPM:**"):
                    rpm = line.replace("* **Dự báo RPM:**", "").strip()
                elif line.startswith("* **Đòn điểm nhấn chiến thuật"):
                    # following lines or this line
                    tactics = line.split(":", 1)[1].strip() if ":" in line else ""
                elif tactics and not line.startswith("* **Hook") and not line.startswith("---") and not line.startswith("#"):
                    tactics += " " + line

            season = "Mùa 1: The Vanguard & Ancient Titans" if ep_num <= 10 else (
                "Mùa 2: Gunpowder & The Napoleonic Storm" if ep_num <= 20 else
                "Mùa 3: Modern Firestorms & Asymmetric Warfare"
            )
            era = "Cổ đại & Trung cổ" if ep_num <= 10 else (
                "Hỏa khí & Thế kỷ 19" if ep_num <= 20 else
                "Thế chiến & Hiện đại"
            )
            
            folder_name = f"EP{ep_num:02d}_"
            matched_folders = [f for f in os.listdir(EPISODES_DIR) if f.startswith(folder_name)] if EPISODES_DIR.exists() else []
            folder_path = matched_folders[0] if matched_folders else ""

            status = "Sẵn sàng sản xuất (Script + 4K Map + Timeline xong)" if ep_num == 1 else "Đã thiết lập khung kiến trúc"

            episodes.append({
                "number": ep_num,
                "code": f"EP{ep_num:02d}",
                "title": ep_title,
                "season": season,
                "era": era,
                "date": date,
                "duration": duration,
                "target_rpm": rpm,
                "core_tactics": tactics[:400] + "..." if len(tactics) > 400 else tactics,
                "status": status,
                "folder": folder_path
            })

    return episodes



def get_ep01_detail():
    """Returns comprehensive detail of EP01 Cannae 216 BC."""
    ep_dir = EPISODES_DIR / "EP01_Cannae_216BC"
    timeline_file = ep_dir / "03_Timeline_Data" / "cannae_operational_timeline.json"
    timeline_data = {}
    if timeline_file.exists():
        with open(timeline_file, "r", encoding="utf-8") as f:
            timeline_data = json.load(f)

    script_file = ep_dir / "01_Script" / "script_cannae_30m.md"
    script_content = ""
    if script_file.exists():
        with open(script_file, "r", encoding="utf-8") as f:
            script_content = f.read()

    return {
        "metadata": {
            "title": "Battle of Cannae (216 BC) – The Anatomy of a Perfect Encirclement",
            "date": "02/08/216 TCN",
            "location": "Cannae, Apulia, Đông Nam Ý (Venosa / Canosa di Puglia)",
            "commanders": {
                "carthage": "Hannibal Barca, Hasdrubal, Maharbal (50.000 quân)",
                "rome": "Lucius Aemilius Paullus, Gaius Terentius Varro (86.400 quân)"
            },
            "casualties": {
                "carthage": "5.700 (4.000 lính Celt, 1.500 lính Iberia, 200 kỵ binh)",
                "rome": "70.000 tử trận, 10.000 bị bắt (bao gồm Paullus & 80 Nguyên lão)"
            }
        },
        "map_assets": [
            {
                "name": "Bản đồ Địa hình 4K (Cannae Shaded Relief 4K)",
                "file": "/media/episodes/EP01_Cannae_216BC/02_Map_Data/cannae_terrain_4k.png",
                "desc": "3840x2160 Shaded relief kết hợp DEM độ cao thực tế và sông Aufidus."
            },
            {
                "name": "Bản đồ Độ cao Bóng Đổ (Cannae Hillshade)",
                "file": "/media/episodes/EP01_Cannae_216BC/02_Map_Data/cannae_hillshade.png",
                "desc": "Bản đồ bóng địa hình SRTM tách biệt làm nền sa bàn 3D."
            },
            {
                "name": "Sa bàn Vector Tác chiến SVG (NATO APP-6 Icons)",
                "file": "/media/episodes/EP01_Cannae_216BC/02_Map_Data/cannae_tactical_vector.svg",
                "desc": "Mũi tên chiến thuật Bézier và khối quân bài gỗ Carthaginian vs Roman."
            },
            {
                "name": "Bản đồ Tiêu chuẩn 1080p (Cannae 1080p)",
                "file": "/media/episodes/EP01_Cannae_216BC/02_Map_Data/cannae_terrain_1080p.png",
                "desc": "1920x1080 tối ưu render trực tiếp."
            }
        ],
        "video_assets": {
            "seamless": {
                "id": "seamless",
                "title": "Bản Master Liền Mạch 4 Phân Đoạn (271.9s: Intro + Dẫn Nhập 176s + Cầu Nối + Sa Bàn Tác Chiến - 100% English)",
                "file": "/media/episodes/EP01_Cannae_216BC/06_Master_Output/EP01_Cannae_Master_Seamless.mp4",
                "poster": "/media/episodes/EP01_Cannae_216BC/05_Renders/cannae_master_preview.jpg",
                "badge": "1080p NVENC • 271.9s SEAMLESS (~4m32s) • ENGLISH MASTER",
                "size_mb": 64.2,
                "desc": "Bản Master hoàn chỉnh 4 phân đoạn chuẩn tiếng Anh Tier 1: 01. Intro The Historical Vault (31s) -> 02. Dẫn nhập bối cảnh lịch sử tiếng Anh (Trebia, Trasimene, Fabius Cunctator, Varro & Paullus - 176s) -> 03. Cầu nối điện ảnh bão cát Volturnus (5s) -> 04. Sa bàn chiến thuật 12 khối quân với Icon Chiến Binh Lịch Sử đặc trưng & Host Seven Nguyen chỉ điểm (60s). Âm thanh Ambient thuần khiết, 0% chồng giọng."
            },
            "prologue": {
                "id": "prologue",
                "title": "Dẫn Nhập Lịch Sử Tiếng Anh (Trebia, Trasimene, Fabius & Canh Bạc Cannae)",
                "file": "/media/episodes/EP01_Cannae_216BC/05_Renders/cannae_prologue_master.mp4",
                "poster": "/media/episodes/EP01_Cannae_216BC/05_Renders/prologue_preview.jpg",
                "badge": "1080p • 5,277 FRAMES • 2m56s (175.9s) ENGLISH BRIEFING",
                "size_mb": 11.2,
                "desc": "Phân đoạn dẫn nhập điện ảnh tiếng Anh (175.9s) theo chỉ đạo của Producer Seven Nguyen: Bối cảnh Đệ nhị Chiến tranh Punic, vượt dãy Alps, các thất bại Trebia, Trasimene, học thuyết trì hoãn Fabius và cỗ xe ủi của 2 Chấp chính quan Varro & Paullus trước khi vào sa bàn. Giọng đọc Christopher Baritone EBU R128."
            },
            "bridge": {
                "id": "bridge",
                "title": "Cầu Nối Điện Ảnh 5s (Match-Cut Tilt-down & Bão Cát Volturnus)",
                "file": "/media/episodes/EP01_Cannae_216BC/05_Renders/cannae_cinematic_bridge.mp4",
                "poster": "/media/episodes/EP01_Cannae_216BC/05_Renders/bridge_preview_mid.jpg",
                "badge": "1080p • 150 FRAMES • MATCH-CUT",
                "size_mb": 10.8,
                "desc": "Cầu nối chuyển cảnh điện ảnh: Máy quay hạ góc nhìn từ bàn chỉ huy phòng tác chiến xuống lòng sông Aufidus, 750 hạt bụi cát Volturnus thổi xiên 45 độ, âm thanh bão cát và tiếng tù và cornu vang vọng."
            },
            "tactical": {
                "id": "tactical",
                "title": "Sa Bàn Tác Chiến 60s (Icon Chiến Binh Lịch Sử & Host Seven Nguyen Docking)",
                "file": "/media/episodes/EP01_Cannae_216BC/05_Renders/cannae_tactical_map_master.mp4",
                "poster": "/media/episodes/EP01_Cannae_216BC/05_Renders/cannae_master_preview.jpg",
                "badge": "1080p • 1,800 FRAMES • SOLDIER ICONS",
                "size_mb": 29.1,
                "desc": "Mô phỏng cơ học vây bọc kinh điển với 6 Icon Quân chủng Lịch sử đặc trưng (Lê dương La Mã, Cựu binh Libya, Kỵ binh Numidia, Chiến binh Gallic, Falcata Iberia, Kỵ binh Equites), 7 mũi tên Bézier xung lực phát quang, và Host Seven Nguyen chỉ điểm uốn cong cánh cung."
            }
        },
        "snapshots": [
            {
                "title": "Dẫn Nhập Lịch Sử 3 Phút (Trebia, Trasimene, Fabius & Cannae)",
                "file": "/media/episodes/EP01_Cannae_216BC/05_Renders/prologue_preview.jpg",
                "desc": "Phân cảnh dẫn nhập 182.5s bối cảnh Đệ nhị Chiến tranh Punic và học thuyết trì hoãn của Fabius."
            },
            {
                "title": "Cầu Nối Khúc Quanh Sông Aufidus (Match-Cut 5s)",
                "file": "/media/episodes/EP01_Cannae_216BC/05_Renders/bridge_preview_mid.jpg",
                "desc": "Hạ góc quay 3D xuống thung lũng Aufidus với 750 hạt bụi bão cát Volturnus."
            },
            {
                "title": "Sa Bàn Cannae Với Icon Chiến Binh Lịch Sử Đặc Trưng (60s)",
                "file": "/media/episodes/EP01_Cannae_216BC/05_Renders/cannae_master_preview.jpg",
                "desc": "12 khối quân bài gỗ tích hợp phù hiệu binh chủng lịch sử (Lê dương, Kỵ binh Numidia, Cựu binh Carthage, Gallic)."
            },
            {
                "title": "Host Seven Nguyen Docking Tại Trạm Chỉ Huy",
                "file": "/media/episodes/EP01_Cannae_216BC/05_Renders/preview_cue2_host.jpg",
                "desc": "Host Seven Nguyen docked tại Trạm B chỉ điểm khoảnh khắc cánh cung lồi biến dạng thành lòng chảo."
            },
            {
                "title": "Bộ Phù Hiệu Binh Chủng Lịch Sử 216 TCN (Lê Dương La Mã)",
                "file": "/media/episodes/EP01_Cannae_216BC/02_Map_Data/unit_icons/roman_legionary.png",
                "desc": "Mẫu phù hiệu Lê dương La Mã (Lorica Hamata, Khiên Scutum đỏ cánh sét mạ vàng, Lao Pilum)."
            }
        ],
        "audio_assets": [
            {
                "name": "1. Master Đa Âm Tiếng Việt 30 Phút (-14.6 LUFS)",
                "file": "/media/episodes/EP01_Cannae_216BC/04_Audio_Voice/master_mix/cannae_soundtrack_vi_30m_master.mp3",
                "desc": "Bản Master âm thanh hoàn chỉnh: Voiceover NamMinh Sử Thi + SFX tiếng cờ gỗ, vó ngựa + Binaural Soundbed."
            },
            {
                "name": "2. Master Đa Âm Tiếng Anh 30 Phút (-14.6 LUFS)",
                "file": "/media/episodes/EP01_Cannae_216BC/04_Audio_Voice/master_mix/cannae_soundtrack_en_30m_master.mp3",
                "desc": "Bản Master âm thanh tiếng Anh: Voiceover Christopher Baritone chuẩn phim tài liệu quốc tế Tier 1."
            },
            {
                "name": "3. Voiceover Tiếng Việt (Host Seven Nguyen)",
                "file": "/media/episodes/EP01_Cannae_216BC/04_Audio_Voice/voice_vi/cannae_voiceover_vi_30m_master.mp3",
                "desc": "Giọng đọc truyền cảm, đĩnh đạc của Host Seven Nguyen dẫn dắt toàn bộ 30 phút trận đánh."
            },
            {
                "name": "4. Voiceover Tiếng Anh (Christopher Baritone)",
                "file": "/media/episodes/EP01_Cannae_216BC/04_Audio_Voice/voice_en/cannae_voiceover_en_30m_master.mp3",
                "desc": "Track giọng đọc tiếng Anh trọn vẹn 30 phút phục vụ khán giả US/UK/Canada."
            }
        ],
        "timeline": timeline_data,
        "script": script_content
    }


def get_document(doc_id: str):
    """Returns markdown content for specified documents."""
    doc_map = {
        "anti_slop": OUTPUT_DIR / "STRATEGY_HOST_AVATAR_ANTI_AI_SLOP_2026.md",
        "rd_report": OUTPUT_DIR / "RD_REPORT_HIGH_RPM_TACTICAL_MAPS_2026.md",
        "master_plan": DATA_DIR / "MASTER_PRODUCTION_PLAN_30_EPISODES.md",
        "agents_spec": BASE_DIR / "AGENTS.md",
        "host_blueprint": EPISODES_DIR / "EP01_Cannae_216BC" / "01_Script" / "HOST_INTEGRATION_BLUEPRINT.md"
    }

    target = doc_map.get(doc_id)
    if target and target.exists():
        with open(target, "r", encoding="utf-8") as f:
            return {"id": doc_id, "title": target.name, "content": f.read()}
    return {"id": doc_id, "title": "Not Found", "content": "# Tài liệu không tồn tại"}


def get_feedback_list():
    """Gets saved feedback notes."""
    if not FEEDBACK_FILE.exists():
        return []
    try:
        with open(FEEDBACK_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    except Exception:
        return []


def save_feedback(data: dict):
    """Saves new feedback entry from Executive Producer Seven Nguyen."""
    notes = get_feedback_list()
    notes.insert(0, data)
    with open(FEEDBACK_FILE, "w", encoding="utf-8") as f:
        json.dump(notes, f, ensure_ascii=False, indent=2)
    return {"status": "success", "count": len(notes)}


if __name__ == "__main__":
    print("Status:", get_system_status()["studio"])
    print("Scenes:", len(get_intro_scenes()))
    eps = get_episodes_list()
    print("Episodes:", len(eps))
    ep01 = get_ep01_detail()
    print("EP01:", ep01["metadata"]["title"])

