@using SilverOS.Welcome.App.Components.Steps
@using SilverOS.Welcome.Core.Flavours
@using SilverOS.Welcome.Core.Apps
@using SilverOS.Welcome.Core.Preconfig
@inject IFlavourLoader FlavourLoader
@inject IAppCatalog AppCatalog
@inject IPreconfigStore PreconfigStore
@inject WizardState State
@inject SilverOS.Welcome.Core.Apply.IProcessRunner ProcessRunner

@if (_toolboxHome)
{
    <div class="toolbox-home">
        <h1>SilverMetal</h1>
        <p class="toolbox-home-subtitle">Your device is set up and ready to go.</p>
        <button class="btn-secondary" @onclick="ReRunSetup">Re-run setup</button>
    </div>
}
else
{
<div class="wizard">
    <div class="wizard-header">
        <div class="wizard-steps-indicator">
            @for (int i = 0; i < _stepTitles.Length; i++)
            {
                var idx = i;
                <span class="wizard-step-dot @(idx == _currentStep ? "active" : idx < _currentStep ? "done" : "")">
                    @_stepTitles[idx]
                </span>
            }
        </div>
    </div>

    <div class="wizard-body">
        @if (_loading)
        {
            <p class="loading">Loading flavours…</p>
        }
        else if (_error is not null)
        {
            <div class="error-panel">
                <p class="error">Couldn't load device profiles. Please reinstall SilverOS.</p>
                <p class="error-detail"><small>@_error</small></p>
                <button class="btn-secondary" @onclick="LoadFlavours">Retry</button>
            </div>
        }
        else
        {
            @switch (_currentStep)
            {
                case 0:
                    <WelcomeStep />
                    break;
                case 1:
                    <FlavourStep Flavours="_flavours" OnSelected="StateHasChanged" />
                    break;
                case 2:
                    <AppsStep Apps="_catalog.AppsForRole(State.Flavour?.Id ?? string.Empty)" />
                    break;
                case 3:
                    <PrefsStep />
                    break;
                case 4:
                    <ApplyStep AutoStart="_autoApply" OnComplete="AdvanceToDone" OnRunningChanged="@(v => { _applyRunning = v; StateHasChanged(); })" />
                    break;
                case 5:
                    <DoneStep />
                    break;
            }
        }
    </div>

    <div class="wizard-footer">
        <button class="btn-secondary"
                disabled="@(_currentStep == 0 || _applyRunning)"
                @onclick="Back">
            Back
        </button>
        @if (_currentStep < _stepTitles.Length - 1 && _currentStep != 4)
        {
            <button class="btn-primary"
                    disabled="@(!CanGoNext)"
                    @onclick="Next">
                @(_currentStep == _stepTitles.Length - 2 ? "Apply" : "Next")
            </button>
        }
        else if (_currentStep == _stepTitles.Length - 1)
        {
            <button class="btn-primary" @onclick="RestartNow">Restart now</button>
        }
    </div>
</div>
}

@code {
    private static readonly string[] _stepTitles = { "Welcome", "Flavour", "Apps", "Prefs", "Apply", "Done" };

    // Flavours dir: baked alongside the exe at publish time.
    private static readonly string FlavoursDir = Path.Combine(
        AppContext.BaseDirectory, "flavours");

    // Apps catalog dir: baked alongside the exe at publish time.
    private static readonly string AppsDir = Path.Combine(
        AppContext.BaseDirectory, "apps");

    private LoadedCatalog _catalog = new(Array.Empty<AppCatalogEntry>());

    private int _currentStep = 0;
    private bool _loading = true;
    private bool _applyRunning = false;
    private bool _toolboxHome = false;
    private bool _autoApply = false;
    private string? _error;
    private IReadOnlyList<FlavourManifest> _flavours = Array.Empty<FlavourManifest>();

    private async Task RestartNow()
    {
        await ProcessRunner.RunAsync("cmd.exe", "/c shutdown /r /t 5", default);
    }

    private bool CanGoNext => _currentStep switch
    {
        1 => State.Flavour is not null,
        // 2 = Apps step is always valid (never blocks Next).
        _ => true
    };

    protected override Task OnInitializedAsync()
    {
        LoadFlavours();
        SeedFromPreconfig();
        return Task.CompletedTask;
    }

    private Task LoadFlavours()
    {
        _error = null;
        _loading = true;
        try
        {
            _flavours = FlavourLoader.Load(FlavoursDir);
            _catalog = AppCatalog.Load(AppsDir);
        }
        catch (Exception ex)
        {
            _error = $"Failed to load flavours: {ex.Message}";
        }
        finally
        {
            _loading = false;
        }
        return Task.CompletedTask;
    }

    // Runs AFTER flavours + catalog are loaded (order matters): decides run-mode and,
    // on a first run, pre-seeds wizard state from the WinPE collector's choices.
    private void SeedFromPreconfig()
    {
        var pre = PreconfigStore.Load();

        if (PreconfigStore.IsConfigured())
        {
            // Already ran once -> open the minimal toolbox-home landing, never auto-apply.
            _toolboxHome = true;
            return;
        }

        if (pre is null)
            return; // fail-open: no preconfig -> normal wizard with flavour defaults.

        // Match the collector's flavour by id; fall back to the loaded default if absent.
        State.Flavour = _flavours.FirstOrDefault(f => f.Id == pre.Flavour)
                        ?? _flavours.FirstOrDefault(f => f.IsDefault)
                        ?? _flavours.FirstOrDefault();

        foreach (var id in _catalog.DefaultSelectionForRole(pre.Flavour))
            State.SelectedApps.Add(id);

        if (pre.Bitlocker.Enable && !string.IsNullOrEmpty(pre.Bitlocker.Pin))
            State.BitLockerPin = pre.Bitlocker.Pin;

        // First run with a preconfig: the collector already captured account + flavour, so
        // skip Welcome/Flavour and land on the Apps step (pre-checked with the flavour's
        // defaults) so the user can review/adjust the app selection before applying. From
        // there it's Apps -> Prefs -> Apply -> Done. (No auto-apply: the picker is the point.)
        _currentStep = 2;
    }

    private void ReRunSetup()
    {
        _toolboxHome = false;
        _currentStep = 0;
    }

    void Next()
    {
        if (_currentStep < _stepTitles.Length - 1)
            _currentStep++;

        // On entering the Apps step, seed the per-role default selection once.
        if (_currentStep == 2 && State.SelectedApps.Count == 0 && State.Flavour is not null)
            foreach (var id in _catalog.DefaultSelectionForRole(State.Flavour.Id))
                State.SelectedApps.Add(id);
    }

    void Back()
    {
        if (_currentStep > 0)
            _currentStep--;
    }

    void AdvanceToDone()
    {
        // Called by ApplyStep when configuration completes successfully.
        _currentStep = _stepTitles.Length - 1;
        StateHasChanged();
    }
}
