@using Microsoft.EntityFrameworkCore
@using BlazorSortableList
@using WebApp.Models
@page "/students/event-ranking-edit/{StudentId:int}"
@inject AppDbContext Context
@inject NavigationManager NavigationManager

<PageTitle>Student Event Ranks - TSA Chapter Organizer</PageTitle>

<MudText Typo="Typo.h3"><MudIcon Icon="@AppIcons.EventRank"></MudIcon> Student Event Ranks</MudText>

<div>
    @if (_student == null)
    {
        <p><em>Loading...</em></p>
    }
    else
    {
        <MudText Typo="Typo.h4">@_student.Name</MudText>
        <MudText Color="Color.Warning">Warning: drag and drop is currently a bit squirrely - double check!</MudText>

        <MudButton StartIcon="@Icons.Material.Filled.ArrowBack" Href="students/event-ranking">Back</MudButton>
        <MudButton StartIcon="@Icons.Material.Filled.Save" OnClick="Save">Save</MudButton>

        /* https://github.com/AlexNek/BlazorSortableList */
        <MudGrid>
            <MudItem xs="6" md="4" xl="3" Class="ranked-event-column">
                <SortableList 
                    Group="GroupId" Id="ListId1" Context="item"
                    Items="_rankedEvents" OnRemove="RankedEventsRemove"  OnUpdate="Update">
                    <SortableItemTemplate>
                        <MudCard Outlined="true">
                            <MudCardContent>@item.Name</MudCardContent>
                        </MudCard>
                    </SortableItemTemplate>
                </SortableList>
            </MudItem>
            <MudItem xs="6" md="4" xl="3">
                <SortableList
                    Group="GroupId" Id="ListId2" Context="item"
                    Items="_availableEvents" OnRemove="AvailableEventsRemove" Sort="false">
                    <SortableItemTemplate>
                        <MudCard Outlined="true">
                            <MudCardContent>@item.Name</MudCardContent>
                        </MudCard>
                    </SortableItemTemplate>

                </SortableList>
            </MudItem>
        </MudGrid>
    }
</div>

@code {

    private const string ListId1 = "SharedListId1";
    private const string ListId2 = "SharedListId2";
    private const string GroupId = "CommonGroup";

    [Parameter] public int? StudentId { get; set; }

    private Student? _student;
    private List<EventDefinition>? _events;

    public List<EventDefinition> _rankedEvents = [];
    public List<EventDefinition> _availableEvents = [];

    SharedSortableListGroup _group;

    private void RankedEventsRemove((int oldIndex, int newIndex) indices)
    {
        // get the item at the old index in list 1
        var item = _rankedEvents[indices.oldIndex];

        // add it to the new index in list 2
        _availableEvents.Insert(indices.newIndex, item);

        // remove the item from the old index in list 1
        _rankedEvents.Remove(_rankedEvents[indices.oldIndex]);
    }

    private void AvailableEventsRemove((int oldIndex, int newIndex) indices)
    {
        // get the item at the old index in list 2
        var item = _availableEvents[indices.oldIndex];

        // add it to the new index in list 1
        _rankedEvents.Insert(indices.newIndex, item);

        // remove the item from the old index in list 2
        _availableEvents.Remove(_availableEvents[indices.oldIndex]);
    }

    protected override async Task OnInitializedAsync()
    {
        _student =
            await Context.Students
                .Include(e => e.EventRankings)
                .Where(e => e.Id == StudentId).FirstAsync();
        _events =
            await Context.Events
                .OrderBy(e => e.Name)
            .ToListAsync();

        _rankedEvents = _student.EventRankings.OrderBy(e => e.Rank).Select(e => e.EventDefinition).ToList();
        _availableEvents = _events.Where(e => !_rankedEvents.Contains(e)).ToList();

        _group = new SharedSortableListGroup(StateHasChanged);
        _group.AddModel(ListId1, new SortableListModel<EventDefinition>(_rankedEvents) { Group = GroupId });
        _group.AddModel(ListId2, new SortableListModel<EventDefinition>(_availableEvents) { Group = GroupId });
    }

    private void Update((int oldIndex, int newIndex) indices)
    {
        var (oldIndex, newIndex) = indices;

        var items = _rankedEvents;
        var itemToMove = items[oldIndex];
        items.RemoveAt(oldIndex);

        if (newIndex < items.Count)
        {
            items.Insert(newIndex, itemToMove);
        }
        else
        {
            items.Add(itemToMove);
        }

        StateHasChanged();
    }


    async Task Save()
    {
        if (_student == null)
            return;

        try
        {
            _student.EventRankings.Clear();
            for (var index = 0; index < _rankedEvents.Count; index++)
            {
                var evt = _rankedEvents[index];
                _student.EventRankings.Add(new StudentEventRanking
                {
                    EventDefinition = evt,
                    Student = _student,
                    Rank = index + 1
                });
            }

            Context.Students.Update(_student);

            await Context.SaveChangesAsync();

            NavigationManager.NavigateTo("/students/event-ranking");
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}
