import json
from pygeai.cli.commands import Command, Option, ArgumentsEnum
from pygeai.cli.commands.builders import build_help_text
from pygeai.cli.commands.common import get_boolean_value
from pygeai.cli.texts.help import OMNI_HELP_TEXT
from pygeai.core.common.exceptions import MissingRequirementException, WrongArgumentError
from pygeai.core.omni.clients import OmniParserClient
from pygeai.core.utils.console import Console


def show_help():
    """
    Displays help text in stdout
    """
    help_text = build_help_text(omni_commands, OMNI_HELP_TEXT)
    Console.write_stdout(help_text)


def parse_file(option_list: list):
    start_page = None
    end_page = None
    hi_res_mode = None
    dialogue = None
    cache = None

    for option_flag, option_arg in option_list:
        if option_flag.name == "start_page":
            try:
                start_page = int(option_arg)
            except (ValueError, TypeError):
                raise WrongArgumentError("start_page must be an integer")
        elif option_flag.name == "end_page":
            try:
                end_page = int(option_arg)
            except (ValueError, TypeError):
                raise WrongArgumentError("end_page must be an integer")
        elif option_flag.name == "hi_res_mode":
            hi_res_mode = get_boolean_value(option_arg)
        elif option_flag.name == "dialogue":
            dialogue = get_boolean_value(option_arg)
        elif option_flag.name == "cache":
            cache = get_boolean_value(option_arg)

    opts = {opt.name: arg for opt, arg in option_list}
    file_path = opts.get('input')
    structure = opts.get('structure')
    output_format = opts.get('output_format')
    password = opts.get('password')

    if not file_path:
        raise MissingRequirementException("Cannot process file without specifying --input parameter")

    client = OmniParserClient()
    result = client.process_file(
        file_path=file_path,
        start_page=start_page,
        end_page=end_page,
        hi_res_mode=hi_res_mode,
        structure=structure,
        dialogue=dialogue,
        output_format=output_format,
        password=password,
        cache=cache if cache is not None else False
    )

    output = {
        "status": result.get("status"),
        "request_id": result.get("requestId"),
        "parts_count": len(result.get("parts", [])),
        "usage": result.get("usage"),
        "parts": []
    }

    for part in result.get("parts", []):
        part_info = {
            "type": part.get("type"),
            "text_length": len(part.get("text", ""))
        }
        if part.get("page") is not None:
            part_info["page"] = part.get("page")
        if part.get("midTime") is not None:
            part_info["mid_time"] = part.get("midTime")

        part_info["text_preview"] = part.get("text", "")[:200] + ("..." if len(part.get("text", "")) > 200 else "")
        output["parts"].append(part_info)

    Console.write_stdout(json.dumps(output, indent=2))


parse_file_options = [
    Option(
        "input",
        ["--input", "-i"],
        "File path to process (required)",
        True
    ),
    Option(
        "start_page",
        ["--start-page", "--sp"],
        "integer: Start page number for processing (1-based, optional)",
        True
    ),
    Option(
        "end_page",
        ["--end-page", "--ep"],
        "integer: End page number for processing (inclusive, use 0 for until end, optional)",
        True
    ),
    Option(
        "hi_res_mode",
        ["--hi-res", "--hr"],
        "Enable high-resolution OCR/vision mode for complex scans (1/0, optional)",
        True
    ),
    Option(
        "structure",
        ["--structure", "--st"],
        "string: Structure format like 'table' for spreadsheet/CSV sources (optional)",
        True
    ),
    Option(
        "dialogue",
        ["--dialogue", "--dl"],
        "For audio/video: enable dialogue transcription mode (1/0, optional)",
        True
    ),
    Option(
        "output_format",
        ["--output-format", "--of"],
        "string: Output format - plainText (default), markdown, or html (optional)",
        True
    ),
    Option(
        "password",
        ["--password", "--pwd"],
        "string: Password for password-protected files (optional)",
        True
    ),
    Option(
        "cache",
        ["--cache"],
        "Enable X-Saia-Cache-Enabled to cache processing results. 1 to enable, 0 to disable (default: 0)",
        True
    ),
]


omni_commands = [
    Command(
        "help",
        ["help", "h"],
        "Display help text",
        show_help,
        ArgumentsEnum.NOT_AVAILABLE,
        [],
        []
    ),
    Command(
        "parse",
        ["parse", "p"],
        "Process file with omni-parser",
        parse_file,
        ArgumentsEnum.REQUIRED,
        [],
        parse_file_options
    ),
]
