"""CLI for cfs2mat."""

import argparse
import glob
import json
import os
import sys

import biosig


def cmd_convert(args):
    """Convert .cfs files to .mat format."""
    from .converter import cfs_to_mat

    files = []
    for pattern in args.input:
        matched = glob.glob(pattern, recursive=True)
        if matched:
            files.extend(matched)
        elif os.path.exists(pattern):
            files.append(pattern)
        else:
            print(f"Warning: no match for '{pattern}'", file=sys.stderr)

    if not files:
        print("Error: no .cfs files found.", file=sys.stderr)
        return 1

    output_dir = args.output_dir
    if output_dir:
        os.makedirs(output_dir, exist_ok=True)

    for cfs_path in files:
        if output_dir:
            basename = os.path.splitext(os.path.basename(cfs_path))[0] + ".mat"
            mat_path = os.path.join(output_dir, basename)
        else:
            mat_path = None  # same directory as input

        mat_path = cfs_to_mat(cfs_path, mat_path=mat_path, flat=args.flat)

        if not args.quiet:
            hdr = json.loads(biosig.header(cfs_path))
            data = biosig.data(cfs_path)
            n_sweeps = hdr.get("NumberOfSweeps", 1)
            channels = [ch["Label"] for ch in hdr.get("CHANNEL", [])]
            samples_per_sweep = data.shape[0] // max(n_sweeps, 1)
            print(f"{cfs_path} -> {mat_path}")
            print(f"  Channels: {channels}")
            print(f"  Sweeps: {n_sweeps}, Samples/sweep: {samples_per_sweep}")
            print(f"  Sampling rate: {hdr.get('Samplingrate', 0):.2f} Hz")

    return 0


def cmd_info(args):
    """Print metadata from a .cfs file."""
    hdr = json.loads(biosig.header(args.input))
    data = biosig.data(args.input)

    if args.json:
        print(json.dumps(hdr, indent=2, default=str))
        return 0

    n_sweeps = hdr.get("NumberOfSweeps", 1)
    channels = hdr.get("CHANNEL", [])
    print(f"File:       {hdr.get('Filename', args.input)}")
    print(f"Type:       {hdr.get('TYPE', '?')} v{hdr.get('VERSION', '?')}")
    print(f"Recorded:   {hdr.get('StartOfRecording', '?')}")
    print(f"Rate:       {hdr.get('Samplingrate', 0):.2f} Hz")
    print(f"Sweeps:     {n_sweeps}")
    print(f"Samples:    {data.shape[0]} total ({data.shape[0] // max(n_sweeps, 1)}/sweep)")
    print(f"Channels:   {len(channels)}")
    for ch in channels:
        print(f"  [{ch.get('ChannelNumber', '?')}] {ch.get('Label', '?'):12s}  "
              f"unit={ch.get('PhysicalUnit', '?'):4s}  "
              f"rate={ch.get('Samplingrate', 0):.1f} Hz  "
              f"scale={ch.get('scaling', 1)}")
    events = hdr.get("EVENT", [])
    if events:
        print(f"Events:     {len(events)}")
        for e in events:
            print(f"  {e.get('TimeStamp', '?'):30s}  {e.get('Description', '')}")
    patient = hdr.get("Patient", {})
    if patient.get("Id") or patient.get("Gender"):
        print(f"Patient:    id={patient.get('Id', '')}  gender={patient.get('Gender', '')}")
    print(f"Manufacturer: {hdr.get('Manufacturer', {}).get('Name', '?')}")
    return 0


def main(argv=None):
    parser = argparse.ArgumentParser(
        prog="cfs2mat",
        description="Convert CED Signal .cfs files to MATLAB .mat format.",
    )
    parser.add_argument("--version", action="version", version=f"%(prog)s {_get_version()}")
    subparsers = parser.add_subparsers(dest="command")

    # convert subcommand
    p_convert = subparsers.add_parser("convert", help="Convert .cfs file(s) to .mat")
    p_convert.add_argument("input", nargs="+", help="Input .cfs file(s) or glob patterns")
    p_convert.add_argument("-o", "--output-dir", help="Output directory (default: same as input)")
    p_convert.add_argument("--flat", action="store_true", help="Store data flat (samples x channels), skip sweep reshape")
    p_convert.add_argument("-q", "--quiet", action="store_true", help="Suppress output")

    # info subcommand
    p_info = subparsers.add_parser("info", help="Print .cfs file metadata")
    p_info.add_argument("input", help="Input .cfs file")
    p_info.add_argument("--json", action="store_true", help="Output raw header as JSON")

    args = parser.parse_args(argv)

    if args.command is None:
        parser.print_help()
        return 1

    if args.command == "convert":
        return cmd_convert(args)
    elif args.command == "info":
        return cmd_info(args)


def _get_version():
    try:
        from . import __version__
        return __version__
    except ImportError:
        return "unknown"


if __name__ == "__main__":
    sys.exit(main())
