using Common.Library;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using GreadyPoang.DataLayer;
using GreadyPoang.EntityLayer;
using GreadyPoang.Services;
using System.Collections.ObjectModel;
using System.Diagnostics;

namespace GreadyPoang.ViewModelLayer;

public partial class RoundStartingViewModel : ObservableObject
{
    #region Constructors
    public RoundStartingViewModel() : base()
    {

    }

    public RoundStartingViewModel(
        IRepository<GameRound> roundsRepo,
        IRepository<GamePoint> pointsRepo,
        IMethodSharingService<Participant> sharingService,
        ICombinedRepository combined,
        IObjectMessageService objectMessage) : base()
    {
        _roundsRepo = roundsRepo;
        _pointsRepo = pointsRepo;
        _sharingService = sharingService;
        _combined = combined;
        _objectMessage = objectMessage;
        RoundElements = new ObservableCollection<RoundBuilderElement>();
    }

    #endregion

    private readonly IRepository<GameRound>? _roundsRepo;
    private readonly IRepository<GamePoint> _pointsRepo;
    private readonly IMethodSharingService<Participant> _sharingService;
    private readonly ICombinedRepository _combined;
    private readonly IObjectMessageService _objectMessage;


    [ObservableProperty]
    private Participant selectedItem;
    partial void OnSelectedItemChanged(Participant value)
    {
        if (value != null)
        {
            OnItemSelected(value);
        }
    }

    [ObservableProperty]
    private ObservableCollection<RoundBuilderElement> roundElements;

    [ObservableProperty]
    private GameRound? gameRoundObject = new();

    [ObservableProperty]
    private ObservableCollection<RoundBuilderGroup> gameRoundList = new();

    [ObservableProperty]
    private ObservableCollection<Participant> participantList = new();


    private void OnItemSelected(Participant item)
    {
        if (RoundElements.Count == 0)
        {
            var GameRound = new GameRound
            {
                GameRoundStartDate = DateTime.Now,
                GameStatus = GamePointStatus.New,
                GameRoundFinished = null
            };
            var gameRoundId = _roundsRepo?.Save(GameRound).GetAwaiter().GetResult();
            if (gameRoundId != null && gameRoundId != -1)
            {
                GameRound.GameRoundId = gameRoundId.Value;
            }
            GameRoundObject = GameRound;
        }

        var GamePointStart = new GamePoint
        {
            ParticipantId = item.ParticipantId,
            GameRoundId = GameRoundObject?.GameRoundId ?? 0,
            GameDate = DateTime.Now,
            GameRoundRegNr = -1,
            GameRegPoints = 0
        };

        var gamePointId = _pointsRepo.Save(GamePointStart).GetAwaiter().GetResult();
        GamePointStart.GamePointId = gamePointId;

        var newElement = new RoundBuilderElement();
        newElement.ParticipantId = item.ParticipantId;
        newElement.ParticipantName = item.LastNameFirstName;
        newElement.GameRoundRegNr = GamePointStart.GameRoundRegNr;
        newElement.GameRegPoints = GamePointStart.GameRegPoints;
        newElement.Status = GameRoundObject!.GameStatus;
        newElement.GameRoundStartDate = GameRoundObject?.GameRoundStartDate ?? DateTime.Now;
        newElement.GameRoundId = GamePointStart.GameRoundId;
        newElement.GamePointId = GamePointStart.GamePointId;

        RoundElements.Add(newElement);
        // Gör något med det valda objektet
        Debug.WriteLine($"Du valde: {item.LastNameFirstName}");
    }



    #region Get Method
    public ObservableCollection<RoundBuilderGroup> Get()
    {
        if (_combined != null)
        {
            //            var GameRoundSummary = _combined.roundBuilderElements();
            var GameRoundSummary = _combined.roundBuilderElementsDb();

            var groupedRounds = GameRoundSummary
                    .GroupBy(r => r.GameRoundId)
                    .Select(g => new RoundBuilderGroup
                    {
                        GameRoundId = g.Key,
                        GameRoundStartDate = g.First().GameRoundStartDate,
                        Status = g.First().Status,
                        Elements = g.Select(p => new RoundBuilderElement
                        {
                            ParticipantId = p.ParticipantId,
                            ParticipantName = p.ParticipantName,
                            GamePointId = p.GamePointId,
                            GameRoundRegNr = p.GameRoundRegNr,
                            GameRegPoints = p.GameRegPoints,
                            GameRoundId = p.GameRoundId,
                            GameRoundStartDate = p.GameRoundStartDate,
                            Status = g.First().Status
                        }).ToList()
                    })
                    .ToList();



            GameRoundList = new ObservableCollection<RoundBuilderGroup>(groupedRounds);

        }
        return GameRoundList;
    }

    public ObservableCollection<Participant> GetParticipants()
    {
        ParticipantList = _sharingService.Get();
        return ParticipantList;
    }

    #endregion

    #region Get(id) Method
    public GameRound? Get(int id)
    {
        try
        {
            GameRoundObject = _roundsRepo?.Get(id).GetAwaiter().GetResult();
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine($"Error in Get method: {ex.Message}");
        }

        return GameRoundObject;
    }

    [RelayCommand]
    public async Task<bool> SaveAsync()
    {
        if (_roundsRepo == null || GameRoundObject == null)
        {
            return false;
        }
        var tmpTask = _roundsRepo.Save(GameRoundObject);
        bool tmp = tmpTask.GetAwaiter().GetResult() != -1;
        if (tmp)
        {
            GameRoundObject = new GameRound();
            RoundElements.Clear();
            this.Get();
            await Shell.Current.GoToAsync("..");
        }
        return tmp;
    }

    [RelayCommand]
    private async Task RensaAsync()
    {
        foreach (var element in RoundElements)
        {
            _pointsRepo.DeleteById(element.GamePointId);
        }
        _roundsRepo?.DeleteById(GameRoundObject?.GameRoundId ?? 0);
        RoundElements.Clear();
        await Shell.Current.GoToAsync("..");
    }

    [RelayCommand]
    public async Task RoundSelected(RoundBuilderElement element)
    {
        var rbGroup = GameRoundList.FirstOrDefault(g => g.GameRoundId == element.GameRoundId);
        Debug.WriteLine($"Du valde raden med Runda {element.GameRoundId} och spelare: {element.ParticipantName}");
        if (rbGroup != null)
        {
            _objectMessage.CurrentGroup = rbGroup;
            //await Shell.Current.GoToAsync("//RoundRunningView");
            await Shell.Current.GoToAsync("//RoundRunningView");
        }
    }

    [RelayCommand]
    public async Task<bool> SelectNewlyAddedParticipant(RoundBuilderElement roundBuilder)
    {
        bool goneOk = false;
        Debug.WriteLine($"Du valde raden med Runda {roundBuilder.GameRoundId} och spelare: {roundBuilder.ParticipantName}");
        goneOk = true;
        return goneOk;
    }

    #endregion

}
