using System.Diagnostics;
using FrymasterBadgeApp.Services;
using Microsoft.Maui.Storage;

namespace FrymasterBadgeApp;

public partial class AppShell : Shell
{
    private readonly SqlService _db;
    private readonly PrinterService _printerService;
    private readonly IServiceProvider _serviceProvider;
    private bool _isInitialized = false;

/// <summary>
/// AppShell is a class that contains the initialization code for the app. It is responsible for
/// loading all companies in the background and then switching to the main thread to
/// update the UI.
/// </summary>
    public AppShell(SqlService db, PrinterService printerService, IServiceProvider serviceProvider)
    {
        InitializeComponent();
        _db = db;
        _printerService = printerService;
        _serviceProvider = serviceProvider;

        // Register pages that are NOT part of the TabBar permanently
        Routing.RegisterRoute(nameof(SettingsPage), typeof(SettingsPage));
        Routing.RegisterRoute(nameof(CompanyPage), typeof(CompanyPage));
        Routing.RegisterRoute(nameof(EmployeePage), typeof(EmployeePage));
    }

    protected override async void OnAppearing()
    {
        base.OnAppearing();

        // Using a small delay or ensuring initialization happens once
        if (!_isInitialized)
        {
            _isInitialized = true;
            await LoadCompaniesAsync();
        }
    }

/// <summary>
/// Loads all companies in the background and then switches to the main thread to update the UI.
/// </summary>
    private async Task LoadCompaniesAsync()
    {
        try
        {
            // 1. Fetch data in background
            AppLogger.Debug("AppShell: Fetching companies");
            var companies = await Task.Run(() => _db.Query("SELECT * FROM dbo.Companies", null));

            // 2. Switch to Main Thread for UI changes
            await MainThread.InvokeOnMainThreadAsync(async () =>
            {
                // Clear the "Loading" item
                MainTabBar.Items.Clear();

                if (companies == null || !companies.Any())
                {
                    MainTabBar.Items.Add(
                        new ShellContent
                        {
                            Title = "Setup",
                            Route = "InitialSetup",
                            ContentTemplate = new DataTemplate(() =>
                                _serviceProvider.GetRequiredService<CompanyPage>()
                            ),
                        }
                    );
                }
                else
                {
                    foreach (var company in companies)
                    {
                        var companyId = company.GetValueOrDefault("ID")?.ToString() ?? "0";
                        MainTabBar.Items.Add(
                            new ShellContent
                            {
                                Title = company.GetValueOrDefault("Name")?.ToString() ?? "Unknown",
                                Route = $"EmployeePage_{companyId}",
                                ContentTemplate = new DataTemplate(() =>
                                    new EmployeePage(_db, _printerService, company)
                                ),
                            }
                        );
                    }
                }

                // 3. Navigate away from the Loading page to the first real tab
                if (MainTabBar.Items.Count > 0)
                {
                    var targetRoute = MainTabBar.Items[0].Route;
                    // The "///" is critical—it tells Shell to rebuild the navigation stack
                    await Shell.Current.GoToAsync($"///{targetRoute}");
                }
            });
        }
        catch (Exception ex)
        {
            AppLogger.Error("AppShell: Error loading companies", ex);
            // Fallback: If DB fails, at least show the Company page
            await Shell.Current.GoToAsync($"///InitialSetup");
        }
    }

/// <summary>
/// Navigates to CompanyPage as a sub-page (pushed onto the stack).
    public async void OnManageCompaniesClicked(object sender, EventArgs e)
    {
        // Navigates to CompanyPage as a sub-page (pushed onto the stack)
        await Shell.Current.GoToAsync(nameof(CompanyPage));
    }

    private async void OnSettingsClicked(object sender, EventArgs e) =>
        await Shell.Current.GoToAsync(nameof(SettingsPage));

/// <summary>
/// Open a simple action sheet to choose theme globally
/// </summary>
/// <param name="sender">The object that triggered the event</param>
/// <param name="e">The event arguments</param>
    private async void OnThemeClicked(object sender, EventArgs e)
    {
        // Open a simple action sheet to choose theme globally
        string action = await Shell.Current.DisplayActionSheet("Select Theme", "Cancel", null, "System", "Light", "Dark");
        if (action == "Cancel" || string.IsNullOrEmpty(action))
            return;

        switch (action)
        {
            case "Light":
                Application.Current.UserAppTheme = AppTheme.Light;
                Preferences.Default.Set("AppTheme", "Light");
                break;
            case "Dark":
                Application.Current.UserAppTheme = AppTheme.Dark;
                Preferences.Default.Set("AppTheme", "Dark");
                break;
            default:
                Application.Current.UserAppTheme = AppTheme.Unspecified;
                Preferences.Default.Set("AppTheme", "System");
                break;
        }
    }

    private void OnExitClicked(object sender, EventArgs e) => Application.Current?.Quit();

/// <summary>
/// Open a simple action sheet to show the app's about page
/// </summary>
/// <param name="sender">The object that triggered the event</param>
/// <param name="e">The event arguments</param>
    private async void OnAboutClicked(object sender, EventArgs e) =>
        await DisplayAlert("About", "Frymaster Badge App v1.0", "OK");
}
