@page "/"
@using Radzen
@using Radzen.Blazor
@using BattSim.Models
@using BattSim.Services

<PageTitle>Thuisbatterij Simulator</PageTitle>

<h1 style="color: white">Thuisbatterij Simulator</h1>

<div class="pipeline-container">
    <!-- Pipeline with 3 connected boxes -->
    <div class="pipeline-row">
        <div class="pipeline-connector"></div>
        
        <!-- Box 1: Data Upload -->
        <div class="pipeline-box @GetPipelineStepClasses(0)">
            <div class="box-header" @onclick="() => ToggleBox(0)">
                <div class="step-number">1</div>
                <div class="step-title">Fluvius Data</div>
                <div class="status-indicator"></div>
            </div>
            <div class="box-content">
                <div class="box-content-inner">
                    <p class="box-description">Upload je Fluvius kwartierdata om te beginnen</p>
                    
                    <div class="form-section">
                        <div class="file-input-wrapper">
                            <InputFile  type="file" id="fileUpload" accept=".csv" onchange="async (e) => await OnFileUploaded(e)" />
                            <label for="fileUpload" class="file-input-label">
                                @if (StepData[0].isProcessing)
                                {
                                    <div class="loading-indicator">
                                        <div class="spinner"></div>
                                        <span style="margin-left: 10px;">Data aan het inladen...</span>
                                    </div>
                                }
                                else
                                {
                                    @if (FluviusDataRaw.Length == 0)
                                    {
                                        <text>Kies CSV bestand</text>
                                    }
                                    else
                                    {
                                        <text>OK @FluviusDataRaw.Length kwartieren geladen</text>
                                    }
                                }
                            </label>
                            @if (FluviusDataRaw.Length > 0 && !StepData[0].isProcessing)
                            {
                                <p class="file-name">@_uploadedFileName</p>
                            }
                        </div>
                    </div>
                    
                    @if (StepData[0].Completed)
                    {
                        <div class="success-message">
                            Data succesvol ingeladen en verwerkt!
                        </div>
                    }
                    @if (_uploadError != null)
                    {
                        <div class="error-message">
                            @_uploadError
                        </div>
                    }
                    
                    <div class="info-text">
                        <p><strong>Tip:</strong> Download een volledig jaar aan kwartierdata voor de meest accurate resultaten.</p>
                    </div>
                </div>
            </div>
        </div>

        <!-- Box 2: Battery Simulation -->
        <div class="pipeline-box @GetPipelineStepClasses(1)">
            <div class="box-header" @onclick="() => ToggleBox(1)">
                <div class="step-number">2</div>
                <div class="step-title">Batterij Simulatie</div>
                <div class="status-indicator"></div>
            </div>
            <div class="box-content">
                <div class="box-content-inner">
                    <p class="box-description">Test verschillende batterijconfiguraties</p>
                    
                    @if (FluviusDataRaw.Length == 0)
                    {
                        <div class="info-text">
                            <p>Upload eerst je Fluvius data (stap 1) om deze stap te kunnen uitvoeren.</p>
                        </div>
                    }
                    else
                    {
                        <div class="form-section">
                            <div style="display: flex; gap: 1rem;">
                                <div class="input-group" style="flex: 1;">
                                    <label>Batterijcapaciteit (kWh):</label>
                                    <InputNumber @bind-value="BatteryCapacity" T="double" min="0.1" max="100" step="0.1"/>
                                </div>
                                <div class="input-group" style="flex: 1;">
                                    <label>Round-trip Efficiëntie (%):</label>
                                    <InputNumber @bind-value="Efficiency" T="double" min="0" max="100" step="1"/>
                                </div>
                            </div>
                            <p style="font-size: 0.85rem; color: var(--text-clr); margin-top: 1rem;">
                                Efficiëntie is het percentage van opgeslagen energie dat terug kan worden gebruikt.
                            </p>
                        </div>
                        
                        <div style="display: flex; justify-content: center; margin-top: 1.5rem;">
                            <button @onclick="SimulateBattery" @onclick:stopPropagation disabled="@(StepData[1].isProcessing || FluviusDataRaw.Length == 0)">
                                @if (StepData[1].isProcessing)
                                {
                                    <text>Simuleren...</text>
                                }
                                else
                                {
                                    <text>Simuleer Batterij</text>
                                }
                            </button>
                        </div>
                        
                        @if (StepData[1].Completed)
                        {
                            <div class="success-message">
                                Simulatie voltooid! @SimulationData.Length kwartieren gesimuleerd.
                            </div>
                        }
                    }
                </div>
            </div>
        </div>

        <!-- Box 3: Cost Calculation -->
        <div class="pipeline-box @GetPipelineStepClasses(2)">
            <div class="box-header" @onclick="() => ToggleBox(2)">
                <div class="step-number">3</div>
                <div class="step-title">Kosten Berekenen</div>
                <div class="status-indicator"></div>
            </div>
            <div class="box-content">
                <div class="box-content-inner">
                    <p class="box-description">Vergelijk kosten met en zonder batterij</p>

                    <!-- Contractuele Kosten -->
                    <div style="margin-bottom: 1.5rem;">
                        <h4 style="color: var(--green-clr); margin-bottom: 0.75rem; border-bottom: 1px solid var(--border-clr); padding-bottom: 0.5rem;">
                            Contractuele Kosten
                        </h4>
                        <div style="display: flex; gap: 1rem; flex-wrap: wrap;">
                            <div class="input-group" style="flex: 1;">
                                <label>Vaste vergoeding (€/jaar):</label>
                                <InputNumber @bind-value="calculator.BasePayment" T="double" min="0" step="1"/>
                            </div>
                            <div class="input-group" style="flex: 1;">
                                <label>Databeheer tarief (€/jaar):</label>
                                <InputNumber @bind-value="calculator.DataManagementCost" T="double" min="0" step="0.01"/>
                            </div>
                        </div>

                        <!-- Vaste Kosten Subbox (Collapsed by Default) -->
                        <details class="collapsible-section" style="margin-top: 1rem;">
                            <summary class="collapsible-header">Vaste Kosten</summary>
                            <div class="collapsible-content">
                                <div style="display: flex; gap: 1rem; flex-wrap: wrap;">
                                    <!-- Vlaamse energieheffing (moved here) -->
                                    <div class="input-group" style="flex: 1;">
                                        <label>Vlaamse energieheffing (€/jaar):</label>
                                        <InputNumber @bind-value="calculator.FlemishEnergyTariff" T="double" min="0" step="0.01"/>
                                    </div>
                                </div>

                                <!-- Heffingen Groene Stroom -->
                                <div style="margin-top: 1rem;">
                                    <h5 style="color: var(--green-clr); margin-bottom: 0.5rem;">Heffingen Groene Stroom</h5>
                                    <div style="display: flex; gap: 1rem; flex-wrap: wrap;">
                                        <div class="input-group" style="flex: 1;">
                                            <label>Groene stroomcertificaten (c€/kWh):</label>
                                            <InputNumber @bind-value="calculator.GreenCertificateCost" T="double" min="0" step="0.0001"/>
                                        </div>
                                        <div class="input-group" style="flex: 1;">
                                            <label>Warmtekracht certificaten (c€/kWh):</label>
                                            <InputNumber @bind-value="calculator.HeatingCertificateCost" T="double" min="0" step="0.0001"/>
                                        </div>
                                    </div>
                                </div>

                                <!-- Net- en distributiekosten -->
                                <div style="margin-top: 1rem;">
                                    <h5 style="color: var(--green-clr); margin-bottom: 0.5rem;">Net- en distributiekosten</h5>
                                    <div style="display: flex; gap: 1rem; flex-wrap: wrap;">
                                        <div class="input-group" style="flex: 1;">
                                            <label>Capaciteitstarief (€/kWh/jaar):</label>
                                            <InputNumber @bind-value="calculator.CapacityCost" T="double" min="0" step="0.01"/>
                                        </div>
                                        <div class="input-group" style="flex: 1;">
                                            <label>Afnametarief (c€/kWh):</label>
                                            <InputNumber @bind-value="calculator.UsageTariff" T="double" min="0" step="0.0001"/>
                                        </div>
                                    </div>
                                </div>

                                <!-- Heffingen en Toeslagen -->
                                <div style="margin-top: 1rem;">
                                    <h5 style="color: var(--green-clr); margin-bottom: 0.5rem;">Heffingen en Toeslagen</h5>
                                    <div style="display: flex; gap: 1rem; flex-wrap: wrap;">
                                        <div class="input-group" style="flex: 1;">
                                            <label>Energiebijdrage (c€/kWh):</label>
                                            <InputNumber @bind-value="calculator.EnergyContribution" T="double" min="0" step="0.0001"/>
                                        </div>
                                        <div class="input-group" style="flex: 1;">
                                            <label>Bijzondere accijns (c€/kWh):</label>
                                            <InputNumber @bind-value="calculator.SpecialTariffs" T="double" min="0" step="0.0001"/>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </details>
                    </div>

                    <!-- Energiekosten -->
                    <div style="margin-bottom: 1.5rem;">
                        <h4 style="color: var(--green-clr); margin-bottom: 0.75rem; border-bottom: 1px solid var(--border-clr); padding-bottom: 0.5rem;">
                            Energiekosten
                        </h4>
                        <div style="display: flex; gap: 1rem; flex-wrap: wrap;">
                            <div class="input-group" style="flex: 1;">
                                <label>Energiekost (c€/kWh):</label>
                                <InputNumber @bind-value="calculator.EnergyCost" T="double" min="0" step="0.0001"/>
                            </div>
                            <div class="input-group" style="flex: 1;">
                                <label>Terugleveringsvergoeding (c€/kWh):</label>
                                <InputNumber @bind-value="calculator.ReturnCost" T="double" min="0" step="0.0001"/>
                            </div>
                        </div>
                    </div>

                    <div style="display: flex; justify-content: center; margin-top: 1.5rem;">
                        <button @onclick="Calculate" @onclick:stopPropagation disabled="@(StepData[2].isProcessing || SimulationData.Length == 0)">
                            @if (StepData[2].isProcessing)
                            {
                                <text>Berekenen...</text>
                            }
                            else
                            {
                                <text>Bereken Kosten</text>
                            }
                        </button>
                    </div>

                    @if (StepData[2].Completed)
                    {
                        <div class="results">
                            <p><strong>Originele kosten:</strong> <span class="result-value">€@normalCost.ToString("0.00")</span></p>
                            <p><strong>Gesimuleerde kosten:</strong> <span class="result-value">€@simulatedCost.ToString("0.00")</span></p>
                            <p><strong>Besparing:</strong> <span class="result-value">€@((normalCost - simulatedCost).ToString("0.00"))</span></p>
                            @if (normalCost > 0)
                            {
                                <p><strong>Besparingspercent:</strong> <span class="result-value">@(((normalCost - simulatedCost) / normalCost * 100).ToString("0.00"))%</span></p>
                            }
                        </div>
                    }
                </div>
            </div>
        </div>
    </div>

</div>


<!-- Chart - Directly on page, full width -->
@if (FilteredFluviusData.Length > 0)
{
    <div class="chart-container">
        <h2>Overzicht: Energie Data & Simulatie</h2>
        
        <!-- Time Period Toggle -->
        <div class="time-toggle-container">
            <button class="@GetTimeButtonClass("all")" @onclick="SetTimePeriodAll" @onclick:stopPropagation>
                Volledige periode
            </button>
            <button class="@GetTimeButtonClass("year")" @onclick="SetTimePeriodYear" @onclick:stopPropagation>
                Laatste jaar
            </button>
            <button class="@GetTimeButtonClass("month")" @onclick="SetTimePeriodMonth" @onclick:stopPropagation>
                Laatste maand
            </button>
            <button class="@GetTimeButtonClass("week")" @onclick="SetTimePeriodWeek" @onclick:stopPropagation>
                Laatste week
            </button>
            <button class="@GetTimeButtonClass("day")" @onclick="SetTimePeriodDay" @onclick:stopPropagation>
                Laatste dag
            </button>
        </div>
        
        <RadzenChart Class="unified-chart">
            <!-- Original Data -->
            <RadzenAreaSeries Smooth=true Data="@FilteredFluviusData" CategoryProperty="Time" Title="Consumption" ValueProperty="Consumption">
            </RadzenAreaSeries>
            <RadzenAreaSeries Smooth=true Data="@FilteredFluviusData" CategoryProperty="Time" Title="Production" ValueProperty="Production">
            </RadzenAreaSeries>
            
            <!-- Simulated Data -->
            @if (FilteredSimulationData.Length > 0)
            {
                <RadzenAreaSeries Smooth=true Data="@FilteredSimulationData" CategoryProperty="Time" Title="Simulated Consumption" ValueProperty="Consumption">
                </RadzenAreaSeries>
                <RadzenAreaSeries Smooth=true Data="@FilteredSimulationData" CategoryProperty="Time" Title="Simulated Production" ValueProperty="Production">
                </RadzenAreaSeries>
                <RadzenAreaSeries Smooth=true Data="@FilteredSimulationData" CategoryProperty="Time" Title="Battery Charge" ValueProperty="BatteryCharge">
                </RadzenAreaSeries>
            }
            
            <RadzenCategoryAxis Formatter="@FormatObject" Padding="20" LabelAutoRotation="-45">
                <RadzenGridLines Visible="true"/>
                <RadzenAxisTitle Text="Tijd"/>
            </RadzenCategoryAxis>
            <RadzenValueAxis Formatter="@FormatObject">
                <RadzenGridLines Visible="true"/>
                <RadzenAxisTitle Text="Energie (kWh)"/>
            </RadzenValueAxis>
        </RadzenChart>
    </div>
}

@code {
    EnergyData[] FluviusDataRaw = [];    
    EnergyData[] SimulationData = [];
    
    DataFilter.FilterOption SelectedFilterOption = DataFilter.FilterOption.ALL;

    EnergyData[] FilteredFluviusData = [];
    EnergyData[] FilteredSimulationData = [];
    
    EnergyCostCalculator calculator = new();
    double normalCost = 0.0;
    double simulatedCost = 0.0;
    
    struct PipelineStep{
        public bool Expanded;
        public bool Completed;
        public bool isProcessing;
    }

    PipelineStep[] StepData = [ 
        new PipelineStep(), // Step 1
        new PipelineStep(), // Step 2
        new PipelineStep(), // Step 3
    ];
    
    string _uploadedFileName = string.Empty;
    string? _uploadError = null;
    
    string _timePeriod = "all";
    
    double BatteryCapacity = 7.5;
    double Efficiency = 90;

    private string GetPipelineStepClasses(int step){
        var classes = new List<string>();
        if (StepData[step].Expanded) classes.Add("expanded");
        if (StepData[step].Completed) classes.Add("completed");
        if (StepData[step].isProcessing) classes.Add("running");
        return string.Join(" ", classes);
    }
    
    private string GetTimeButtonClass(string period)
    {
        var baseClass = "time-toggle-button";
        if (_timePeriod == period)
        {
            return $"{baseClass} active";
        }
        return baseClass;
    }

    private void SetTimePeriodAll() => SetTimePeriod("all");
    private void SetTimePeriodYear() => SetTimePeriod("year");
    private void SetTimePeriodMonth() => SetTimePeriod("month");
    private void SetTimePeriodWeek() => SetTimePeriod("week");
    private void SetTimePeriodDay() => SetTimePeriod("day");

    private void ToggleBox(int step)
    {
        if(step == 1 && FluviusDataRaw.Length == 0) return;
        if(step == 2 && SimulationData.Length == 0) return;
        StepData[step].Expanded = !StepData[step].Expanded;
        StateHasChanged();
    }

    private async Task OnFileUploaded(InputFileChangeEventArgs e)
    {
        _uploadError = null;
        var file = e.File;
        _uploadedFileName = file.Name;
        
        if (file.ContentType != "text/csv")
        {
            _uploadError = "Alleen CSV bestanden zijn toegestaan!";
            StateHasChanged();
            return;
        }

        try
        {
            StepData[0].isProcessing = true;
            StateHasChanged();
            
            FluviusDataRaw = await FluviusDataHandler.LoadAndProcessFile(file);
            SetTimePeriod("all");
            FilteredSimulationData = [];
            
            StepData[0].isProcessing = false;
            StepData[0].Completed = true;
            StepData[1].Completed = false;
            StepData[2].Completed = false;
            SimulationData = [];
            
            StateHasChanged();
        }
        catch (Exception ex)
        {
            StepData[0].isProcessing = false;
            _uploadError = ex.Message;
            StateHasChanged();
        }
    }

    private void SimulateBattery()
    {
        if (FluviusDataRaw.Length == 0) return;
        
        StepData[1].isProcessing = true;
        StateHasChanged();
        
        try
        {
            SimulationData = BatterySimulator.SimulateBattery(FluviusDataRaw, BatteryCapacity, Efficiency/100);
            SetTimePeriod("all");
            
            StepData[1].isProcessing = false;
            StepData[1].Completed = true;
            StepData[2].Completed = false;
            normalCost = 0;
            simulatedCost = 0;
            
            StateHasChanged();
        }
        catch (Exception ex)
        {
            StepData[1].isProcessing = false;
            Console.WriteLine($"Error: {ex.Message}");
        }
    }

    private void Calculate()
    {
        if (SimulationData.Length == 0) return;
        
        StepData[2].isProcessing = true;
        StateHasChanged();
        
        try
        {
            normalCost = calculator.CalculateCostOfEnergyUsage(FluviusDataRaw);            
            simulatedCost = calculator.CalculateCostOfEnergyUsage(SimulationData);            
            StepData[2].isProcessing = false;
            StepData[2].Completed = true;
            StateHasChanged();
        }
        catch (Exception ex)
        {
            StepData[2].isProcessing = false;
            Console.WriteLine($"Error: {ex.Message}");
        }
    }

    private void SetTimePeriod(string period)
    {
        _timePeriod = period;
        var filterOption = period switch {
            "all" => DataFilter.FilterOption.ALL,
            "year" => DataFilter.FilterOption.YEAR,
            "month" => DataFilter.FilterOption.MONTH,
            "week" => DataFilter.FilterOption.WEEK,
            "day" => DataFilter.FilterOption.DAY,
        };
        // Filter data based on selected period
        if(FluviusDataRaw.Length > 0) FilteredFluviusData = DataFilter.FilterData(FluviusDataRaw, filterOption);
        if(SimulationData.Length > 0) FilteredSimulationData = DataFilter.FilterData(SimulationData, filterOption);
        
        StateHasChanged();
    }

    private string FormatObject(object value) {
        if(value is double d) return $"{d:0.##} kWh";
        if(value is DateTime time) return time.ToString("dd/MM/yyyy");
        if(value is DateOnly date) return date.ToString("dd/MM/yyyy");
        return string.Empty;
    }
}
