"""Extract form field data from PDFs using pymupdf widgets."""

import argparse
import os
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import fitz  # pymupdf

from output_utils import output_to_file_or_stdout


# Widget type names from pymupdf
WIDGET_TYPES = {
    0: "unknown",
    1: "button",
    2: "checkbox",
    3: "combobox",
    4: "listbox",
    5: "radiobutton",
    6: "signature",
    7: "text",
}


def extract(pdf_path: str) -> list[dict]:
    """Return list of form field dicts."""
    results = []
    with fitz.open(pdf_path) as doc:
        for i, page in enumerate(doc, start=1):
            for widget in page.widgets():
                entry = {
                    "page": i,
                    "field_name": widget.field_name,
                    "field_type": WIDGET_TYPES.get(widget.field_type, "unknown"),
                    "value": widget.field_value,
                }
                if widget.choice_values:
                    entry["choices"] = widget.choice_values
                results.append(entry)
    return results


def _forms_to_text(fields: list[dict]) -> list[dict]:
    """Convert form fields into page-text dicts for txt/md output."""
    page_texts: dict[int, list[str]] = {}
    for f in fields:
        line = f"{f['field_name']} ({f['field_type']}): {f['value'] or '(empty)'}"
        if "choices" in f:
            line += f"  choices={f['choices']}"
        page_texts.setdefault(f["page"], []).append(line)
    return [{"page": p, "text": "\n".join(texts)} for p, texts in sorted(page_texts.items())]


def _forms_to_csv(fields: list[dict]) -> list[list]:
    """Flatten form fields into CSV rows."""
    rows = [["page", "field_name", "field_type", "value"]]
    for f in fields:
        rows.append([f["page"], f["field_name"], f["field_type"], f["value"] or ""])
    return rows


def main():
    parser = argparse.ArgumentParser(description="Extract form fields from PDFs")
    parser.add_argument("pdf", help="Path to input PDF")
    parser.add_argument("output", nargs="?", default=None, help="Output file path")
    parser.add_argument("--format", choices=["json", "txt", "md", "csv"], default="json",
                        dest="fmt", help="Output format (default: json)")
    args = parser.parse_args()

    fields = extract(args.pdf)

    if args.fmt == "json":
        data = {"extractor": "forms", "fields": fields}
        output_to_file_or_stdout(data, "json", args.output)
    elif args.fmt == "csv":
        csv_rows = _forms_to_csv(fields)
        output_to_file_or_stdout(csv_rows, "csv", args.output)
    else:
        text_pages = _forms_to_text(fields)
        output_to_file_or_stdout(text_pages, args.fmt, args.output)


if __name__ == "__main__":
    main()
