"""Core logic: orchestrates the splitting process."""

import os
import subprocess

from .constants import FORMAT_INFO
from .ffmpeg import get_audio_duration, get_stream_info, get_metadata, build_ffmpeg_command
from .formats import determine_output_format, validate_format_compatibility
from .timestamp import parse_track_timestamps, resolve_end_times
from .filename import build_filename
from .metadata import build_metadata_dict
from .utils import format_time


def split_audio(input_file, output_directory, tracks, args):
    """
    Main orchestration function: split the audio file into tracks.

    Args:
        input_file: Path to the input media file.
        output_directory: Directory where output files will be saved.
        tracks: List of dicts, each containing parsed fields.
        args: Parsed command‑line arguments (namespace).

    Raises:
        RuntimeError: If no audio stream is found.
        ValueError: If timestamp parsing or format compatibility fails.
    """
    # --------------------------------------------------------------------------
    # 1. Setup
    # --------------------------------------------------------------------------
    os.makedirs(output_directory, exist_ok=True)

    total_duration = get_audio_duration(input_file)
    stream_info = get_stream_info(input_file)

    print(f"Detected streams: audio={stream_info['has_audio']}, "
          f"video={stream_info['has_video']}, subs={stream_info['has_subtitle']}")
    print(f"Audio codec: {stream_info.get('audio_codec', 'unknown')}")

    if not stream_info['has_audio']:
        raise RuntimeError("No audio stream found in input file.")

    # --------------------------------------------------------------------------
    # 2. Format decision
    # --------------------------------------------------------------------------
    output_format = determine_output_format(stream_info, args.format, args.transcode_to)
    print(f"Output container: {output_format}")

    validate_format_compatibility(output_format, stream_info,
                                  args.drop_video, args.drop_subs)

    # Determine file extension.
    extension_info = FORMAT_INFO.get(output_format, {})
    extension = extension_info.get('ext', '.mkv')

    # --------------------------------------------------------------------------
    # 3. Parse timestamps
    # --------------------------------------------------------------------------
    track_times = parse_track_timestamps(tracks)
    resolved_times = resolve_end_times(track_times, total_duration)

    # --------------------------------------------------------------------------
    # 4. Fetch original metadata (for fallbacks)
    # --------------------------------------------------------------------------
    input_metadata = get_metadata(input_file)
    original_album = input_metadata.get('album')
    original_title = input_metadata.get('title')
    original_comments = input_metadata.get('comments', [])

    if original_album:
        print(f"Original album: '{original_album}'")
    if original_title:
        print(f"Original title: '{original_title}'")
    if original_comments:
        print(f"Found {len(original_comments)} comment(s) in input file.")
        for idx, comment in original_comments:
            print(f"  Stream {idx}: '{comment}'")

    # --------------------------------------------------------------------------
    # 5. Process each track
    # --------------------------------------------------------------------------
    for idx, track in enumerate(tracks, start=1):
        start_seconds, end_seconds = resolved_times[idx - 1]
        duration_seconds = end_seconds - start_seconds

        if duration_seconds <= 0:
            print(f"Warning: Track {idx} has zero or negative duration, skipping.")
            continue

        track_name = track.get('tn', 'Unknown')

        # ----------------------------------------------------------------------
        # 5a. Build filename
        # ----------------------------------------------------------------------
        clean_filename = build_filename(track, idx, extension, args)
        output_path = os.path.join(output_directory, clean_filename)

        # ----------------------------------------------------------------------
        # 5b. Handle existing files
        # ----------------------------------------------------------------------
        if args.skip_existing and os.path.exists(output_path):
            print(f"Skipping track {idx}: {output_path} already exists.")
            continue

        # ----------------------------------------------------------------------
        # 5c. Build metadata
        # ----------------------------------------------------------------------
        metadata = build_metadata_dict(track, idx, input_metadata, args)

        # ----------------------------------------------------------------------
        # 5d. Build and execute FFmpeg command
        # ----------------------------------------------------------------------
        cmd = build_ffmpeg_command(
            input_file, start_seconds, duration_seconds, output_path,
            stream_info, output_format, args.transcode_to,
            args.drop_video, args.drop_subs,
            metadata=metadata
        )

        print(f"Extracting track {idx}: {track_name} "
              f"({format_time(start_seconds)} - {format_time(end_seconds)})")

        result = subprocess.run(cmd, capture_output=True, text=True, check=False)

        if result.returncode != 0:
            print(f"ERROR extracting track {idx}:")
            print(result.stderr)
        else:
            print(f"  -> Saved to: {output_path}")
