from .console import print, input, clear_console
from rich.table import Table
import sys
import traceback

def _total_characters(object):
    if isinstance(object, str): return len(object)
    if isinstance(object, list): return sum(len(segment) for segment, _ in object)
    return len(str(object))

def _choose_option(
    options,
    message = "Seleccione una opción:",
    selection_text = "Su elección: ",
    error = "La opción ingresada no es válida, intente nuevamente",
):
    print(f"{message}\n", bold = True)
    for key, option in options.items(): print([(f"{key}:", {"bold": True}), (f" {option}", {})])
    selection = input(f"\n{selection_text}", bold = True).upper()
    while selection not in options:
        print(f"\n{error}", color = "#ff0000")
        selection = input(f"\n{selection_text}", bold = True).upper()
    return selection

def header(
    title,
    title_color = "#ffffff",
    title_bold = True,
    title_italic = True,
    title_underline = False,
    title_strike = False,
    title_reverse = False,
    title_alignment = "center",
    title_padding = 0,
    title_top_padding = None,
    title_right_padding = None,
    title_bottom_padding = None,
    title_left_padding = None,
    separator_first_character = "\\",
    separator_separator_character = "-",
    separator_last_character = "/",
    separator_length = None,
    separator_color = "#ffffff",
    separator_aligment = "center",
    separator_padding = 0,
    separator_top_padding = None,
    separator_right_padding = None,
    separator_bottom_padding = 2,
    separator_left_padding = None
):
    clear_console()
    print(
        title,
        color = title_color,
        bold = title_bold,
        italic = title_italic,
        underline = title_underline,
        strike = title_strike,
        reverse = title_reverse,
        alignment = title_alignment,
        padding = title_padding,
        top_padding = title_top_padding,
        right_padding = title_right_padding,
        bottom_padding = title_bottom_padding,
        left_padding = title_left_padding
    )
    separator(
        first_character = separator_first_character,
        separator_character = separator_separator_character,
        last_character = separator_last_character,
        length = separator_length if separator_length else _total_characters(title) + 2,
        color = separator_color,
        aligment = separator_aligment,
        padding = separator_padding,
        top_padding = separator_top_padding,
        right_padding = separator_right_padding,
        bottom_padding = separator_bottom_padding,
        left_padding = separator_left_padding
    )

def menu(
    options,
    title,
    title_color = "#ffffff",
    title_bold = True,
    title_italic = True,
    title_underline = False,
    title_strike = False,
    title_reverse = False,
    title_alignment = "center",
    title_padding = 0,
    title_top_padding = None,
    title_right_padding = None,
    title_bottom_padding = None,
    title_left_padding = None,
    separator_first_character = "\\",
    separator_separator_character = "-",
    separator_last_character = "/",
    separator_length = None,
    separator_color = "#ffffff",
    separator_aligment = "center",
    separator_padding = 0,
    separator_top_padding = None,
    separator_right_padding = None,
    separator_bottom_padding = 2,
    separator_left_padding = None,
    message = "Seleccione una opción:",
    selection_text = "Su elección: ",
    error = "La opción ingresada no es válida, intente nuevamente"
):
    header(
        title = title,
        title_color = title_color,
        title_bold = title_bold,
        title_italic = title_italic,
        title_underline = title_underline,
        title_strike = title_strike,
        title_reverse = title_reverse,
        title_alignment = title_alignment,
        title_padding = title_padding,
        title_top_padding = title_top_padding,
        title_right_padding = title_right_padding,
        title_bottom_padding = title_bottom_padding,
        title_left_padding = title_left_padding,
        separator_first_character = separator_first_character,
        separator_separator_character = separator_separator_character,
        separator_last_character = separator_last_character,
        separator_length = separator_length,
        separator_color = separator_color,
        separator_aligment = separator_aligment,
        separator_padding = separator_padding,
        separator_top_padding = separator_top_padding,
        separator_right_padding = separator_right_padding,
        separator_bottom_padding = separator_bottom_padding,
        separator_left_padding = separator_left_padding
    )
    options_dictionary = {}
    key = 1
    for option in options:
        match option:
            case "Atrás": options_dictionary["A"] = option
            case "Salir": options_dictionary["S"] = option
            case _:
                options_dictionary[str(key)] = option
                key += 1
    return _choose_option(options_dictionary, message, selection_text, error)

def table(
    columns,
    rows,
    title = None,
    title_style = "bold italic #ffffff",
    title_justify = "center",
    caption = None,
    caption_style = None,
    caption_justify = "center",
    width = None,
    min_width = None,
    box = None,
    safe_box = None,
    padding_table = (0, 1),
    collapse_padding = False,
    pad_edge = True,
    expand = False,
    show_header = True,
    show_footer = False,
    show_edge = True,
    show_lines = True,
    leading = 0,
    style = "none",
    header_style = "bold #ffffff",
    footer_style = "footer",
    border_style = "#ffffff",
    row_styles = None,
    highlight = False,
    alignment = "center",
    padding = None,
    top_padding = None,
    right_padding = None,
    bottom_padding = 1,
    left_padding = None
):
    table_instance = Table(
        title = title,
        title_style = title_style,
        title_justify = title_justify,
        caption = caption,
        caption_style = caption_style,
        caption_justify = caption_justify,
        width = width,
        min_width = min_width,
        box = box,
        safe_box = safe_box,
        padding = padding_table,
        collapse_padding = collapse_padding,
        pad_edge = pad_edge,
        expand = expand,
        show_header = show_header,
        show_footer = show_footer,
        show_edge = show_edge,
        show_lines = show_lines,
        leading = leading,
        style = style,
        header_style = header_style,
        footer_style = footer_style,
        border_style = border_style,
        row_styles = row_styles,
        highlight = highlight
    )
    for column in columns:
        if isinstance(column, str): table_instance.add_column(column)
        elif isinstance(column, dict): table_instance.add_column(**column)
        elif isinstance(column, tuple): table_instance.add_column(*column)
    for row in rows: table_instance.add_row(*row)
    print(
        table_instance,
        alignment = alignment,
        padding = padding,
        top_padding = top_padding,
        right_padding = right_padding,
        bottom_padding = bottom_padding,
        left_padding = left_padding
    )

def confirm_exit(
    message = "¿Está seguro de querer salir?",
    selection_text = "Su elección: ",
    error = "La opción ingresada no es válida, intente nuevamente",
    options_text = ["Sí", "No"]
):
    options = {
        "1": options_text[0],
        "2": options_text[1]
    }
    selection = _choose_option(options, f"\n{message}", selection_text, error)
    if selection == "1": sys.exit()

def separator(
    first_character = "/",
    separator_character = "-",
    last_character = "/",
    length = 100,
    color = "#ffffff",
    aligment = "left",
    padding = 0,
    top_padding = None,
    right_padding = None,
    bottom_padding = None,
    left_padding = None
):
    print(
        first_character + separator_character * (length - 2) + last_character,
        color = color,
        bold = True,
        alignment = aligment,
        padding = padding,
        top_padding = top_padding,
        right_padding = right_padding,
        bottom_padding = bottom_padding,
        left_padding = left_padding
    )

def error_message(
    message,
    error,
    separator_first_character = "/",
    separator_separator_character = "-",
    separator_last_character = "/",
    separator_length = 100,
    separator_color = "#ffffff",
    separator_aligment = "left",
    separator_padding = 0,
    separator_top_padding = None,
    separator_right_padding = None,
    separator_bottom_padding = None,
    separator_left_padding = None
):
    print(f"{message}\n", color = "#ff0000", bold = True)
    separator(
        first_character = separator_first_character,
        separator_character = separator_separator_character,
        last_character = separator_last_character,
        length = separator_length,
        color = separator_color,
        aligment = separator_aligment,
        padding = separator_padding,
        top_padding = separator_top_padding,
        right_padding = separator_right_padding,
        bottom_padding = separator_bottom_padding,
        left_padding = separator_left_padding
    )
    print(f"Error: {error}", bold = True)
    separator(
        first_character = separator_first_character,
        separator_character = separator_separator_character,
        last_character = separator_last_character,
        length = separator_length,
        color = separator_color,
        aligment = separator_aligment,
        padding = separator_padding,
        top_padding = separator_top_padding,
        right_padding = separator_right_padding,
        bottom_padding = separator_bottom_padding,
        left_padding = separator_left_padding
    )
    print("Detalles:\n", bold = True)
    print(traceback.format_exc(), color = "#00bfff")
    separator(
        first_character = separator_first_character,
        separator_character = separator_separator_character,
        last_character = separator_last_character,
        length = separator_length,
        color = separator_color,
        aligment = separator_aligment,
        padding = separator_padding,
        top_padding = separator_top_padding,
        right_padding = separator_right_padding,
        bottom_padding = separator_bottom_padding,
        left_padding = separator_left_padding
    )