using DiunaBI.UI.Shared.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using DiunaBI.Application.DTOModels.Common;
using DiunaBI.Domain.Entities;
using MudBlazor;
using Microsoft.JSInterop;

namespace DiunaBI.UI.Shared.Pages.Jobs;

public partial class Index : ComponentBase, IDisposable
{
    [Inject] private JobService JobService { get; set; } = default!;
    [Inject] private EntityChangeHubService HubService { get; set; } = default!;
    [Inject] private ISnackbar Snackbar { get; set; } = default!;
    [Inject] private NavigationManager NavigationManager { get; set; } = default!;
    [Inject] private IJSRuntime JSRuntime { get; set; } = default!;
    [Inject] private DateTimeHelper DateTimeHelper { get; set; } = default!;

    private PagedResult<QueueJob> jobs = new();
    private bool isLoading = false;
    private int currentPage = 1;
    private int pageSize = 50;
    private IEnumerable<JobStatus> selectedStatuses = new HashSet<JobStatus>();
    private JobType? selectedJobType = null;

    protected override async Task OnInitializedAsync()
    {
        await DateTimeHelper.InitializeAsync();
        await LoadJobs();

        // Subscribe to SignalR entity changes
        HubService.EntityChanged += OnEntityChanged;
    }

    private async void OnEntityChanged(string module, string id, string operation)
    {
        Console.WriteLine($"🔔 JobListComponent.OnEntityChanged called: module={module}, id={id}, operation={operation}");

        // Only react if it's a QueueJobs change
        if (module.Equals("QueueJobs", StringComparison.OrdinalIgnoreCase))
        {
            Console.WriteLine($"📨 Job {id} changed, refreshing job list");
            await InvokeAsync(async () =>
            {
                Console.WriteLine($"🔄 LoadJobs starting...");
                await LoadJobs();
                Console.WriteLine($"🔄 StateHasChanged calling...");
                StateHasChanged();
                Console.WriteLine($"✅ Job list refresh complete");
            });
        }
        else
        {
            Console.WriteLine($"⏭️ Skipping - module '{module}' is not QueueJobs");
        }
    }

    private async Task LoadJobs()
    {
        isLoading = true;

        try
        {
            var statusList = selectedStatuses?.ToList();
            jobs = await JobService.GetJobsAsync(currentPage, pageSize, statusList, selectedJobType);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Loading jobs failed: {ex.Message}");
            Snackbar.Add("Failed to load jobs", Severity.Error);
        }
        finally
        {
            isLoading = false;
        }
    }

    private async Task OnPageChanged(int page)
    {
        currentPage = page;
        await LoadJobs();
    }

    private async Task ClearFilters()
    {
        selectedStatuses = new HashSet<JobStatus>();
        selectedJobType = null;
        currentPage = 1;
        await LoadJobs();
    }

    private async Task OnStatusFilterChanged(IEnumerable<JobStatus> values)
    {
        selectedStatuses = values;
        currentPage = 1;
        await LoadJobs();
    }

    private async Task OnJobTypeFilterChanged(JobType? value)
    {
        selectedJobType = value;
        currentPage = 1;
        await LoadJobs();
    }

    private async Task OnStatusClear()
    {
        selectedStatuses = new HashSet<JobStatus>();
        currentPage = 1;
        await LoadJobs();
    }

    private async Task OnJobTypeClear()
    {
        selectedJobType = null;
        currentPage = 1;
        await LoadJobs();
    }

    private void OnRowClick(QueueJob job)
    {
        NavigationManager.NavigateTo($"/jobs/{job.Id}");
    }

    private async Task OnRowRightClick(MouseEventArgs e, QueueJob job)
    {
        var url = NavigationManager.ToAbsoluteUri($"/jobs/{job.Id}").ToString();
        await JSRuntime.InvokeVoidAsync("open", url, "_blank");
    }

    private async Task ScheduleJobs(string type)
    {
        isLoading = true;

        try
        {
            (bool success, int jobsCreated, string message) result = type switch
            {
                "all" => await JobService.ScheduleAllJobsAsync(),
                "imports" => await JobService.ScheduleImportJobsAsync(),
                "processes" => await JobService.ScheduleProcessJobsAsync(),
                _ => (false, 0, "Unknown job type")
            };

            if (result.success)
            {
                Snackbar.Add($"{result.message} ({result.jobsCreated} jobs created)", Severity.Success);
                await LoadJobs();
            }
            else
            {
                Snackbar.Add(result.message, Severity.Error);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Scheduling jobs failed: {ex.Message}");
            Snackbar.Add($"Failed to schedule jobs: {ex.Message}", Severity.Error);
        }
        finally
        {
            isLoading = false;
        }
    }

    private Color GetStatusColor(JobStatus status)
    {
        return status switch
        {
            JobStatus.Pending => Color.Default,
            JobStatus.Running => Color.Info,
            JobStatus.Completed => Color.Success,
            JobStatus.Failed => Color.Error,
            JobStatus.Retrying => Color.Warning,
            _ => Color.Default
        };
    }

    private Color GetJobTypeColor(JobType jobType)
    {
        return jobType switch
        {
            JobType.Import => Color.Primary,
            JobType.Process => Color.Secondary,
            _ => Color.Default
        };
    }

    public void Dispose()
    {
        HubService.EntityChanged -= OnEntityChanged;
    }
}
