@page "/yearly-summary"
@page "/yearly-summary/{Year:int}"
@attribute [Authorize]
@rendermode InteractiveServer

@using System.Globalization
@inject global::WorkTracker.Services.WorkDays.IWorkDayService WorkDayService
@inject IJSRuntime JS
@inject NavigationManager Navigation

<PageTitle>Yearly Summary</PageTitle>

<h1>Yearly Summary</h1>

<div class="d-flex align-items-center gap-2 mb-3">
    <button class="btn btn-outline-secondary btn-sm" @onclick="PreviousYear">&laquo; Prev</button>
    <h2 class="h5 mb-0">@currentYear</h2>
    <button class="btn btn-outline-secondary btn-sm" @onclick="NextYear">Next &raquo;</button>
    <a class="btn btn-outline-primary btn-sm ms-auto" href="summary">Monthly Summary</a>
</div>

<div class="form-check mb-3">
    <input id="include-preview-yearly" type="checkbox" class="form-check-input" checked="@includePreview" @onchange="OnIncludePreviewChanged" />
    <label class="form-check-label" for="include-preview-yearly">Include preview work units in totals</label>
</div>

@if (loading)
{
    <p><em>Loading...</em></p>
}
else
{
    <div class="yearly-summary-card card border-0 shadow-sm">
        <div class="card-body p-0">
            <div class="table-responsive">
                <table class="table table-bordered table-sm align-middle mb-0 yearly-summary-table">
                    <thead>
                        <tr>
                            <th class="yearly-summary-sticky-column">Month</th>
                            <th class="text-end yearly-summary-header-cell">Working Days</th>
                            <th class="text-end yearly-summary-header-cell">Worked Hours</th>
                            <th class="text-end yearly-summary-header-cell">Hours Off</th>
                            <th class="text-end yearly-summary-header-cell text-success">Gross Income</th>
                            <th class="text-end yearly-summary-header-cell text-primary">Net Income</th>
                            <th class="text-end yearly-summary-header-cell">Office Days</th>
                            <th class="text-end yearly-summary-header-cell">Home Days</th>
                            <th class="text-end yearly-summary-header-cell">Holidays</th>
                            <th class="text-end yearly-summary-header-cell">Closure Days</th>
                            <th class="text-end yearly-summary-header-cell">Days Off</th>
                            <th class="text-end yearly-summary-header-cell">Sick Days</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (var month in summaryByMonth)
                        {
                            <tr>
                                <th scope="row" class="yearly-summary-sticky-column">
                                    <a href="summary/@GetYearMonth(month)">@GetMonthLabel(month)</a>
                                </th>
                                <td class="text-end">@FormatCount(month.TotalWorkingDays)</td>
                                <td class="text-end">@FormatHoursCell(month.TotalWorkedHours)</td>
                                <td class="text-end">@FormatHoursCell(month.TotalHoursOff)</td>
                                <td class="text-end text-success">@FormatCurrency(month.TotalGrossIncome)</td>
                                <td class="text-end text-primary">@FormatCurrency(month.TotalNetIncome)</td>
                                <td class="text-end">@FormatCount(month.OfficeDays)</td>
                                <td class="text-end">@FormatCount(month.HomeDays)</td>
                                <td class="text-end">@FormatCount(month.HolidayDays)</td>
                                <td class="text-end">@FormatCount(month.ClosureDays)</td>
                                <td class="text-end">@FormatCount(month.DaysOff)</td>
                                <td class="text-end">@FormatCount(month.SickDays)</td>
                            </tr>
                        }
                    </tbody>
                    <tfoot>
                        <tr class="yearly-summary-total-row">
                            <th class="yearly-summary-sticky-column">Total</th>
                            <td class="text-end">@FormatCount(Totals.TotalWorkingDays)</td>
                            <td class="text-end">@FormatHoursCell(Totals.TotalWorkedHours)</td>
                            <td class="text-end">@FormatHoursCell(Totals.TotalHoursOff)</td>
                            <td class="text-end text-success">@FormatCurrency(Totals.TotalGrossIncome)</td>
                            <td class="text-end text-primary">@FormatCurrency(Totals.TotalNetIncome)</td>
                            <td class="text-end">@FormatCount(Totals.OfficeDays)</td>
                            <td class="text-end">@FormatCount(Totals.HomeDays)</td>
                            <td class="text-end">@FormatCount(Totals.HolidayDays)</td>
                            <td class="text-end">@FormatCount(Totals.ClosureDays)</td>
                            <td class="text-end">@FormatCount(Totals.DaysOff)</td>
                            <td class="text-end">@FormatCount(Totals.SickDays)</td>
                        </tr>
                    </tfoot>
                </table>
            </div>
        </div>
    </div>
}

@code {
    [Parameter] public int? Year { get; set; }

    private static readonly CultureInfo ItalianCulture = CultureInfo.GetCultureInfo("it-IT");
    private const string IncludePreviewPreferenceKey = "worktracker.includePreviewWorkUnits";

    private int currentYear;
    private bool loading = true;
    private bool includePreview;
    private IReadOnlyList<global::WorkTracker.Domain.MonthlySummaryModel> summaryByMonth = [];

    private global::WorkTracker.Domain.MonthlySummaryModel Totals => new()
    {
        Year = currentYear,
        TotalWorkingDays = summaryByMonth.Sum(item => item.TotalWorkingDays),
        CountedWorkUnits = summaryByMonth.Sum(item => item.CountedWorkUnits),
        TotalWorkedHours = summaryByMonth.Sum(item => item.TotalWorkedHours),
        TotalPreviewWorkedHours = summaryByMonth.Sum(item => item.TotalPreviewWorkedHours),
        PreviewWorkUnits = summaryByMonth.Sum(item => item.PreviewWorkUnits),
        TotalHoursOff = summaryByMonth.Sum(item => item.TotalHoursOff),
        TotalGrossIncome = summaryByMonth.Sum(item => item.TotalGrossIncome),
        TotalNetIncome = summaryByMonth.Sum(item => item.TotalNetIncome),
        OfficeDays = summaryByMonth.Sum(item => item.OfficeDays),
        HomeDays = summaryByMonth.Sum(item => item.HomeDays),
        HolidayDays = summaryByMonth.Sum(item => item.HolidayDays),
        ClosureDays = summaryByMonth.Sum(item => item.ClosureDays),
        DaysOff = summaryByMonth.Sum(item => item.DaysOff),
        SickDays = summaryByMonth.Sum(item => item.SickDays)
    };

    protected override async Task OnParametersSetAsync()
    {
        currentYear = Year ?? DateTime.Today.Year;
        await LoadSummary();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (!firstRender)
        {
            return;
        }

        var savedIncludePreview = await JS.InvokeAsync<bool?>("workTrackerPreferences.getBool", IncludePreviewPreferenceKey);
        if (savedIncludePreview.HasValue && savedIncludePreview.Value != includePreview)
        {
            includePreview = savedIncludePreview.Value;
            await LoadSummary();
            await InvokeAsync(StateHasChanged);
        }
    }

    private async Task LoadSummary()
    {
        loading = true;
        summaryByMonth = await WorkDayService.GetYearlySummaryAsync(currentYear, includePreview);
        loading = false;
    }

    private async Task OnIncludePreviewChanged(ChangeEventArgs e)
    {
        includePreview = e.Value is bool value && value;
        await JS.InvokeVoidAsync("workTrackerPreferences.setBool", IncludePreviewPreferenceKey, includePreview);
        await LoadSummary();
    }

    private Task PreviousYear()
    {
        currentYear--;
        Navigation.NavigateTo($"/yearly-summary/{currentYear}");
        return Task.CompletedTask;
    }

    private Task NextYear()
    {
        currentYear++;
        Navigation.NavigateTo($"/yearly-summary/{currentYear}");
        return Task.CompletedTask;
    }

    private static string GetMonthLabel(global::WorkTracker.Domain.MonthlySummaryModel month)
    {
        return new DateOnly(month.Year, month.Month, 1).ToString("MMMM", ItalianCulture);
    }

    private static string GetYearMonth(global::WorkTracker.Domain.MonthlySummaryModel month)
    {
        return $"{month.Year:D4}-{month.Month:D2}";
    }

    private static string FormatHours(decimal value)
    {
        return DurationFormatter.FormatHours(value);
    }

    private static string FormatHoursCell(decimal value)
    {
        return DurationFormatter.FormatHours(value, blankWhenZero: true);
    }

    private static string FormatCount(int value)
    {
        return value == 0 ? string.Empty : value.ToString(CultureInfo.InvariantCulture);
    }

    private static string FormatCurrency(decimal value)
    {
        return value == 0m ? string.Empty : $"€{value.ToString("N2", ItalianCulture)}";
    }
}