#!/usr/bin/env python3
from beancount import loader
from beancount.query import query
from beancount.core.data import Transaction
from beancount.parser import printer
import argparse
from datetime import date, timedelta
from tabulate import tabulate
from collections import defaultdict


class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKCYAN = '\033[96m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'


def get_shared_expenses(entries, options, start_date, end_date):
    expenses_query = f"""SELECT date, account, value(position) FROM
date >= {start_date} AND
date < {end_date.isoformat()}
WHERE account ~ \"Expenses:Lloguer\" OR account ~ \"Expenses:FacturesUtilitats\""""
    rtypes, rrows = query.run_query(
        entries, options, expenses_query)
    expenses = []
    for row in rrows:
        if row.value_position.number > 0:
            expenses.append(row)
    return expenses


def get_paid_equities(entries, options, start_date, end_date):
    expenses_query = f"""SELECT date, account, value(position) FROM
date >= {start_date} AND
date < {end_date.isoformat()}
WHERE account ~ \"Equity:LloguerMiquel\" OR account ~ \"Equity:FacturesUtilitatsMiquel\""""
    rtypes, rrows = query.run_query(
        entries, options, expenses_query)
    return rrows


def find_matching_expense(expense, equities):
    for equity in equities:
        if equity.value_position == expense.value_position:
            return True
    return False


def find_missing_shared_expenses(expenses, equities):
    missing_shared_expenses = []
    for expense in expenses:
        if not find_matching_expense(expense, equities):
            missing_shared_expenses.append(expense)
    return missing_shared_expenses


def print_report(missing_shared_expenses, start_date):
    print("Missing shared expenses")
    print(f"From {start_date}")
    print(missing_shared_expenses)
    report = {
        "Date": [],
        "Account": [],
        "Amount": []
    }
    for expense in missing_shared_expenses:
        report["Date"].append(expense.date)
        report["Account"].append(expense.account)
        report["Amount"].append(expense.value_position)
    print(tabulate(report))


def main():
    parser = argparse.ArgumentParser(
        description='Find pending shared expenses (checks last 12 months)')
    args = parser.parse_args()

    # Calculate date range: 1 year ago to today
    end_date = date.today()
    start_date = end_date - timedelta(days=365)

    print(f"Checking period: {start_date.isoformat()} to {
          end_date.isoformat()}")

    filename = "ledger/main.beancount"
    entries, errors, options = loader.load_file(filename)

    if errors:
        printer.print_errors(errors)
        return

    expenses = get_shared_expenses(entries, options, start_date, end_date)
    equities = get_paid_equities(entries, options, start_date, end_date)

    missing_shared_expenses = find_missing_shared_expenses(expenses, equities)

    print_report(missing_shared_expenses, start_date)


if __name__ == "__main__":
    main()
