"""*Bankr* module for data presentation on TUI."""

import i18n
import sys

import pandas as pd
from prettytable import PrettyTable

from bankr.money import Money


def show_iban_stats(page: pd.DataFrame, iban: str) -> Money:
    """Statistics of an IBAN.

    It provides the number of Transactions, the first and last Transaction date,
    and the IBAN balance.
    """
    try:
        first_transaction = page[page.iban == iban].date.min().strftime("%d.%m.%Y")
    except:  # noqa: E722
        first_transaction = f"{i18n.t('general.none'):>10}"
    try:
        last_transaction = page[page.iban == iban].date.max().strftime("%d.%m.%Y")
    except:  # noqa: E722
        last_transaction = f"{i18n.t('general.none'):>10}"
    try:
        value = Money.m(page[page.iban == iban].cents.sum() / 100.0)
    except:  # noqa: E722
        value = Money.m(0.0)

    # Print IBAN statistics
    print(f"    {i18n.t('general.no_tracts'):<30}{len(page[page.iban == iban]):>10}")
    print(f"    {i18n.t('general.first_transaction'):<30}{first_transaction}")
    print(f"    {i18n.t('general.last_transaction'):<30}{last_transaction}")
    print(f"    {i18n.t('general.fin_bal'):<30}{value}\n")

    return value


def show_book_stats(extended_accounts: pd.DataFrame) -> None:
    """Show the account statistics of the Book

    tbc
    """
    sum_tracts: int = 0
    sum_balance = Money.m(0, "€")
    iban: str = i18n.t("general.iban")
    tract: str = i18n.t("general.tract")
    balance: str = i18n.t("general.balance")
    first_tract: str = i18n.t("general.first_tract")
    last_tract: str = i18n.t("general.last_tract")
    account_desc: str = i18n.t("general.account_desc")

    stats: str = PrettyTable(field_names=[iban, tract, balance, first_tract, last_tract, account_desc])
    stats.align = "l"
    stats.align[tract] = "r"
    stats.align[balance] = "r"

    for account in extended_accounts:
        sum_tracts = sum_tracts + account["tracts"]
        sum_balance = sum_balance + account["balance"]
        stats.add_row(
            [
                account["iban"],
                account["tracts"],
                account["balance"],
                account["first_tract"],
                account["last_tract"],
                account["desc"][:40],
            ]
        )
    print(f"{i18n.t('general.total_amount')}: {sum_balance}  ({sum_tracts} {i18n.t('general.transactions')})\n")
    print(stats, "\n")


def show_page_header(tracts: int, cents: int, **kwargs) -> None:
    """_Show header of Page Mode_

    `params` are shown only if filtered.

    Args:
        tracts (int): _Number of Transactions_
        cents (int): _Sum of Transactions in Cents_
    """

    # Update default (unfiltered) parameters
    params = {"bounds": [], "cat": "", "iban": ""}
    params |= kwargs

    # Print Page Header
    print(f"{i18n.t('general.transactions'):<15} {tracts}")
    print(f"{i18n.t('general.total'):<15} {Money.m(cents / 100, '€')}")
    bounds = params["bounds"]
    if len(bounds) > 0:
        print(f"{i18n.t('general.date'):<15} {bounds[0].strftime('%d.%m.%Y')} - {bounds[1].strftime('%d.%m.%Y')}")
    if params["cat"]:
        print(f"{i18n.t('general.cat'):<15} {i18n.t('cats.' + params['cat'])}")
    if params["iban"]:
        print(f"{i18n.t('general.iban'):<15} {params['iban']}")


def show_page(page: pd.DataFrame) -> int:
    """Show a table of Transactions or a Page of the Book.

    The arguments `year` and `month` limit the selected Transactions (`0` is unlimited).
    The selection can also be limited to a category or an IBAN (`""` is unlimited).
    The number of Transactions must not exceed 200.
    """

    # Headline of Transaction table
    pnum = "#"
    pdate = i18n.t("general.date")
    pamount = i18n.t("general.amount")
    pcat = i18n.t("general.cat")
    poffset = i18n.t("general.offset")
    pname = i18n.t("general.name")
    field_names = [pnum, pdate, pamount, pcat, poffset, pname]
    if False:
        pprocess = i18n.t("general.process")
        field_names.extend([pprocess])
    else:
        piban = i18n.t("general.iban")
        field_names[2:2] = [piban]
    ppage: str = PrettyTable(field_names=field_names)
    ppage.align = "l"
    ppage.align[pnum] = "r"

    # Transactions table
    for n in range(0, page.shape[0]):
        pnum = n + 1
        pdate = page["date"].iloc[n].strftime("%d.%m.%Y")
        pamount = f"{Money.m(page['cents'].iloc[n] / 100, page['curr'].iloc[n])}"
        pcat = f"{i18n.t('cats.' + page['cat'].iloc[n])}"
        poffset = page["offset"].iloc[n]
        pname = str(page["name"].iloc[n])[:20]
        field_names = [pnum, pdate, pamount, pcat, poffset, pname]
        if False:
            pprocess = str(page["process"].iloc[n])[:20]
            field_names.extend([pprocess])
        else:
            piban = page["iban"].iloc[n]
            field_names[2:2] = [piban]
        ppage.add_row(field_names)
    print(ppage)

    # Transaction details
    while True:
        try:
            selection = input(f"{i18n.t('general.tractdetails')} ")
            if selection == "q":
                return -1  # Quit
            selint = int(selection)
            if selint < 1 or selint > page.shape[0]:
                raise ValueError
            break
        except ValueError:
            continue
    return selint - 1


def show_income_per_interval(amounts: pd.DataFrame) -> None:
    """Create a Pretty Table of an "amounts table".

    See the documentation for an explanation of an "amounts table".
    """
    # Header
    cols = list(amounts)
    cols.remove("internal")
    amounts = amounts.drop(labels="internal", axis=1)
    pnames = [i18n.t("general.perd")]
    for col in cols:
        pnames.append(i18n.t("cats." + col)[:3])
    ptable: str = PrettyTable(field_names=pnames)
    ptable.align = "r"

    # Rows
    index = list(amounts.index)
    index[-1] = i18n.t("general.total")
    for row in range(amounts.shape[0]):
        ptable.add_row([index[row]] + [round(value) for value in amounts.iloc[row, :].to_list()])
    print(ptable)  # TODO Add legend


def show_transaction(book: pd.DataFrame, uuid: str, details: bool) -> None:
    """Show a Transaction, given by its UUID, in tabular form.

    The data source is the Book, a Page or a comparable data frame.
    """
    try:
        # Hint: This works only, if
        # (1) the uuid is the index of the book, and
        # (2) the uuid is of dtype string or category, not object.
        tract = book.loc[uuid]
    except KeyError:
        sys.exit(f"Bankr Error - Transaction {uuid} not found.")
    print("-" * 120)
    print(f"{i18n.t('general.uuid'):<20}{uuid}")
    print("-" * 120)
    print(f"{i18n.t('general.date'):<20}{tract['date'].strftime('%d.%m.%Y')}")
    print(f"{i18n.t('general.iban'):<20}{tract['iban']}")
    print(f"{i18n.t('general.amount'):<20}{Money.m(tract['cents'] / 100, tract['curr'])}")
    print(f"{i18n.t('general.cat'):<20}{i18n.t('cats.' + tract['cat'])}")
    if pd.notna(tract["valuta"]):
        print(f"{i18n.t('general.valuta'):<20}{tract['valuta'].strftime('%d.%m.%Y')}")
    if details:
        print(f"{i18n.t('general.offset'):<20}{tract['offset']}")
    print(f"{i18n.t('general.name'):<20}{tract['name']}")
    print(f"{i18n.t('general.process'):<20}{tract['process']}")
    print(f"{i18n.t('general.desc'):<20}{tract['desc'][:100]}")
    if details:
        print(f"{i18n.t('general.creditor'):<20}{tract['creditor']}")
        print(f"{i18n.t('general.mandate'):<20}{tract['mandate']}")
        print(f"{i18n.t('general.customer'):<20}{tract['customer']}")
        print(f"{i18n.t('general.source'):<20}{tract['source']}")
    print("-" * 120)
