# db.py
import sqlite3
import pprint

def connect_db(as_object):
    conn = sqlite3.connect('finance.db')
    if as_object:
        conn.row_factory = sqlite3.Row  # This allows us to access columns by name
    return conn

def init_db():
    conn = connect_db(True)
    cur = conn.cursor()
    cur.execute('''CREATE TABLE IF NOT EXISTS finance (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    D_Salary INTEGER,
                    D_Num_fortnights_pay INTEGER,
                    School_Fees INTEGER,
                    Car_loan_via_pay INTEGER,
                    Car_loan INTEGER,
                    Car_balloon INTEGER,
                    Car_buyout INTEGER,
                    Living_Expenses INTEGER,
                    Savings INTEGER,
                    Interest_Rate REAL,
                    Inflation REAL,
                    Mich_present INTEGER,
                    Overseas_trip INTEGER,
                    Mark_reno INTEGER,
                    D_leave_owed_in_days REAL,
                    D_TLS_shares INTEGER,
                    M_TLS_shares INTEGER,
                    D_CBA_shares INTEGER,
                    TLS_price REAL,
                    CBA_price REAL,
                    Overseas_trip_date STRING,
                    Mark_reno_date STRING,
                    Car_buyout_date STRING,
                    Sell_shares INTEGER,
                    compare_to INTEGER,
                    Ioniq6_future INTEGER
                    )''')
    
    cur.execute('''CREATE TABLE IF NOT EXISTS comparison_set (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    name STRING,
                    D_Salary INTEGER,
                    D_Num_fortnights_pay INTEGER,
                    School_Fees INTEGER,
                    Car_loan_via_pay INTEGER,
                    Car_loan INTEGER,
                    Car_balloon INTEGER,
                    Car_buyout INTEGER,
                    Living_Expenses INTEGER,
                    Savings INTEGER,
                    Interest_Rate REAL,
                    Inflation REAL,
                    Mich_present INTEGER,
                    Overseas_trip INTEGER,
                    Mark_reno INTEGER,
                    D_leave_owed_in_days REAL,
                    D_TLS_shares INTEGER,
                    M_TLS_shares INTEGER,
                    D_CBA_shares INTEGER,
                    TLS_price REAL,
                    CBA_price REAL,
                    Overseas_trip_date STRING,
                    Mark_reno_date STRING,
                    Car_buyout_date STRING,
                    Sell_shares INTEGER,
                    CBA INTEGER,
                    TLS INTEGER,
                    Ioniq6_future INTEGER
                    )''')

    cur.execute('''CREATE TABLE IF NOT EXISTS comparison_savings_data (
                    comparison_set_id INTEGER,
                    name STRING,
                    value INTEGER,
                    FOREIGN KEY(comparison_set_id) REFERENCES comparison_set(id)
                    )''')


    # Check if table is empty, if so insert default values
    cur.execute('SELECT COUNT(*) FROM finance')
    if cur.fetchone()[0] == 0:
        ###
        # For now manually update below on the fortnight of the original pay shcedule to compare saved version vs. our reality.  Update:
        #   Savings (Macq+me bank)
        #   TLS/CBA prices
        #   Interest rate
        #   D_leave_owed_in_days
        #   maybe quarterly update Inflation? (this is harder to appreciate, seems much lower officialy than Savings, but which inflation:
        #     I've decided to consider food only or overall, whichever is worse - using this: https://tradingeconomics.com/australia/food-inflation
        #     FOR NOW inf=3 THIS IS A MATERIAL ISSUE WITH PROJECTING OUT)
        ###
        cur.execute('''INSERT INTO finance (D_Salary, D_Num_fortnights_pay, School_Fees, Car_loan_via_pay, Car_loan, Car_balloon, Car_buyout, Living_Expenses, Savings, Interest_Rate,
                        Inflation, Mich_present, Overseas_trip, Mark_reno, D_leave_owed_in_days, D_TLS_shares, M_TLS_shares, D_CBA_shares, TLS_price, CBA_price, Overseas_trip_date, Mark_reno_date, Car_buyout_date, Sell_shares, compare_to, Ioniq6_future)
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', 
                    (4762.29, 10, 22000, 620, 2412, 45824.68, 83738.74, 84000, 421271.5, 5.0, 3.0, 10000, 30000, 10000, 94.66, 1000, 750, 1095, 3.9, 158.9, '2025-06-01', '2025-09-01', '2025-02-20', 5, 0, 0))
    # NOTE: 1017.99 car-lease (NEED TO VERIFY)
    # NOTE: o/s trip.  ~ $4kpp flights x3, then ~$3k / week in barcelona accom, $100pp/pd for food ($2k), + spending money (could be less)
    conn.commit()
    conn.close()

def get_finance_data():
    conn = connect_db(True)
    cur = conn.cursor()
    cur.execute('SELECT * FROM finance WHERE id = 1')  # Assuming a single record for simplicity
    finance = cur.fetchone()
    conn.close()
    return dict(finance)

def get_budget_data(finance_data):
    # annual bills - health ins (5k), rates (2.4), electricity (1.5), gas (2), internet (1.6), car insurance (.7), rego (.8), house insurance (2.4), GFC (2.2), phones (.5), melb. pollen (.03), nabu casa (.1), eweka (.1)  --- noting phone is elevated presuming I also go onto Aldi plan, but that there is no family discount
    bills = 19330
    BUDGET=[]
    BUDGET.append( ('Bills', f"${bills:,.2f}") )
    BUDGET.append( ('Buffer', f"${finance_data['CBA']*finance_data['CBA_price']+finance_data['TLS']*finance_data['TLS_price']:,.2f}") )
    BUDGET.append( ('Monthly budget', f"${((finance_data['Living_Expenses']) / 12):,.2f}" ) )
    BUDGET.append( ('Weekly budget', f"${((finance_data['Living_Expenses']) / 52):,.2f}" ) )
    BUDGET.append( ('Monthly budget (ex bills)', f"${((finance_data['Living_Expenses']-bills) / 12):,.2f}" ) )
    BUDGET.append( ('Weekly budget (ex bills)', f"${((finance_data['Living_Expenses']-bills) / 52):,.2f}" ) )
    return BUDGET

def update_finance(data):
    conn = connect_db(False)
    cur = conn.cursor()
    cur.execute('''UPDATE finance SET
                    D_Salary = ?,
                    D_Num_fortnights_pay = ?,
                    School_Fees = ?,
                    Car_loan_via_pay = ?,
                    Car_loan = ?,
                    Car_balloon = ?,
                    Car_buyout = ?,
                    Living_Expenses = ?,
                    Savings = ?,
                    Interest_Rate = ?,
                    Inflation = ?,
                    Mich_present = ?,
                    Overseas_trip = ?,
                    Mark_reno = ?,
                    D_leave_owed_in_days = ?,
                    D_TLS_shares = ?,
                    M_TLS_shares = ?,
                    D_CBA_shares = ?,
                    TLS_price = ?,
                    CBA_price = ?,
                    Overseas_trip_date = ?,
                    Mark_reno_date = ?,
                    Car_buyout_date = ?,
                    Sell_shares = ?,
                    compare_to = ?,
                    Ioniq6_future = ?
                    WHERE id = 1''', data)
    conn.commit()
    conn.close()


def insert_cset( data ):
    print( f"Saving: {data['vars']['name']}" )
    conn = connect_db(False)
    cur = conn.cursor()
    cur.execute('''INSERT INTO comparison_set (
                    name, D_Salary, D_Num_fortnights_pay, School_Fees, Car_loan_via_pay,
                    Car_loan, Car_balloon, Car_buyout, Living_Expenses, Savings, Interest_Rate, Inflation, Mich_present,
                    Overseas_trip, Mark_reno, D_leave_owed_in_days, D_TLS_shares, M_TLS_shares, D_CBA_shares,
                    TLS_price, CBA_price, Overseas_trip_date, Mark_reno_date, Car_buyout_date, Sell_shares, CBA, TLS, Ioniq6_future
                    )
                    VALUES (
                    :name, :D_Salary, :D_Num_fortnights_pay, :School_Fees, :Car_loan_via_pay,
                    :Car_loan, :Car_balloon, :Car_buyout, :Living_Expenses, :Savings, :Interest_Rate, :Inflation, :Mich_present,
                    :Overseas_trip, :Mark_reno, :D_leave_owed_in_days, :D_TLS_shares, :M_TLS_shares, :D_CBA_shares,
                    :TLS_price, :CBA_price, :Overseas_trip_date, :Mark_reno_date, :Car_buyout_date, :Sell_shares, :CBA, :TLS, :Ioniq6_future
                    )
                    ''', data['vars'])
    cset_id = cur.lastrowid

    for d in data['savings_data']:
        cur.execute( f"INSERT INTO comparison_savings_data ( comparison_set_id, name, value  ) VALUES ( {cset_id}, '{d[0]}', '{d[1]}' )" )

    conn.commit()
    conn.close()
    return cset_id

################################################################################
#
# gets comparison set data from the DB based on cset_id passed in (via drop-down in GUI).
# returns a DICT vars pointing to all the var values used for the ARRAY savings_data of saved fortnightly $'s
# also sets date / amount for the last set of $'s for easy display in the GUI
#
################################################################################
def get_comp_set_data(cset_id):
    COMP={}
    # get comp data from DB (as object so dict conversion works below)
    conn = connect_db(True)
    cur = conn.cursor()

    # get saved finance data for this comparison set
    cur.execute( f"select * from comparison_set where id = {cset_id}" )
    res=cur.fetchone()
    if not res:
        return None
    COMP['vars']= dict(res)
    conn.close()

    # open new connection so we get rows back as basic array
    conn = connect_db(False)
    cur = conn.cursor()

    # get data for this comparison set
    cur.execute( f"select name, value from comparison_savings_data where comparison_set_id = {cset_id}" )
    COMP['savings_data']=cur.fetchall()

    # do this for convenience in printing single last cset data point
    COMP['date'], COMP['amount'] = COMP['savings_data'][-1]
    return COMP


def get_comp_set_options(finance):
    finance['COMP_SETS']=[ ( 0, 'Nothing' ) ]
    # get comp data from DB (as object so dict conversion works below)
    conn = connect_db(False)
    cur = conn.cursor()

    # get saved finance data for this comparison set
    cur.execute( f"select id, name from comparison_set order by id" )
    finance['COMP_SETS'].extend( cur.fetchall() )
    return
