"""
Command-line interface for digit counter.
"""

import argparse
import sys
import json
from typing import Optional, List, Any
from pathlib import Path

from .core import DigitCounter
from .types import DigitCountResult, CountingMode
from .utils import create_digit_counter
from .exceptions import DigitCounterError


def create_parser() -> argparse.ArgumentParser:
    """Create argument parser for CLI."""
    parser = argparse.ArgumentParser(
        description="Advanced Digit Counter CLI",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  digit-counter count 123.456
  digit-counter count 123.456 --mode before
  digit-counter batch values.txt --output results.json
  digit-counter batch data.csv --format csv --column value
""",
    )

    subparsers = parser.add_subparsers(dest="command", help="Command")

    count_parser = subparsers.add_parser("count", help="Count digits for a single value")
    count_parser.add_argument("value", help="Value to count digits for")
    count_parser.add_argument("--mode", choices=CountingMode.values(), default="total", help="Counting mode")
    count_parser.add_argument("--precision", type=int, default=15, help="Precision for decimal digits")
    count_parser.add_argument("--no-cache", action="store_true", help="Disable caching")
    count_parser.add_argument("--json", action="store_true", help="Output as JSON")

    batch_parser = subparsers.add_parser("batch", help="Process multiple values")
    batch_parser.add_argument("input", help="Input file")
    batch_parser.add_argument("--output", help="Output file (default: stdout)")
    batch_parser.add_argument("--mode", choices=CountingMode.values(), default="total", help="Counting mode")
    batch_parser.add_argument("--precision", type=int, default=15, help="Precision for decimal digits")
    batch_parser.add_argument("--format", choices=["text", "json", "csv"], default="text", help="Input format")
    batch_parser.add_argument("--column", help="Column name for CSV input")
    batch_parser.add_argument("--skip-errors", action="store_true", help="Skip values that cause errors")

    stats_parser = subparsers.add_parser("stats", help="Show statistics")
    stats_parser.add_argument("--reset", action="store_true", help="Reset statistics")

    return parser


def read_input_file(input_path: str, fmt: str, column: Optional[str] = None) -> List[Any]:
    """Read values from input file."""
    path = Path(input_path)
    if not path.exists():
        raise FileNotFoundError(f"Input file not found: {input_path}")

    values = []
    if fmt == "text":
        with open(input_path, "r", encoding="utf-8") as fh:
            for line in fh:
                line = line.strip()
                if line and not line.startswith("#"):
                    values.append(line)
    elif fmt == "csv":
        import csv
        with open(input_path, "r", encoding="utf-8") as fh:
            reader = csv.DictReader(fh)
            if column and column not in reader.fieldnames:
                raise ValueError(f"Column '{column}' not found in CSV")
            for row in reader:
                value = row[column] if column else next(iter(row.values()))
                if value:
                    values.append(value)
    elif fmt == "json":
        with open(input_path, "r", encoding="utf-8") as fh:
            data = json.load(fh)
            if isinstance(data, list):
                values = data
            elif isinstance(data, dict):
                values = list(data.values())
            else:
                raise ValueError("JSON must be an array or object")
    return values


def handle_count(args) -> None:
    """Handle count command."""
    counter = create_digit_counter(
        precision=args.precision, enable_cache=not args.no_cache, log_level="WARNING"
    )
    try:
        value = float(args.value) if "." in args.value else int(args.value)
    except Exception:
        value = args.value

    result = counter.count_digits(value, mode=args.mode, precision=args.precision)

    if args.json:
        if isinstance(result, DigitCountResult):
            output = result.to_dict()
        else:
            output = {"value": args.value, "result": result}
        print(json.dumps(output, indent=2))
    else:
        if isinstance(result, DigitCountResult):
            print(result.summary())
        else:
            print(f"Digits ({args.mode}): {result}")


def handle_batch(args) -> None:
    """Handle batch command."""
    values = read_input_file(args.input, args.format, args.column)
    if not values:
        print("No values found in input file", file=sys.stderr)
        sys.exit(1)
    counter = create_digit_counter(precision=args.precision, enable_cache=True, log_level="INFO")
    batch_result = counter.batch_process(
        values=values,
        mode=args.mode,
        precision=args.precision,
        return_dicts=True,
        skip_errors=args.skip_errors,
    )
    output_data = {
        "summary": batch_result.to_dict(),
        "results": [r.to_dict() if hasattr(r, "to_dict") else r for r in batch_result.results if r is not None],
        "errors": batch_result.errors,
    }
    out_text = json.dumps(output_data, indent=2) if args.format == "json" else str(output_data)
    if args.output:
        with open(args.output, "w", encoding="utf-8") as fh:
            fh.write(out_text)
        print(f"Results written to {args.output}")
    else:
        print(out_text)


def handle_stats(args) -> None:
    """Handle stats command."""
    counter = create_digit_counter(log_level="WARNING")
    if args.reset:
        counter.reset_statistics()
        print("Statistics reset")
    else:
        stats = counter.get_statistics()
        print(json.dumps(stats, indent=2))


def main() -> None:
    """CLI entry point."""
    parser = create_parser()
    args = parser.parse_args()
    try:
        if args.command == "count":
            handle_count(args)
        elif args.command == "batch":
            handle_batch(args)
        elif args.command == "stats":
            handle_stats(args)
        else:
            parser.print_help()
            sys.exit(1)
    except DigitCounterError as exc:
        print(f"Error: {exc}", file=sys.stderr)
        sys.exit(1)
    except Exception as exc:
        print(f"Unexpected error: {exc}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()
