#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script to audit prompts, assets, acting directives, and start frames
for KieuStory project survey (R3, R4, R5).
"""
import os
import sys
import json
import glob
from pathlib import Path

if sys.platform == "win32":
    try:
        sys.stdout.reconfigure(encoding="utf-8")
        sys.stderr.reconfigure(encoding="utf-8")
    except Exception:
        pass

BASE_DIR = Path("c:/Projects/KieuStory")
MUSE_PROMPTS_FILE = BASE_DIR / "02_AI_Prompts" / "muse_ai_video_prompts.json"
BANANA_PROMPTS_FILE = BASE_DIR / "02_AI_Prompts" / "gemini_banana_prompts.json"
CHAR_BIBLE_FILE = BASE_DIR / "00_Project_Bible" / "CHARACTER_BIBLE.md"
ENV_BIBLE_FILE = BASE_DIR / "00_Project_Bible" / "ENVIRONMENT_BIBLE.md"

def audit_all():
    muse_data = json.load(open(MUSE_PROMPTS_FILE, encoding="utf-8"))
    banana_data = json.load(open(BANANA_PROMPTS_FILE, encoding="utf-8"))
    
    print("=== 1. START FRAMES AUDIT (R3) ===")
    ep01_shots = {k: v for k, v in muse_data["motion_prompts"].items() if k.startswith("ep01_scene")}
    print(f"Total EP01 motion prompts: {len(ep01_shots)}")
    
    start_frame_issues = []
    for shot_id, shot in ep01_shots.items():
        mode = shot.get("mode")
        char_ref = shot.get("character_asset_ref")
        ref_sf = shot.get("reference_start_frame")
        prompt = shot.get("motion_prompt", "")
        
        # Check if shot uses static solo character portrait as start frame
        uses_static_solo = False
        if char_ref and "04_Assets/characters" in char_ref:
            uses_static_solo = True
            
        start_frame_issues.append({
            "shot_id": shot_id,
            "scene_title": shot.get("scene_title"),
            "mode": mode,
            "char_ref": char_ref,
            "ref_sf": ref_sf,
            "uses_static_solo": uses_static_solo
        })
    
    print(f"Shots directly referencing static solo character portraits: {sum(1 for s in start_frame_issues if s['uses_static_solo'])}")
    for s in start_frame_issues:
        if s["uses_static_solo"]:
            print(f"  {s['shot_id']}: {s['char_ref']} -> {s['scene_title']}")

    print("\n=== 2. MALE TEARS & ACTING DIRECTIVES AUDIT (R4) ===")
    male_names = ["kim trọng", "kim trong", "vương quan", "vuong quan", "vương ông", "vuong ong", 
                  "từ hải", "tu hai", "thúc sinh", "thuc sinh", "mã giám sinh", "ma giam sinh", 
                  "sở khanh", "so khanh", "hồ tôn hiến", "ho ton hien", "thúc ông", "thuc ong"]
    tear_words = ["khóc", "lệ", "nước mắt", "weep", "tear", "crying", "rưng rưng", "nức nở", "ngấn lệ", "nghẹn ngào"]
    
    male_tear_incidents = []
    for shot_id, shot in muse_data["motion_prompts"].items():
        full_text = (shot.get("motion_prompt", "") + " " + shot.get("audio_prompt", "") + " " + shot.get("scene_title", "")).lower()
        has_male = any(m in full_text for m in male_names)
        has_tear = any(t in full_text for t in tear_words)
        if has_male and has_tear:
            male_tear_incidents.append((shot_id, shot.get("scene_title"), [t for t in tear_words if t in full_text]))
            
    print(f"Muse prompts with male character + tear/crying keywords: {len(male_tear_incidents)}")
    for m in male_tear_incidents:
        print(f"  {m[0]}: {m[1]} -> matched {m[2]}")

    print("\n=== 3. DIALOGUE & OFF-SCREEN LIP-SYNC AUDIT (R5) ===")
    dialogue_shots = []
    for shot_id, shot in muse_data["motion_prompts"].items():
        m_prompt = shot.get("motion_prompt", "")
        a_prompt = shot.get("audio_prompt", "")
        full = m_prompt + " " + a_prompt
        is_vo = "v.o" in full.lower() or "voice-over" in full.lower() or "vọng" in full.lower() or "từ xa" in full.lower()
        has_quote = ("'" in full or '"' in full or "thì thầm:" in full.lower() or "nói:" in full.lower() or "ngâm:" in full.lower())
        has_closed_lip_guard = ("khép môi" in full.lower() or "không mấp máy" in full.lower() or "closed lip" in full.lower() or "không nói" in full.lower() or "lips remain closed" in full.lower())
        
        if is_vo or has_quote:
            dialogue_shots.append({
                "shot_id": shot_id,
                "title": shot.get("scene_title"),
                "is_vo": is_vo,
                "has_quote": has_quote,
                "has_closed_lip_guard": has_closed_lip_guard,
                "motion_prompt_snippet": m_prompt[:120]
            })
            
    print(f"Total dialogue / VO shots detected: {len(dialogue_shots)}")
    unguarded = [d for d in dialogue_shots if not d["has_closed_lip_guard"]]
    print(f"Dialogue / VO shots WITHOUT lip-sync / closed-lip guard: {len(unguarded)} (out of {len(dialogue_shots)})")
    for u in unguarded[:15]:
        print(f"  {u['shot_id']} [VO={u['is_vo']}]: {u['title']}")

    # Save detailed JSON output for report generation
    out_data = {
        "start_frame_issues": start_frame_issues,
        "male_tear_incidents": male_tear_incidents,
        "dialogue_shots": dialogue_shots
    }
    with open(BASE_DIR / ".agents/teamwork/spec_miner_survey_2/audit_results.json", "w", encoding="utf-8") as f:
        json.dump(out_data, f, ensure_ascii=False, indent=2)
    print("\nWrote full audit results to audit_results.json")

if __name__ == "__main__":
    audit_all()
