# calc.py
from datetime import datetime, timedelta

def calculate_savings_depletion(finance):
    # Extract all the financial data from the database
    D_Salary = finance['D_Salary']
    M_salary = finance['M_salary']
    D_Num_fortnights_pay = finance['D_Num_fortnights_pay']
    M_Num_fortnights_pay = finance['M_Num_fortnights_pay']
    School_Fees = finance['School_Fees']
    Car_loan_via_pay = finance['Car_loan_via_pay']
    Car_loan = finance['Car_loan']
    Car_balloon = finance['Car_balloon']
    Living_Expenses = finance['Living_Expenses']
    Savings = finance['Savings']
    Interest_Rate = finance['Interest_Rate']
    Inflation = finance['Inflation']
    M_payout = finance['M_payout']
    Mich_present = finance['Mich_present']
    Overseas_trip = finance['Overseas_trip']
    Mark_reno = finance['Mark_reno']
    D_leave_owed_in_days = finance['D_leave_owed_in_days']
    Sell_shares = finance['Sell_shares']
    D_TLS_shares = finance['D_TLS_shares']
    M_TLS_shares = finance['M_TLS_shares']
    D_CBA_shares = finance['D_CBA_shares']
    TLS_price = finance['TLS_price']
    CBA_price = finance['CBA_price']

    # leave in days, 10 business days to a fortnight, salary is per fortnight, and we lose 37% to tax
    # (assuming we don't earn over $180k)
    D_leave_after_tax = (D_leave_owed_in_days/10) * D_Salary * 0.63;

    # Constants for interest calculations
    annual_interest_rate = Interest_Rate / 100.0
    daily_interest_rate = annual_interest_rate / 365

    # Time periods: start from now, and simulate till D is 65 (April 25)
    current_date = datetime.now()
    end_date = datetime(2031, 4, 15)

    # Fortnightly pay
    car_loan_via_pay = Car_loan_via_pay  # Fortnightly payment while income is paid
    regular_car_loan = Car_loan # Fortnightly payment after salary ends

    # Calculate daily living expenses
    daily_living_expenses = Living_Expenses / 365

    # Start the calculation
    current_savings = Savings
    depletion_date = None
    savings_per_fortnight = []
    
    # significant dates that are non-changeable
    school_fees_date = datetime(2025, 12, 5)
    car_balloon_date = datetime(2026, 11, 15)
    mich_present_date = datetime(2026,10,15)

    # significant dates - but who knows when? :)
    overseas_trip_date = datetime.strptime( finance['Overseas_trip_date'], "%Y-%m-%d")
    mark_reno_date = datetime.strptime( finance['Mark_reno_date'], "%Y-%m-%d")
    M_payout_date = datetime.strptime( finance['M_payout_date'], "%Y-%m-%d")

    # to force deakin pay cycles to match reality, we work from the 8th of Jan as our "day-zero" so we are paid on the 8/1/25, 22/1/25, etc.
    days_count = ( current_date - datetime(2025,1,1) ).days

    # Track the fortnight, and monthly interest
    fortnight_income = 0
    monthly_interest = 0

    while current_date <= end_date:
        #paid on 8th or 22nd of Jan (so 8th day of fortnight)
        is_fortnight = (days_count % 14 == 7)
        is_end_of_month = (current_date.day == 1)
        
        # Subtract daily living expenses
        current_savings -= daily_living_expenses

        # Calculate daily interest but apply at the end of the month
        monthly_interest += current_savings * daily_interest_rate

        # Apply fortnightly salary and handle car loan deduction
        if is_fortnight:
            if D_Num_fortnights_pay > 0:
                fortnight_income += D_Salary 
                D_Num_fortnights_pay -= 1
            if M_Num_fortnights_pay > 0:
                fortnight_income += M_salary 
                M_Num_fortnights_pay -= 1

            if D_Num_fortnights_pay == 0 and D_leave_after_tax > 0:
                print(f"D has resigned {current_date}:  get paid out my 9 weeks leave and lose 45% to tax - ${D_leave_after_tax}" )
                current_savings += D_leave_after_tax
                D_leave_after_tax = 0

            if fortnight_income:
                print(f"salary paid by Deakin: {current_date} adding: {fortnight_income}" )
            current_savings += fortnight_income
            fortnight_income = 0  # reset for next fortnight

            # keep paying car off until the end of the car loan
            if current_date < car_balloon_date:
                if D_Num_fortnights_pay > 0:
                    current_savings -= car_loan_via_pay
                else:
                    current_savings -= regular_car_loan

            savings_per_fortnight.append((current_date.strftime("%Y-%m-%d"), round(current_savings, 2)))

        if is_end_of_month:
            current_savings += monthly_interest
            #print(f"interest paid {current_date}: ${monthly_interest}")
            monthly_interest = 0
            # monthly increase living expenses by a monthly inflation multiplier
            Living_Expenses += (Inflation/100.0)/12 * Living_Expenses
            daily_living_expenses = Living_Expenses / 365
            #print(f"Living Exp inceased {current_date}: ${Living_Expenses}")

        if current_date.date() == M_payout_date.date():
            current_savings += M_payout
            print(f"payout={current_date} + {M_payout}")

        if current_date.date() == school_fees_date.date():
            current_savings -= School_Fees
            print(f"school fees={current_date} - {School_Fees}")

        if current_date.date() == car_balloon_date.date():
            current_savings -= Car_balloon
            print(f"car balloon paid={current_date} - {Car_balloon}")

        if current_date.date() == overseas_trip_date.date():
            current_savings -= Overseas_trip
            print(f"overseas_trip={current_date} - {Overseas_trip}")

        if current_date.date() == mich_present_date.date():
            current_savings -= Mich_present
            print(f"Mich_present={current_date} - {Mich_present}")

        if current_date.date() == mark_reno_date.date():
            current_savings -= Mark_reno
            print(f"Mark/reno costs={current_date} - {Mark_reno}")

        if current_savings < 0:
            depletion_date = current_date
            break

        # twice a year, CBA has a dividend of $2-2.5 DRP gives back around 20ish shares twice a year, estimate this...
        if current_date.day == 1 and (current_date.month == 4 or current_date.month == 10):
            drp = int( (2.25*D_CBA_shares/CBA_price) )
            print( f"DRP {current_date} - adding {drp} CBA shares" )
            D_CBA_shares += int( (2.25*D_CBA_shares/CBA_price) )

        if Sell_shares>0 and current_date.month == 7 and current_date.day == 1:
            # 2024 Govt. value
            tax_threshold = 18200 
            can_sell = 2*tax_threshold
            actual_sell = 0
            # sell off TLS first - and they are way under the limit, so just sell them all in one hit
            if D_TLS_shares > 0:
                actual_sell += TLS_price*D_TLS_shares
                D_TLS_shares = 0
            if M_TLS_shares > 0:
                actual_sell += TLS_price*M_TLS_shares
                M_TLS_shares = 0
 
            while actual_sell + CBA_price < can_sell and D_CBA_shares > 0:
                actual_sell += CBA_price
                D_CBA_shares -= 1
            Sell_shares -= 1
            
            print( f"SELLING SHARES {current_date}: D_TLS={D_TLS_shares}, D_CBA={D_CBA_shares}" )
            current_savings += actual_sell


        current_date += timedelta(days=1)
        days_count += 1

    return depletion_date, savings_per_fortnight, current_savings, D_TLS_shares+M_TLS_shares, D_CBA_shares

