using LightlessSync.API.Dto.Group;
using Microsoft.Extensions.Logging;

namespace LightlessSync.PlayerData.Pairs;

/// <summary>
///     handles group related pair events
/// </summary>
public sealed partial class PairCoordinator
{
    public void HandleGroupChangePermissions(GroupPermissionDto dto)
    {
        var result = _pairManager.UpdateGroupPermissions(dto);
        if (!result.Success)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("Failed to update permissions for group {GroupId}: {Error}", dto.Group.GID, result.Error);
            }
            return;
        }

        PublishPairDataChanged(groupChanged: true);
    }

    public void HandleGroupFullInfo(GroupFullInfoDto dto)
    {
        var result = _pairManager.AddGroup(dto);
        if (!result.Success && _logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("Failed to add group {GroupId}: {Error}", dto.Group.GID, result.Error);
            return;
        }

        PublishPairDataChanged(groupChanged: true);
    }

    public void HandleGroupPairJoined(GroupPairFullInfoDto dto)
    {
        var result = _pairManager.AddOrUpdateGroupPair(dto);
        if (!result.Success && _logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("Failed to add group pair {Uid}/{Group}: {Error}", dto.User.UID, dto.Group.GID, result.Error);
            return;
        }

        PublishPairDataChanged(groupChanged: true);
    }

    public void HandleGroupPairLeft(GroupPairDto dto)
    {
        var deregistration = _pairManager.RemoveGroupPair(dto);
        if (deregistration.Success && deregistration.Value is { } registration && registration.CharacterIdent is not null)
        {
            _ = _handlerRegistry.DeregisterOfflinePair(registration, forceDisposal: true);
        }
        else if (!deregistration.Success && _logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("RemoveGroupPair failed for {Uid}: {Error}", dto.User.UID, deregistration.Error);
        }

        if (deregistration.Success)
        {
            PublishPairDataChanged(groupChanged: true);
        }
    }

    public void HandleGroupRemoved(GroupDto dto)
    {
        var removalResult = _pairManager.RemoveGroup(dto.Group.GID);
        if (removalResult.Success)
        {
            foreach (var registration in removalResult.Value)
            {
                if (registration.CharacterIdent is not null)
                {
                    _ = _handlerRegistry.DeregisterOfflinePair(registration, forceDisposal: true);
                }
            }
        }
        else if (_logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("Failed to remove group {Group}: {Error}", dto.Group.GID, removalResult.Error);
        }

        if (removalResult.Success)
        {
            PublishPairDataChanged(groupChanged: true);
        }
    }

    public void HandleGroupInfoUpdate(GroupInfoDto dto)
    {
        var result = _pairManager.UpdateGroupInfo(dto);
        if (!result.Success && _logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("Failed to update group info for {Group}: {Error}", dto.Group.GID, result.Error);
            return;
        }

        PublishPairDataChanged(groupChanged: true);
    }

    public void HandleGroupPairPermissions(GroupPairUserPermissionDto dto)
    {
        var result = _pairManager.UpdateGroupPairPermissions(dto);
        if (!result.Success && _logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("Failed to update group pair permissions for {Group}: {Error}", dto.Group.GID, result.Error);
            return;
        }

        PublishPairDataChanged(groupChanged: true);
    }

    public void HandleGroupPairStatus(GroupPairUserInfoDto dto, bool isSelf)
    {
        PairOperationResult result;
        if (isSelf)
        {
            result = _pairManager.UpdateGroupStatus(dto);
        }
        else
        {
            result = _pairManager.UpdateGroupPairStatus(dto);
        }

        if (!result.Success && _logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("Failed to update group status for {Group}:{Uid}: {Error}", dto.GID, dto.UID, result.Error);
            return;
        }

        PublishPairDataChanged(groupChanged: true);
    }
}
