from decimal import Decimal

class FinancialEngine:
    def __init__(self, business_plan):
        self.bp = business_plan
    
    def calculate_global_costs(self):
        investments = self.bp.investments.all()
        startup_costs = self.bp.startup_costs.all()
        
        total_incorporel = sum(i.total_cost for i in investments if i.invest_type == 'INCORPOREL')
        total_corporel = sum(i.total_cost for i in investments if i.invest_type == 'CORPOREL')
        total_bfr = sum(c.total_bfr for c in startup_costs)
        
        total_project_cost = total_incorporel + total_corporel + total_bfr
        
        needed_loan = total_project_cost - (self.bp.personal_contribution + self.bp.other_funding)
        
        return {
            "incorporel": total_incorporel,
            "corporel": total_corporel,
            "bfr": total_bfr,
            "total_project": total_project_cost,
            "loan_amount": max(0, needed_loan)
        }

    def calculate_amortization_table(self):
        table = []
        investments = self.bp.investments.filter(duration_years__gt=0)
        total_annuity = 0
        for inv in investments:
            annuity = inv.annual_amortization
            table.append({
                "name": inv.name,
                "value": inv.total_cost,
                "duration": inv.duration_years,
                "annuity": annuity
            })
            total_annuity += annuity
        return {"lines": table, "total_annual_amortization": total_annuity}

    def calculate_loan_schedule(self, loan_amount):
        if loan_amount <= 0 or self.bp.loan_duration_months == 0:
            return []

        rate_annual = float(self.bp.loan_interest_rate) / 100
        duration_years = self.bp.loan_duration_months // 12
        if duration_years == 0: duration_years = 1
        
        schedule = []
        capital_restant = float(loan_amount)
        
        if rate_annual > 0:
            annuity = capital_restant * (rate_annual / (1 - (1 + rate_annual) ** -duration_years))
        else:
            annuity = capital_restant / duration_years

        for year in range(1, duration_years + 2):
            if capital_restant <= 1: break
            interest = capital_restant * rate_annual
            amortization = annuity - interest
            if amortization > capital_restant:
                amortization = capital_restant
                annuity = interest + amortization
            schedule.append({
                "year": f"Année {year}",
                "capital_start": round(capital_restant, 2),
                "interest": round(interest, 2),
                "amortization": round(amortization, 2),
                "annuity": round(annuity, 2)
            })
            capital_restant -= amortization
        return schedule

    def generate_pnl(self, sensitivity_mode="NORMAL"):
        years = ['year_1', 'year_2', 'year_3', 'year_4']
        pnl_data = []

        costs = self.calculate_global_costs()
        loan_schedule = self.calculate_loan_schedule(costs['loan_amount'])
        amort_assets = self.calculate_amortization_table()
        annual_depreciation = amort_assets['total_annual_amortization']

        for i, year_key in enumerate(years):
            revenues = sum(getattr(r, year_key) for r in self.bp.revenues.all())
            if sensitivity_mode == "PESSIMIST_REV": revenues = revenues * Decimal('0.90')

            expenses = sum(getattr(e, year_key) for e in self.bp.expenses.all())
            if sensitivity_mode == "PESSIMIST_COST": expenses = expenses * Decimal('1.10')

            rbe = revenues - expenses
            amortization = annual_depreciation
            interest = 0
            if i < len(loan_schedule): interest = Decimal(loan_schedule[i]['interest'])

            rai = rbe - amortization - interest
            impot = rai * Decimal('0.30') if rai > 0 else 0
            net_result = rai - impot
            cash_flow = net_result + amortization

            pnl_data.append({
                "year": i + 1,
                "revenues": round(revenues, 2),
                "expenses": round(expenses, 2),
                "rbe": round(rbe, 2),
                "amortization": round(amortization, 2),
                "interest": round(interest, 2),
                "rai": round(rai, 2),
                "impot": round(impot, 2),
                "net_result": round(net_result, 2),
                "cash_flow": round(cash_flow, 2)
            })
        return pnl_data