"""Shared output formatting for all extractors."""

import csv
import io
import json
import sys


def write_txt(pages: list[dict], out=sys.stdout):
    """Write plain text output. Each dict must have 'page' and 'text' keys."""
    for p in pages:
        out.write(f"--- Page {p['page']} ---\n")
        out.write(p["text"].rstrip() + "\n\n")


def write_json(data, out=sys.stdout):
    """Write JSON output (any serializable data)."""
    json.dump(data, out, indent=2, ensure_ascii=False)
    out.write("\n")


def write_md(pages: list[dict], out=sys.stdout):
    """Write Markdown output. Each dict must have 'page' and 'text' keys."""
    for p in pages:
        out.write(f"## Page {p['page']}\n\n")
        out.write(p["text"].rstrip() + "\n\n")


def write_csv_rows(rows: list[list], out=sys.stdout):
    """Write CSV output from a list of rows (first row = header)."""
    writer = csv.writer(out)
    writer.writerows(rows)


def write_output(data, fmt: str, out=sys.stdout):
    """Dispatch to the correct writer based on format string.

    `data` interpretation depends on format:
      - txt/md: list of {"page": int, "text": str}
      - json: any serializable object
      - csv: list of lists (first row = header)
    """
    if fmt == "txt":
        write_txt(data, out)
    elif fmt == "json":
        write_json(data, out)
    elif fmt == "md":
        write_md(data, out)
    elif fmt == "csv":
        write_csv_rows(data, out)
    else:
        raise ValueError(f"Unsupported format: {fmt}")


def output_to_file_or_stdout(data, fmt: str, output_path: str | None):
    """Write output to a file path or stdout."""
    if output_path:
        with open(output_path, "w", encoding="utf-8") as f:
            write_output(data, fmt, f)
    else:
        write_output(data, fmt, sys.stdout)
