"""Command‑line interface and entry point."""

import os
import sys
import subprocess
import argparse

from .constants import DEFAULT_BAD_CHARS
from .tracklist import read_tracklist, parse_format
from .core import split_audio


def main():
    """Parse arguments and start the splitting process."""
    parser = argparse.ArgumentParser(
        description="Split an audio file into tracks using a tracklist.",
        epilog="Tracklist format: mm:ss track_name - author_name"
    )

    # Positional arguments.
    parser.add_argument('input_file', help='Input audio/video file')
    parser.add_argument('tracklist_file', help='Tracklist file')

    # Optional arguments.
    parser.add_argument(
        '--output-dir', '-o',
        help='Output directory for split tracks (default: <input_basename>_splits)'
    )
    parser.add_argument(
        '--format',
        help='Output container format (e.g., mp3, m4a, mkv, mp4, ogg, opus)'
    )
    parser.add_argument(
        '--transcode-to',
        help='Re-encode audio to this codec (e.g., libmp3lame, aac, libopus)'
    )
    parser.add_argument(
        '--drop-video',
        action='store_true',
        help='Remove video streams from output'
    )
    parser.add_argument(
        '--drop-subs',
        action='store_true',
        help='Remove subtitle streams from output'
    )
    parser.add_argument(
        '--number-tracks',
        action='store_true',
        help='Prepend track number to output filenames (convenience; use %%num in template for full control)'
    )
    parser.add_argument(
        '--replace-bad-chars',
        action='store_true',
        help='Replace problematic characters in filenames (default: off)'
    )
    parser.add_argument(
        '--replacement-char',
        default='_',
        help='Character used as replacement (default: "_")'
    )
    parser.add_argument(
        '--bad-chars',
        default=DEFAULT_BAD_CHARS,
        help='String of characters to replace (default includes space and single quote)'
    )
    parser.add_argument(
        '--skip-existing',
        action='store_true',
        help='Skip extraction if output file already exists (default: overwrite)'
    )
    parser.add_argument(
        '--tracklist-format',
        default='%ts %tn - %an',
        help='Format of each line in the tracklist using placeholders: '
             '%%ts (timestamp), %%tn (track name), %%an (author), %%al (album), '
             '%%date (date/year), %%ext (file extension). '
             'Default: "%%ts %%tn - %%an"'
    )
    parser.add_argument(
        '--output-template',
        default='%an-%tn.%ext',
        help='Template for output filenames using placeholders: '
             '%%tn (track name), %%an (author), %%al (album), '
             '%%date (date/year), %%ext (file extension), %%num (track number). '
             'Default: "%%an-%%tn.%%ext"'
    )
    parser.add_argument(
        '--dry-run',
        action='store_true',
        help='Parse and display the tracklist without splitting any files'
    )

    # Metadata options.
    parser.add_argument(
        '--album',
        help='Set album name in output metadata (overrides parsed %%al and original album)'
    )
    parser.add_argument(
        '--comment',
        help='Explicit comment text (overrides all other comment settings)'
    )
    parser.add_argument(
        '--no-comment',
        action='store_true',
        help='Explicitly ignore any comment (no comment written)'
    )
    parser.add_argument(
        '--comment-stream',
        type=int,
        default=None,
        help='Select comment from a specific stream index (0‑based). Default: first stream with a comment.'
    )
    parser.add_argument(
        '--merge-comments',
        action='store_true',
        help='Merge all comments from all streams into one (separated by --comment-separator)'
    )
    parser.add_argument(
        '--comment-separator',
        default='; ',
        help='Separator used when merging comments (default: "; ")'
    )

    # NEW: Delete original after successful split.
    parser.add_argument(
        '--delete-original',
        action='store_true',
        help='Delete the original input file after successful splitting (default: keep)'
    )

    args = parser.parse_args()

    # --------------------------------------------------------------------------
    # Input validation
    # --------------------------------------------------------------------------
    if not os.path.exists(args.input_file):
        print(f"Error: Input file not found: {args.input_file}")
        sys.exit(1)

    if not os.path.exists(args.tracklist_file):
        print(f"Error: Tracklist file not found: {args.tracklist_file}")
        sys.exit(1)

    # Ensure the replacement character is a single character.
    if len(args.replacement_char) != 1:
        print("Error: --replacement-char must be a single character.")
        sys.exit(1)

    # Check that FFmpeg is installed.
    try:
        subprocess.run(['ffmpeg', '-version'], capture_output=True, check=True)
    except (subprocess.CalledProcessError, FileNotFoundError):
        print("Error: FFmpeg not found. Please install FFmpeg first.")
        print("  - https://ffmpeg.org/download.html")
        sys.exit(1)

    # Parse the tracklist using the user‑provided format.
    try:
        tokens = parse_format(args.tracklist_format)
    except ValueError as error:
        print(f"Error in --tracklist-format: {error}")
        sys.exit(1)

    # Read and parse the tracklist file.
    tracks = read_tracklist(args.tracklist_file, tokens)
    if not tracks:
        print("Error: No valid tracks found in tracklist file.")
        sys.exit(1)

    print(f"Found {len(tracks)} tracks.")

    # Dry‑run mode: display parsed data and exit.
    if args.dry_run:
        print("\nParsed tracklist:")
        print("-" * 60)
        if tracks:
            fields = sorted(tracks[0].keys())
            header = " | ".join(f"{f:>10}" for f in fields)
            print(header)
            print("-" * len(header))
            for idx, track in enumerate(tracks, 1):
                values = [f"{track.get(f, ''):>10}" for f in fields]
                print(f"{idx:3d} | " + " | ".join(values))
        print("-" * 60)
        print("Dry‑run complete. No files were created.")
        sys.exit(0)

    # Determine the output directory.
    if args.output_dir:
        output_dir = args.output_dir
        print(f"Using custom output directory: {output_dir}")
    else:
        base_name = os.path.splitext(os.path.basename(args.input_file))[0]
        output_dir = base_name + "_splits"
        print(f"Using default output directory: {output_dir}")

    # Run the splitter.
    try:
        split_audio(args.input_file, output_dir, tracks, args)
    except (RuntimeError, ValueError) as error:
        print(f"Error: {error}")
        sys.exit(1)

    # --------------------------------------------------------------------------
    # Delete original file if requested and successful.
    # --------------------------------------------------------------------------
    if args.delete_original:
        try:
            os.remove(args.input_file)
            print(f"Deleted original file: {args.input_file}")
        except OSError as e:
            print(f"Warning: Could not delete original file: {e}")

    print("Done!")


if __name__ == "__main__":
    main()
