#!/usr/bin/env python3
"""
Inference CLI

Runs inference on new PDFs to extract invoice data.
"""

import argparse
import json
import logging
import sys
from pathlib import Path

from shared.config import DEFAULT_DPI
from shared.logging_config import setup_cli_logging

logger = logging.getLogger(__name__)


def main():
    parser = argparse.ArgumentParser(
        description='Extract invoice data from PDFs using trained model'
    )
    parser.add_argument(
        '--model', '-m',
        required=True,
        help='Path to trained YOLO model (.pt file)'
    )
    parser.add_argument(
        '--input', '-i',
        required=True,
        help='Input PDF file or directory'
    )
    parser.add_argument(
        '--output', '-o',
        help='Output JSON file (default: stdout)'
    )
    parser.add_argument(
        '--confidence',
        type=float,
        default=0.5,
        help='Detection confidence threshold (default: 0.5)'
    )
    parser.add_argument(
        '--dpi',
        type=int,
        default=DEFAULT_DPI,
        help=f'DPI for PDF rendering (default: {DEFAULT_DPI}, must match training)'
    )
    parser.add_argument(
        '--no-fallback',
        action='store_true',
        help='Disable fallback OCR'
    )
    parser.add_argument(
        '--lang',
        default='en',
        help='OCR language (default: en)'
    )
    parser.add_argument(
        '--gpu',
        action='store_true',
        help='Use GPU'
    )
    parser.add_argument(
        '--verbose', '-v',
        action='store_true',
        help='Verbose output'
    )

    args = parser.parse_args()

    # Configure logging for CLI
    setup_cli_logging()

    # Validate model
    model_path = Path(args.model)
    if not model_path.exists():
        logger.error("Model not found: %s", model_path)
        sys.exit(1)

    # Get input files
    input_path = Path(args.input)
    if input_path.is_file():
        pdf_files = [input_path]
    elif input_path.is_dir():
        pdf_files = list(input_path.glob('*.pdf'))
    else:
        logger.error("Input not found: %s", input_path)
        sys.exit(1)

    if not pdf_files:
        logger.error("No PDF files found")
        sys.exit(1)

    if args.verbose:
        logger.info("Processing %d PDF file(s)", len(pdf_files))
        logger.info("Model: %s", model_path)

    from backend.pipeline import InferencePipeline

    # Initialize pipeline
    pipeline = InferencePipeline(
        model_path=model_path,
        confidence_threshold=args.confidence,
        ocr_lang=args.lang,
        use_gpu=args.gpu,
        dpi=args.dpi,
        enable_fallback=not args.no_fallback
    )

    # Process files
    results = []

    for pdf_path in pdf_files:
        if args.verbose:
            logger.info("Processing: %s", pdf_path.name)

        result = pipeline.process_pdf(pdf_path)
        results.append(result.to_json())

        if args.verbose:
            logger.info("  Success: %s", result.success)
            logger.info("  Fields: %d", len(result.fields))
            if result.fallback_used:
                logger.info("  Fallback used: Yes")
            if result.errors:
                logger.info("  Errors: %s", result.errors)

    # Output results
    if len(results) == 1:
        output = results[0]
    else:
        output = results

    json_output = json.dumps(output, indent=2, ensure_ascii=False)

    if args.output:
        with open(args.output, 'w', encoding='utf-8') as f:
            f.write(json_output)
        if args.verbose:
            logger.info("Results written to: %s", args.output)
    else:
        # Output JSON to stdout (not logged)
        sys.stdout.write(json_output)
        sys.stdout.write('\n')


if __name__ == '__main__':
    main()
