@page "/todos"
@rendermode InteractiveServer
@attribute [StreamRendering]

@using ToDos.Business.Abstractions
@using ToDos.Business.Models
@inject ITodoService TodoService

<PageTitle>ToDos</PageTitle>

<h1>ToDos</h1>
<p>Liste des todos :</p>

@if (todos == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <div class="card p-3 mb-3">
        <h5>Filtres</h5>

        <div class="row g-2">
            <div class="col-md-4">
                <label class="form-label">Recherche (libellé/commentaire)</label>
                <InputText class="form-control" @bind-Value="filter.Search" />
            </div>

            <div class="col-md-3">
                <label class="form-label">Statut</label>
                <select class="form-select" @bind="statusValue">
                    <option value="">Tous</option>
                    <option value="todo">À faire</option>
                    <option value="done">Faits</option>
                </select>
            </div>

            <div class="col-md-2">
                <label class="form-label">Planifiée du</label>
                <InputDate TValue="DateTime ?" class="form-control" @bind-Value="filter.PlanifFrom" />
            </div>

            <div class="col-md-2">
                <label class="form-label">au</label>
                <InputDate TValue="DateTime ?" class="form-control" @bind-Value="filter.PlanifTo" />
            </div>
        </div>

        <div class="row g-2 mt-2">
            <div class="col-md-2">
                <label class="form-label">Réalisée du</label>
                <InputDate TValue="DateTime ?" class="form-control" @bind-Value="filter.DoneFrom" />
            </div>

            <div class="col-md-2">
                <label class="form-label">au</label>
                <InputDate TValue="DateTime ?" class="form-control" @bind-Value="filter.DoneTo" />
            </div>

            <div class="col-md-8 d-flex align-items-end justify-content-end gap-2">
                <button class="btn btn-primary" @onclick="ApplyFilter">Filtrer</button>
                <button class="btn btn-outline-secondary" @onclick="ResetFilter">Réinitialiser</button>
            </div>
        </div>
    </div>

    <div class="table-wrap">
        <RadzenDataGrid Data="@todos"
                        TItem="TodosVM"
                        AllowPaging="true"
                        PageSize="10"
                        AllowSorting="true"
                        AllowColumnResize="true"
                        Responsive="true"
                        EmptyText="Aucune ToDo"
                        class="w-100 dense-grid">
            <Columns>
                <RadzenDataGridColumn TItem="TodosVM" Property="Id" Title="ID" Width="70px" />

                <RadzenDataGridColumn TItem="TodosVM" Property="Libelle" Title="Libellé" Width="220px">
                    <Template Context="t">
                        <div class="truncate" title="@t.Libelle">@t.Libelle</div>
                    </Template>
                </RadzenDataGridColumn>

                <RadzenDataGridColumn TItem="TodosVM" Property="Commentaire" Title="Commentaire" Width="260px">
                    <Template Context="t">
                        <div class="truncate" title="@t.Commentaire">@t.Commentaire</div>
                    </Template>
                </RadzenDataGridColumn>

                <RadzenDataGridColumn TItem="TodosVM" Property="Date_planif" Title="Planifiée le" Width="110px">
                    <Template Context="t">
                        @t.Date_planif.ToString("yyyy-MM-dd")
                    </Template>
                </RadzenDataGridColumn>

                <RadzenDataGridColumn TItem="TodosVM" Property="Date_realisation" Title="Réalisée le" Width="110px">
                    <Template Context="t">
                        @(t.Date_realisation.HasValue? t.Date_realisation.Value.ToString("yyyy-MM-dd") : "")
                    </Template>
                </RadzenDataGridColumn>

                <RadzenDataGridColumn TItem="TodosVM" Title="Statut" Width="170px">
                    <Template Context="t">
                        <div class="d-flex flex-column align-items-start">
                            <span class="badge @GetStatusBadgeClass(t)">
                                @t.Statut
                            </span>

                            @if (t.DureeAvanceJours > 0)
                            {
                                <small class="text-success">@t.DureeAvanceJours j</small>
                            }
                            else if (t.DureeRetardJours > 0)
                            {
                                <small class="text-danger">@t.DureeRetardJours j</small>
                            }
                        </div>
                    </Template>
                </RadzenDataGridColumn>

                <RadzenDataGridColumn TItem="TodosVM"
                                      Title="Actions"
                                      Sortable="false"
                                      Filterable="false"
                                      Width="90px">
                    <Template Context="t">
                        <div class="d-flex gap-1">
                            <RadzenButton Icon="edit"
                                          ButtonStyle="ButtonStyle.Warning"
                                          Size="ButtonSize.Small"
                                          Click="@(args => ShowEditForm(t))"
                                          Title="Modifier" />

                            <RadzenButton Icon="delete"
                                          ButtonStyle="ButtonStyle.Danger"
                                          Size="ButtonSize.Small"
                                          Click="@(args => ConfirmDelete(t))"
                                          Title="Supprimer" />
                        </div>
                    </Template>
                </RadzenDataGridColumn>
            </Columns>
        </RadzenDataGrid>
    </div>

    @if (showDeleteConfirm && todoToDelete != null)
    {
        <div class="alert alert-danger mt-3">
            <p>
                Êtes-vous sûr de vouloir supprimer :
                <strong>@todoToDelete.Libelle</strong> ?
            </p>

            <button class="btn btn-danger me-2" @onclick="DeleteTodo">
                Oui, supprimer
            </button>

            <button class="btn btn-secondary" @onclick="CancelDelete">
                Annuler
            </button>
        </div>
    }

    <button class="btn btn-success mb-3" @onclick="ShowCreateForm">
        Ajouter une ToDo
    </button>

    @if (showCreateForm)
    {
        <div class="accordion mb-3" id="todoCreateAccordion">
            <div class="accordion-item">
                <h2 class="accordion-header" id="headingCreate">
                    <button class="accordion-button @(createAccordionOpen ? "" : "collapsed")"
                            type="button"
                            @onclick="() => createAccordionOpen = !createAccordionOpen">
                        Ajouter une ToDo
                    </button>
                </h2>

                <div class="accordion-collapse collapse @(createAccordionOpen ? "show" : "")"
                     aria-labelledby="headingCreate">
                    <div class="accordion-body">

                        <EditForm Model="@newTodo"
                                  OnValidSubmit="CreateTodo"
                                  @key="formKey">
                            <DataAnnotationsValidator />

                            <ValidationSummary />

                            <div class="mb-2">
                                <label>Libellé</label>
                                <InputText class="form-control"
                                           @bind-Value="newTodo.Libelle" />
                                <ValidationMessage For="() => newTodo.Libelle" />
                            </div>

                            <div class="mb-2">
                                <label>Commentaire</label>
                                <InputText class="form-control"
                                           @bind-Value="newTodo.Commentaire" />
                            </div>

                            <div class="mb-2">
                                <label>Date planifiée</label>
                                <InputDate TValue="DateTime"
                                           class="form-control"
                                           @bind-Value="newTodo.Date_planif"
                                           @attributes="PlanifDateMinAttr" />

                                <ValidationMessage For="() => newTodo.Date_planif" />

                                @* Warning si date < aujourd'hui mais >= aujourd'hui - 7 *@
                                @if (newTodo.ShouldWarnPlanifInPastButAllowed)
                                {
                                    <div class="alert alert-warning py-1 mt-2 mb-0">
                                        @newTodo.PlanifWarningMessage
                                    </div>
                                }
                            </div>

                            <div class="mb-2">
                                <label>Date de réalisation</label>
                                <InputDate TValue="DateTime ?"
                                           class="form-control"
                                           @bind-Value="newTodo.Date_realisation" />
                            </div>

                            <div class="mt-3">
                                <button class="btn btn-primary me-2">Ajouter</button>
                                <button type="button"
                                        class="btn btn-secondary"
                                        @onclick="CancelCreate">
                                    Annuler
                                </button>
                            </div>
                        </EditForm>

                    </div>
                </div>
            </div>
        </div>
    }

    @if (showEditForm)
    {
        <div class="accordion mb-3" id="todoEditAccordion">
            <div class="accordion-item">
                <h2 class="accordion-header" id="headingEdit">
                    <button class="accordion-button @(editAccordionOpen ? "" : "collapsed")"
                            type="button"
                            @onclick="() => editAccordionOpen = !editAccordionOpen">
                        Modifier la ToDo #@editTodo.Id
                    </button>
                </h2>

                <div class="accordion-collapse collapse @(editAccordionOpen ? "show" : "")"
                     aria-labelledby="headingEdit">
                    <div class="accordion-body">

                        <EditForm Model="@editTodo"
                                  OnValidSubmit="UpdateTodo"
                                  @key="editFormKey">
                            <DataAnnotationsValidator />

                            <ValidationSummary />

                            <div class="mb-2">
                                <label>Libellé</label>
                                <InputText class="form-control"
                                           @bind-Value="editTodo.Libelle" />
                                <ValidationMessage For="() => editTodo.Libelle" />
                            </div>

                            <div class="mb-2">
                                <label>Commentaire</label>
                                <InputText class="form-control"
                                           @bind-Value="editTodo.Commentaire" />
                            </div>

                            <div class="mb-2">
                                <label>Date planifiée</label>
                                <InputDate TValue="DateTime"
                                           class="form-control"
                                           @bind-Value="editTodo.Date_planif"
                                           @attributes="PlanifDateMinAttr" />

                                <ValidationMessage For="() => editTodo.Date_planif" />

                                @if (editTodo.ShouldWarnPlanifInPastButAllowed)
                                {
                                    <div class="alert alert-warning py-1 mt-2 mb-0">
                                        @editTodo.PlanifWarningMessage
                                    </div>
                                }
                            </div>

                            <div class="mb-2">
                                <label>Date de réalisation</label>
                                <InputDate TValue="DateTime ?"
                                           class="form-control"
                                           @bind-Value="editTodo.Date_realisation" />
                            </div>

                            <div class="mt-3">
                                <button class="btn btn-primary me-2">Enregistrer</button>
                                <button type="button"
                                        class="btn btn-secondary"
                                        @onclick="CancelEdit">
                                    Annuler
                                </button>
                            </div>
                        </EditForm>

                    </div>
                </div>
            </div>
        </div>
    }
}

@code {
    // =============================
    // Données
    // =============================

    private List<TodosVM>? todos;

    private TodosVM newTodo = new()
    {
        Date_planif = DateTime.Today
    };

    private TodosVM editTodo = new();

    private TodoFilter filter = new();

    private string statusValue = ""; // "", "todo", "done"

    // =============================
    // Min date planif (aujourd'hui - 7 jours)
    // =============================
    private DateTime MinPlanifDate => DateTime.Today.AddDays(-7);

    private IReadOnlyDictionary<string, object> PlanifDateMinAttr =>
        new Dictionary<string, object>
        {
            ["min"] = MinPlanifDate.ToString("yyyy-MM-dd")
        };

    // =============================
    // Accordéons
    // =============================
    private bool createAccordionOpen = true;
    private bool editAccordionOpen = true;

    // =============================
    // États UI
    // =============================

    private bool showCreateForm = false;
    private bool showEditForm = false;
    private bool showDeleteConfirm = false;

    private TodosVM? todoToDelete;

    // Clés pour forcer la recréation des formulaires
    private Guid formKey = Guid.NewGuid();
    private Guid editFormKey = Guid.NewGuid();

    // =============================
    // Cycle de vie
    // =============================

    protected override async Task OnInitializedAsync()
    {
        todos = await TodoService.GetTodosAsync(filter);
    }

    // =============================
    // UI – Affichage formulaires
    // =============================

    private void ShowCreateForm()
    {
        showCreateForm = true;
        showEditForm = false;
        showDeleteConfirm = false;

        newTodo = new TodosVM
        {
            Date_planif = DateTime.Today
        };

        formKey = Guid.NewGuid();

        createAccordionOpen = true; // ouvre l'accordéon
    }

    private void ShowEditForm(TodosVM todo)
    {
        editTodo = new TodosVM
        {
            Id = todo.Id,
            Libelle = todo.Libelle,
            Commentaire = todo.Commentaire,
            Date_planif = todo.Date_planif,
            Date_realisation = todo.Date_realisation
        };

        editFormKey = Guid.NewGuid();

        showEditForm = true;
        showCreateForm = false;
        showDeleteConfirm = false;

        editAccordionOpen = true; // ouvre l'accordéon
    }

    private void CancelCreate()
    {
        showCreateForm = false;
        createAccordionOpen = false;
    }

    private void CancelEdit()
    {
        showEditForm = false;
        editAccordionOpen = false;
    }

    // =============================
    // CRUD
    // =============================

    private async Task CreateTodo()
    {
        await TodoService.AddTodoAsync(newTodo);
        todos = await TodoService.GetTodosAsync(filter);

        showCreateForm = false;
        createAccordionOpen = false;
    }

    private async Task UpdateTodo()
    {
        await TodoService.UpdateTodoAsync(editTodo);
        todos = await TodoService.GetTodosAsync(filter);

        showEditForm = false;
        editAccordionOpen = false;
    }

    private void ConfirmDelete(TodosVM todo)
    {
        todoToDelete = todo;
        showDeleteConfirm = true;
        showCreateForm = false;
        showEditForm = false;
    }

    private async Task DeleteTodo()
    {
        if (todoToDelete == null)
            return;

        await TodoService.DeleteTodoAsync(todoToDelete.Id);
        todos = await TodoService.GetTodosAsync(filter);

        showDeleteConfirm = false;
        todoToDelete = null;
    }

    private void CancelDelete()
    {
        showDeleteConfirm = false;
        todoToDelete = null;
    }

    // =============================
    // Filtrage
    // =============================

    private void SyncStatusToFilter()
    {
        filter.IsDone = statusValue switch
        {
            "done" => true,
            "todo" => false,
            _ => null
        };
    }

    private async Task ApplyFilter()
    {
        SyncStatusToFilter();
        todos = await TodoService.GetTodosAsync(filter);
    }

    private async Task ResetFilter()
    {
        filter = new TodoFilter();
        statusValue = "";
        todos = await TodoService.GetTodosAsync(filter);
    }

    private string GetStatusBadgeClass(TodosVM t) => t.Statut switch
    {
        "En avance" => "bg-success",
        "À temps" => "bg-primary",
        "En retard" => "bg-danger",
        _ => "bg-secondary" // En cours
    };
}
