from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any

import cv2

from app.config import AppConfig
from app.label_parser import parse_label_text
from app.ocr import create_ocr_engine


def iter_images(path: Path) -> list[Path]:
    if path.is_file():
        return [path]

    extensions = {".jpg", ".jpeg", ".png", ".bmp", ".webp", ".tif", ".tiff"}
    return sorted(item for item in path.iterdir() if item.is_file() and item.suffix.lower() in extensions)


def result_to_dict(path: Path, result: Any, config: dict[str, Any]) -> dict[str, Any]:
    label_cfg = config.get("label_data", {})
    parsed = parse_label_text(
        result.text,
        label_cfg.get("colors", []),
        label_cfg.get("models", []),
        model_min_score=float(label_cfg.get("model_min_score", 0.72)),
        color_min_score=float(label_cfg.get("color_min_score", 0.72)),
    )
    return {
        "file": str(path),
        "engine": result.engine,
        "elapsed_ms": round(result.elapsed_ms, 2),
        "confidence": result.confidence,
        "error": result.error,
        "text": result.text,
        "lines": [
            {
                "text": line.text,
                "confidence": line.confidence,
                "bbox": line.bbox,
            }
            for line in result.lines
        ],
        "parsed": parsed.to_dict(),
    }


def main() -> int:
    parser = argparse.ArgumentParser(description="Test OCR backend on cropped label images.")
    parser.add_argument("path", help="Image file or directory with crop images")
    parser.add_argument("--config", default="app_config.json", help="Application config JSON path")
    parser.add_argument(
        "--engine",
        choices=["none", "tesseract", "paddle"],
        help="Override ocr.engine from config",
    )
    parser.add_argument("--no-threshold", action="store_true", help="Disable threshold preprocessing")
    parser.add_argument("--scale", type=float, help="Override OCR scale")
    parser.add_argument("--json", action="store_true", help="Print JSON output")
    args = parser.parse_args()

    app_config = AppConfig(Path(args.config))
    config = app_config.data
    if args.engine:
        config["ocr"]["engine"] = args.engine
        config["ocr"]["enabled"] = args.engine != "none"
    if args.no_threshold:
        config["ocr"]["threshold"] = False
    if args.scale is not None:
        config["ocr"]["scale"] = args.scale

    engine = create_ocr_engine(config)
    outputs = []
    for image_path in iter_images(Path(args.path)):
        image = cv2.imread(str(image_path), cv2.IMREAD_COLOR)
        if image is None:
            outputs.append({"file": str(image_path), "error": "Nie mozna odczytac obrazu"})
            continue

        h, w = image.shape[:2]
        result = engine.read_label(image, (0, 0, w, h))
        outputs.append(result_to_dict(image_path, result, config))

    if args.json:
        print(json.dumps(outputs, indent=2, ensure_ascii=False))
        return 0

    for output in outputs:
        print(f"file: {output['file']}")
        print(f"engine: {output.get('engine')}")
        print(f"elapsed_ms: {output.get('elapsed_ms')}")
        print(f"confidence: {output.get('confidence')}")
        if output.get("error"):
            print(f"error: {output['error']}")
        print("text:")
        print(output.get("text") or "")
        print(f"parsed: {output.get('parsed')}")
        print()
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
