using CMSMicroservice.Protobuf.Protos.NetworkMembership;
using Google.Protobuf.WellKnownTypes;

namespace FrontOffice.Main.Utilities;

/// <summary>
/// Service for Network Membership operations
/// Connected to FrontOffice.BFF gRPC NetworkMembershipCQ
/// </summary>
public class NetworkMembershipService
{
    private readonly NetworkMembershipContract.NetworkMembershipContractClient _client;

    public NetworkMembershipService(NetworkMembershipContract.NetworkMembershipContractClient client)
    {
        _client = client;
    }

    /// <summary>
    /// Get current user's network tree
    /// Maps to: NetworkMembershipCQ.GetMyNetworkTree
    /// </summary>
    public async Task<NetworkTreeDto> GetMyNetworkTreeAsync(int maxDepth = 3)
    {
        try
        {
            var request = new GetMyNetworkTreeRequest { MaxDepth = maxDepth };
            var response = await _client.GetMyNetworkTreeAsync(request);
            
            return new NetworkTreeDto
            {
                RootNode = MapNodeFromProto(response.RootNode),
                TotalMembers = response.TotalMembers,
                CurrentDepth = response.CurrentDepth
            };
        }
        catch
        {
            // Return empty tree if backend is unavailable
            return new NetworkTreeDto
            {
                CurrentDepth = 0,
                TotalMembers = 0,
                RootNode = null
            };
        }
    }

    /// <summary>
    /// Get subordinate's network tree (with security check on backend)
    /// Maps to: NetworkMembershipCQ.GetSubordinateTree
    /// </summary>
    public async Task<NetworkTreeDto> GetSubordinateTreeAsync(long targetUserId, int maxDepth = 3)
    {
        try
        {
            var request = new GetSubordinateTreeRequest 
            { 
                TargetUserId = targetUserId,
                MaxDepth = maxDepth 
            };
            var response = await _client.GetSubordinateTreeAsync(request);
            
            return new NetworkTreeDto
            {
                RootNode = MapNodeFromProto(response.RootNode),
                TotalMembers = response.TotalMembers,
                CurrentDepth = response.CurrentDepth
            };
        }
        catch (Grpc.Core.RpcException ex) when (ex.StatusCode == Grpc.Core.StatusCode.PermissionDenied)
        {
            throw new UnauthorizedAccessException("شما اجازه مشاهده درخت این کاربر را ندارید");
        }
        catch
        {
            // Fallback to current user's tree
            return await GetMyNetworkTreeAsync(maxDepth);
        }
    }

    /// <summary>
    /// Get current user's network statistics
    /// Maps to: NetworkMembershipCQ.GetMyNetworkStatistics
    /// </summary>
    public async Task<NetworkStatisticsDto> GetMyNetworkStatisticsAsync()
    {
        try
        {
            var response = await _client.GetMyNetworkStatisticsAsync(new Empty());
            
            return new NetworkStatisticsDto
            {
                LeftLegCount = response.LeftLegCount,
                RightLegCount = response.RightLegCount,
                TotalMembers = response.TotalMembers,
                TreeDepth = response.MaxDepth,
                WeakerLeg = response.WeakerLeg,
                GoldLeftLegTotal = response.GoldLeftLegTotal,
                GoldRightLegTotal = response.GoldRightLegTotal,
                SilverLeftLegTotal = response.SilverLeftLegTotal,
                SilverRightLegTotal = response.SilverRightLegTotal,
                LastMember = response.LastMember != null ? new LastMemberDto
                {
                    UserId = response.LastMember.UserId,
                    FullName = response.LastMember.FullName,
                    Position = response.LastMember.Position,
                    JoinedAt = DateTime.Now // TODO: Add JoinedAt to proto
                } : null
            };
        }
        catch
        {
            // Return empty statistics if backend is unavailable
            return new NetworkStatisticsDto
            {
                LeftLegCount = 0,
                RightLegCount = 0,
                TotalMembers = 0,
                TreeDepth = 0,
                WeakerLeg = string.Empty,
                LastMember = null
            };
        }
    }

    #region Helper Methods

    private static NetworkNodeDto? MapNodeFromProto(NetworkTreeNodeModel? node)
    {
        if (node == null) return null;
        
        return new NetworkNodeDto
        {
            UserId = node.UserId,
            FullName = node.FullName,
            Mobile = node.Mobile,
            Avatar = node.Avatar,
            Position = node.Position,
            Level = node.Level,
            IsActive = node.IsActive,
            IsClubActive = node.IsClubActive,
            ReferralCode = node.ReferralCode,
            PackageName = string.IsNullOrWhiteSpace(node.PackageName) ? null : node.PackageName,
            GoldLeftLegTotal = node.GoldLeftLegTotal,
            GoldRightLegTotal = node.GoldRightLegTotal,
            SilverLeftLegTotal = node.SilverLeftLegTotal,
            SilverRightLegTotal = node.SilverRightLegTotal,
            ActivationWeekNumber = node.ActivationWeekDefinitionId?.ToString(),
            JoinedAt = node.JoinedAt?.ToDateTime(),
            LeftChild = MapNodeFromProto(node.LeftChild),
            RightChild = MapNodeFromProto(node.RightChild)
        };
    }

    #endregion
}
