import os
import zipfile
import logging
import shutil
import math
from pathlib import Path
from typing import List, Dict, Any
import config

logger = logging.getLogger(__name__)

def format_timestamp(seconds: float) -> str:
    """Convert seconds to SRT timestamp format (HH:MM:SS,mmm)"""
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    secs = int(seconds % 60)
    millis = int((seconds - int(seconds)) * 1000)
    return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"

def generate_srt(script_data: Dict[str, Any], video_map: Dict[int, str]) -> str:
    """Generate SRT content from script data"""
    scenes = script_data.get("scenes", [])
    srt_content = ""
    current_time = 0.0
    
    # Need to get durations from actual videos if possible, else estimate
    from modules import ffmpeg_utils
    
    for i, scene in enumerate(scenes):
        scene_id = scene["id"]
        # Get duration
        duration = 5.0
        if scene_id in video_map and os.path.exists(video_map[scene_id]):
            try:
                info = ffmpeg_utils.get_video_info(video_map[scene_id])
                duration = info.get("duration", 5.0)
            except:
                pass
        
        start_time = current_time
        end_time = current_time + duration
        current_time = end_time
        
        text = scene.get("subtitle", "")
        if text:
            srt_content += f"{i+1}\n"
            srt_content += f"{format_timestamp(start_time)} --> {format_timestamp(end_time)}\n"
            srt_content += f"{text}\n\n"
            
    return srt_content

def create_capcut_package(project_id: str, script_data: Dict[str, Any], assets: Dict[str, str]) -> str:
    """
    Create a ZIP package for CapCut (JianYing) import
    Contains:
    - videos/ (scene videos)
    - audios/ (voiceover, bgm)
    - images/ (fancy text transparent pngs)
    - subtitles.srt
    """
    package_dir = config.TEMP_DIR / f"capcut_pkg_{project_id}_{int(os.getpid())}"
    if package_dir.exists():
        shutil.rmtree(package_dir)
    package_dir.mkdir()
    
    (package_dir / "videos").mkdir()
    (package_dir / "audios").mkdir()
    (package_dir / "images").mkdir()
    
    # 1. Generate SRT
    # Need to reconstruct video map from assets or script
    # Assuming 'assets' contains 'scene_videos' map
    scene_videos = assets.get("scene_videos", {})
    srt_content = generate_srt(script_data, scene_videos)
    with open(package_dir / "subtitles.srt", "w", encoding="utf-8") as f:
        f.write(srt_content)
        
    # 2. Copy Videos
    scenes = script_data.get("scenes", [])
    for i, scene in enumerate(scenes):
        sid = scene["id"]
        if sid in scene_videos and os.path.exists(scene_videos[sid]):
            # Rename with sequence number for easy sorting: 01_scene.mp4
            ext = Path(scene_videos[sid]).suffix
            dest_name = f"{i+1:02d}_scene_{sid}{ext}"
            shutil.copy(scene_videos[sid], package_dir / "videos" / dest_name)
            
    # 3. Copy Audio (Voiceover)
    # We might not have the separate voiceover file easily accessible if it was mixed on the fly.
    # But usually we generate it to temp.
    # Option: Re-generate voiceover audio for the whole track or segments?
    # Better: If we have 'voiceover_segments', generate them or copy if cached.
    # For now, let's try to find if we have a full voiceover file or just use segments.
    # Simplest: Re-generate the full voiceover audio file if it doesn't exist as a standalone asset.
    # Or check if user just wants the pieces.
    # Let's check if we have a mixed audio file. Usually we don't save the intermediate audio as an asset.
    # So we might need to re-generate the voiceover audio here.
    from modules import factory
    full_vo_text = " ".join([s.get("voiceover", "") for s in scenes if s.get("voiceover")])
    if full_vo_text:
        try:
            # Assuming default voice
            voice_type = config.VOLC_TTS_DEFAULT_VOICE
            vo_path = factory.generate_voiceover_volcengine(full_vo_text, voice_type)
            shutil.copy(vo_path, package_dir / "audios" / "full_voiceover.mp3")
        except Exception as e:
            logger.warning(f"Failed to generate export voiceover: {e}")
            
    # Copy BGM
    # Check settings or script for BGM? BGM is usually a global setting in Composer.
    # We'll just look for BGM in assets folder or let user drag their own.
    # Or if we saved the BGM selection in the project, we could copy it.
    # For now, skip specific BGM unless we know which one was used.
    
    # 4. Copy Fancy Text Images
    # We need to re-render them or find them. 
    # Since they are generated to temp in composer, they might be gone.
    # Safer to re-render them.
    from modules.text_renderer import renderer
    for i, scene in enumerate(scenes):
        ft = scene.get("fancy_text")
        if ft:
            text = ft.get("text", "") if isinstance(ft, dict) else ""
            style = ft.get("style", "highlight") if isinstance(ft, dict) else "highlight"
            if text:
                try:
                    # Render
                    if isinstance(style, str):
                         # Simple mapping or default
                         # We need the full style dict logic from composer ideally
                         # For export, we just use default render
                         pass
                    
                    # Actually, composer logic for style resolution is complex.
                    # Let's just use a simple render here.
                    img_path = renderer.render(text, {"font_size": 60, "font_color": "#FFFFFF"}, cache=False)
                    shutil.copy(img_path, package_dir / "images" / f"{i+1:02d}_text_{scene['id']}.png")
                except:
                    pass

    # 5. Zip it
    zip_path = config.TEMP_DIR / f"capcut_export_{project_id}.zip"
    with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
        for root, dirs, files in os.walk(package_dir):
            for file in files:
                file_path = os.path.join(root, file)
                arcname = os.path.relpath(file_path, package_dir)
                zipf.write(file_path, arcname)
                
    # Cleanup
    shutil.rmtree(package_dir)
    return str(zip_path)





