using FrontOffice.Main.Utilities;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;

namespace FrontOffice.Main.Pages.Profile.Components;

public partial class OrganizationChart : IAsyncDisposable
{
    private NetworkTreeDto? _networkTree;
    private NetworkStatisticsDto? _statistics;
    private bool _isLoading = true;
    private bool _hasError = false;
    private int _selectedDepthValue = 3;
    private DotNetObjectReference<OrganizationChart>? _dotNetHelper;
    private bool _chartNeedsInit = false;
    private bool _jsReady = false;
    
    // برای نگهداری شناسه کاربر فعلی که درختش نمایش داده شده
    private long? _currentViewUserId = null;
    // Stack برای بازگشت به عقب
    private Stack<long> _navigationHistory = new();

    private int _selectedDepth
    {
        get => _selectedDepthValue;
        set
        {
            if (_selectedDepthValue != value)
            {
                _selectedDepthValue = value;
                _ = OnDepthChanged();
            }
        }
    }

    [Inject] private NetworkMembershipService NetworkService { get; set; } = default!;
    // JSRuntime is injected globally via _Imports.razor;

    protected override async Task OnInitializedAsync()
    {
        await LoadData();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _jsReady = true;
        }
        
        // Initialize chart after JS is ready and data is loaded
        if (_jsReady && _chartNeedsInit && _networkTree?.RootNode != null)
        {
            _chartNeedsInit = false;
            await InitializeChart();
        }
    }

    private async Task LoadData()
    {
        _isLoading = true;
        _hasError = false;
        StateHasChanged();

        try
        {
            // Load tree and statistics in parallel
            var treeTask = NetworkService.GetMyNetworkTreeAsync(_selectedDepth);
            var statsTask = NetworkService.GetMyNetworkStatisticsAsync();

            await Task.WhenAll(treeTask, statsTask);

            _networkTree = await treeTask;
            _statistics = await statsTask;
            
            // Mark that chart needs to be initialized
            _chartNeedsInit = true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error loading network data: {ex.Message}");
            _hasError = true;
        }
        finally
        {
            _isLoading = false;
            StateHasChanged();
        }
    }

    private async Task InitializeChart()
    {
        if (_networkTree?.RootNode == null) return;

        try
        {
            _dotNetHelper = DotNetObjectReference.Create(this);
            // Explicit camelCase mapping (same pattern as BackOffice admin chart)
            var flatData = _networkTree.ToFlatArray().Select(n => new
            {
                id = n.Id,
                parentId = n.ParentId,
                fullName = n.FullName,
                mobile = n.Mobile,
                avatar = n.Avatar,
                position = n.Position,
                level = n.Level,
                isActive = n.IsActive,
                isClubActive = n.IsClubActive,
                activationWeekNumber = n.ActivationWeekNumber,
                joinedAt = n.JoinedAt,
                referralCode = n.ReferralCode,
                packageName = n.PackageName ?? string.Empty
            }).ToArray();
            
            await JSRuntime.InvokeVoidAsync("OrgChart.init", "org-chart-container", flatData, _dotNetHelper);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error initializing chart: {ex.Message}");
        }
    }

    private async Task RefreshData()
    {
        await LoadData();
        
        if (_networkTree?.RootNode != null)
        {
            await InitializeChart();
        }
    }

    private async Task OnDepthChanged()
    {
        await RefreshData();
    }

    private async Task ExpandAll()
    {
        try
        {
            await JSRuntime.InvokeVoidAsync("OrgChart.expandAll");
        }
        catch { }
    }

    private async Task CollapseAll()
    {
        try
        {
            await JSRuntime.InvokeVoidAsync("OrgChart.collapseAll");
        }
        catch { }
    }

    private async Task CenterChart()
    {
        try
        {
            await JSRuntime.InvokeVoidAsync("OrgChart.center");
        }
        catch { }
    }

    private async Task FitToScreen()
    {
        try
        {
            await JSRuntime.InvokeVoidAsync("OrgChart.fitToScreen");
        }
        catch { }
    }

    private async Task ExportPng()
    {
        try
        {
            await JSRuntime.InvokeVoidAsync("OrgChart.exportPng");
        }
        catch { }
    }

    /// <summary>
    /// Called from JavaScript when a node is clicked
    /// </summary>
    [JSInvokable]
    public async Task OnNodeClicked(long userId)
    {
        // اگر روی همان نود کلیک شده، کاری نکن
        if (_currentViewUserId == userId) return;
        
        // ذخیره نود فعلی در history برای بازگشت
        if (_currentViewUserId.HasValue)
        {
            _navigationHistory.Push(_currentViewUserId.Value);
        }
        
        await LoadSubordinateTree(userId);
    }

    /// <summary>
    /// بارگذاری درخت یک زیرمجموعه
    /// </summary>
    private async Task LoadSubordinateTree(long targetUserId)
    {
        _isLoading = true;
        StateHasChanged();

        try
        {
            _networkTree = await NetworkService.GetSubordinateTreeAsync(targetUserId, _selectedDepth);
            _currentViewUserId = targetUserId;
            _chartNeedsInit = true;
        }
        catch (UnauthorizedAccessException)
        {
            // نمایش پیام خطا - این کاربر زیرمجموعه نیست
            Console.WriteLine("Unauthorized access to subordinate tree");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error loading subordinate tree: {ex.Message}");
        }
        finally
        {
            _isLoading = false;
            StateHasChanged();
        }
    }

    /// <summary>
    /// بازگشت به درخت قبلی
    /// </summary>
    private async Task GoBack()
    {
        if (_navigationHistory.Count > 0)
        {
            var previousUserId = _navigationHistory.Pop();
            await LoadSubordinateTree(previousUserId);
        }
        else
        {
            // بازگشت به درخت خود کاربر
            _currentViewUserId = null;
            await LoadData();
            if (_networkTree?.RootNode != null)
            {
                await InitializeChart();
            }
        }
    }

    /// <summary>
    /// بازگشت به درخت اصلی (خود کاربر)
    /// </summary>
    private async Task GoToMyTree()
    {
        _navigationHistory.Clear();
        _currentViewUserId = null;
        await LoadData();
        if (_networkTree?.RootNode != null)
        {
            await InitializeChart();
        }
    }

    public async ValueTask DisposeAsync()
    {
        try
        {
            await JSRuntime.InvokeVoidAsync("OrgChart.dispose");
        }
        catch { }

        _dotNetHelper?.Dispose();
    }
}