@page "/routines"
@page "/{UserId}/routines"

@inject ApiClient Api
@inject NavigationManager Navigation
@inject UserContext UserContext

<PageTitle>Routines</PageTitle>

<div class="page">
    <header class="page-header">
        <h1>Routines</h1>
        <p>Build routines from your exercise list.</p>
        <button class="primary" @onclick="ToggleCreate">@(ShowCreateRoutine ? "Close" : "+")</button>
    </header>

    @if (ActiveRun is null)
    {
        @if (ExerciseList.Count == 0)
        {
            <section class="card">
                <h2>No exercises yet</h2>
                <p class="muted">Add exercises first, then create routines.</p>
                <button class="primary" @onclick="GoToExercises">Go to Exercises</button>
            </section>
        }

        @if (EditingRoutine is null)
        {
            @if (ShowCreateRoutine)
            {
                <section class="card">
                    <h2>Create Routine</h2>
                    <input class="input" placeholder="Routine name" @bind="NewRoutineName" @bind:event="oninput" />
                    <div class="list">
                        @foreach (var exercise in ExerciseList)
                        {
                            <label class="checkbox-row">
                                <input type="checkbox" checked="@SelectedExerciseIds.Contains(exercise.Id)" @onchange="() => ToggleExercise(exercise.Id)" />
                                <span>@exercise.Name</span>
                            </label>
                        }
                    </div>
                    <button class="primary" @onclick="CreateRoutineAsync" disabled="@string.IsNullOrWhiteSpace(NewRoutineName)">Save Routine</button>
                </section>
            }

            @if (ExerciseList.Count > 0 || RoutineList.Count > 0)
            {
                <section class="card">
                    <h2>Your Routines</h2>
                    @if (IsLoading)
                    {
                        <p>Loading...</p>
                    }
                    else if (RoutineList.Count == 0)
                    {
                        <p class="muted">No routines yet. Create one above.</p>
                    }
                    else
                    {
                        <div class="list">
                            @foreach (var routine in RoutineList)
                            {
                                <div class="list-item">
                                    <div>
                                        <div class="item-title">@routine.Name</div>
                                        <div class="item-subtitle">@string.Join(" · ", routine.Exercises.Select(e => e.Name))</div>
                                    </div>
                                    <div class="actions">
                                        <button class="ghost" @onclick="() => StartEdit(routine)" aria-label="Edit routine">✏️</button>
                                        <button class="ghost" @onclick="() => DeleteRoutineAsync(routine.Id)" aria-label="Delete routine">🗑️</button>
                                        <button class="primary" @onclick="() => StartRun(routine)">Start</button>
                                    </div>
                                </div>
                            }
                        </div>
                    }
                </section>
            }
        }

        @if (EditingRoutine is not null)
        {
            <section class="card">
                <h2>Edit Routine</h2>
                <input class="input" @bind="EditingName" @bind:event="oninput" />
                <div class="list">
                    @foreach (var exercise in ExerciseList)
                    {
                        <label class="checkbox-row">
                            <input type="checkbox" checked="@EditingExerciseIds.Contains(exercise.Id)" @onchange="() => ToggleEditExercise(exercise.Id)" />
                            <span>@exercise.Name</span>
                        </label>
                    }
                </div>
                <div class="actions">
                    <button class="primary" @onclick="SaveEditAsync">Save Changes</button>
                    <button class="ghost" @onclick="CancelEdit">Cancel</button>
                </div>
            </section>
        }
    }
    else
    {
        <section class="card">
            <h2>Routine Run: @ActiveRun.Name</h2>
            <div class="list">
                @foreach (var entry in RunEntries)
                {
                    <div class="list-item @(entry.Completed ? "done" : string.Empty)">
                        <label class="checkbox-row">
                            <input type="checkbox" checked="@entry.Completed" @onchange="() => ToggleRunCompleted(entry.ExerciseId)" />
                            <span>@GetExerciseName(entry.ExerciseId)</span>
                        </label>
                        <div class="input-unit">
                            <input class="input input-sm" type="number" step="0.5" @bind="entry.Weight" @bind:event="oninput" />
                            <span class="unit">kg</span>
                        </div>
                    </div>
                }
            </div>
            <div class="actions">
                <button class="ghost" @onclick="AbortRun">Abort</button>
                <button class="primary" @onclick="SaveRunAsync">Save Run</button>
            </div>
        </section>
    }
</div>

@code {
    [Parameter]
    public string? UserId { get; set; }

    private List<ExerciseDto> ExerciseList { get; set; } = new();
    private List<RoutineDto> RoutineList { get; set; } = new();
    private bool IsLoading { get; set; } = true;
    private bool ShowCreateRoutine { get; set; }

    private string NewRoutineName { get; set; } = string.Empty;
    private HashSet<int> SelectedExerciseIds { get; set; } = new();

    private RoutineDto? EditingRoutine { get; set; }
    private string EditingName { get; set; } = string.Empty;
    private HashSet<int> EditingExerciseIds { get; set; } = new();

    private RoutineDto? ActiveRun { get; set; }
    private List<RoutineRunEntryDto> RunEntries { get; set; } = new();

    protected override async Task OnInitializedAsync()
    {
        var ensured = await Api.EnsureUserAsync(UserId);
        if (string.IsNullOrWhiteSpace(ensured))
        {
            return;
        }

        UserContext.SetUserId(ensured);
        if (UserId != ensured)
        {
            Navigation.NavigateTo($"/{ensured}/routines", true);
            return;
        }

        await LoadDataAsync();
    }

    private async Task LoadDataAsync()
    {
        IsLoading = true;
        ExerciseList = await Api.GetExercisesAsync(UserContext.UserId);
        RoutineList = await Api.GetRoutinesAsync(UserContext.UserId);
        IsLoading = false;
    }

    private void ToggleExercise(int exerciseId)
    {
        if (!SelectedExerciseIds.Add(exerciseId))
        {
            SelectedExerciseIds.Remove(exerciseId);
        }
    }

    private async Task CreateRoutineAsync()
    {
        if (string.IsNullOrWhiteSpace(NewRoutineName))
        {
            return;
        }

        var request = new RoutineUpsertRequest(NewRoutineName, SelectedExerciseIds.ToList());
        var created = await Api.CreateRoutineAsync(UserContext.UserId, request);
        if (created is not null)
        {
            RoutineList.Add(created);
            RoutineList = RoutineList.OrderBy(r => r.Name).ToList();
            NewRoutineName = string.Empty;
            SelectedExerciseIds.Clear();
        }
    }

    private void ToggleCreate()
    {
        ShowCreateRoutine = !ShowCreateRoutine;
    }

    private void GoToExercises()
    {
        Navigation.NavigateTo($"/{UserContext.UserId}/exercises");
    }

    private void StartEdit(RoutineDto routine)
    {
        EditingRoutine = routine;
        EditingName = routine.Name;
        EditingExerciseIds = routine.Exercises.Select(e => e.ExerciseId).ToHashSet();
    }

    private void CancelEdit()
    {
        EditingRoutine = null;
        EditingName = string.Empty;
        EditingExerciseIds.Clear();
    }

    private void ToggleEditExercise(int exerciseId)
    {
        if (!EditingExerciseIds.Add(exerciseId))
        {
            EditingExerciseIds.Remove(exerciseId);
        }
    }

    private async Task SaveEditAsync()
    {
        if (EditingRoutine is null)
        {
            return;
        }

        var request = new RoutineUpsertRequest(EditingName, EditingExerciseIds.ToList());
        var updated = await Api.UpdateRoutineAsync(UserContext.UserId, EditingRoutine.Id, request);
        if (updated is not null)
        {
            var index = RoutineList.FindIndex(r => r.Id == EditingRoutine.Id);
            if (index >= 0)
            {
                RoutineList[index] = updated;
                RoutineList = RoutineList.OrderBy(r => r.Name).ToList();
            }
        }

        CancelEdit();
    }

    private async Task DeleteRoutineAsync(int routineId)
    {
        await Api.DeleteRoutineAsync(UserContext.UserId, routineId);
        RoutineList.RemoveAll(r => r.Id == routineId);
    }

    private async Task StartRun(RoutineDto routine)
    {
        ActiveRun = routine;
        var lastRun = await Api.GetLastRunAsync(UserContext.UserId, routine.Id);
        RunEntries = routine.Exercises
            .OrderBy(e => e.Order)
            .Select(e =>
            {
                var last = lastRun.Entries.FirstOrDefault(x => x.ExerciseId == e.ExerciseId);
                return new RoutineRunEntryDto(e.ExerciseId, last?.Weight ?? 0, false);
            }).ToList();
    }

    private void ToggleRunCompleted(int exerciseId)
    {
        var entry = RunEntries.FirstOrDefault(e => e.ExerciseId == exerciseId);
        if (entry is null)
        {
            return;
        }

        entry.Completed = !entry.Completed;
    }

    private string GetExerciseName(int exerciseId)
    {
        return ExerciseList.FirstOrDefault(e => e.Id == exerciseId)?.Name ?? "Exercise";
    }

    private void AbortRun()
    {
        ActiveRun = null;
        RunEntries = new List<RoutineRunEntryDto>();
    }

    private async Task SaveRunAsync()
    {
        if (ActiveRun is null)
        {
            return;
        }

        var request = new RoutineRunRequest(RunEntries);
        await Api.SaveRunAsync(UserContext.UserId, ActiveRun.Id, request);
        ActiveRun = null;
        RunEntries = new List<RoutineRunEntryDto>();
    }
}
