using Common.Library;
using Gready_Poang.DataLayer;
using Gready_Poang.EntityLayer;
using Gready_Poang.Services;
using System.Collections.ObjectModel;
using System.Diagnostics;

namespace Gready_Poang.ViewModelLayer;

public class RoundStartingViewModel : ViewModelBase
{
    #region Constructors
    public RoundStartingViewModel() : base()
    {
    }

    public RoundStartingViewModel(
        IRepository<GameRound> roundsRepo,
        IRepository<GamePoint> pointsRepo,
        IMethodSharingService<Participant> sharingService,
        ICombinedRepository combined,
        IObjectMessageService objectMessage,
        //INavigationService nav,
        //IPageFactory factory,
        //ISplashService splashService,
        AppShellViewModel appShellView
        ) : base()
    {
        _roundsRepo = roundsRepo;
        _pointsRepo = pointsRepo;
        _sharingService = sharingService;
        _combined = combined;
        _objectMessage = objectMessage;
        //_nav = nav;
        //_factory = factory;
        //_splashService = splashService;
        _appShellView = appShellView;
        _roundElements = new ObservableCollection<RoundBuilderElement>();
    }

    #endregion

    private GameRound? _GameRoundObject = new();
    private ObservableCollection<RoundBuilderGroup> _GameRoundList = new();
    private ObservableCollection<Participant> _ParticipantList = new();
    private readonly IRepository<GameRound>? _roundsRepo;
    private readonly IRepository<GamePoint> _pointsRepo;
    private readonly IMethodSharingService<Participant> _sharingService;
    private readonly ICombinedRepository _combined;
    private readonly IObjectMessageService _objectMessage;
    //private readonly INavigationService _nav;
    //private readonly IPageFactory _factory;
    //private readonly ISplashService _splashService;
    private readonly AppShellViewModel _appShellView;
    private Participant _selectedItem;

    private ObservableCollection<RoundBuilderElement> _roundElements;

    public ObservableCollection<RoundBuilderElement> RoundElements
    {
        get { return _roundElements; }
        set
        {
            _roundElements = value;
            RaisePropertyChanged(nameof(RoundElements));
        }
    }


    public Participant SelectedItem
    {
        get => _selectedItem;
        set
        {
            if (_selectedItem != value)
            {

                _selectedItem = value;
                RaisePropertyChanged(nameof(SelectedItem));
                OnItemSelected(value); // Metod som triggas vid val
            }
        }
    }

    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}");
    }


    public GameRound? GameRoundObject
    {
        get { return _GameRoundObject; }
        set
        {
            _GameRoundObject = value;
            RaisePropertyChanged(nameof(GameRoundObject));
        }
    }

    public ObservableCollection<RoundBuilderGroup> GameRoundList
    {
        get { return _GameRoundList; }
        set
        {
            _GameRoundList = value;
            RaisePropertyChanged(nameof(GameRoundList));
        }
    }

    public ObservableCollection<Participant> ParticipantList
    {
        get { return _ParticipantList; }
        set
        {
            _ParticipantList = value;
            RaisePropertyChanged(nameof(ParticipantList));
        }
    }

    #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;
    }
    public virtual bool Save()
    {
        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();
        }
        return tmp;
    }

    public void Rensa()
    {
        foreach (var element in RoundElements)
        {
            _pointsRepo.DeleteById(element.GamePointId);
        }
        _roundsRepo?.DeleteById(GameRoundObject?.GameRoundId ?? 0);
        RoundElements.Clear();
    }

    public async void 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;
            _objectMessage.Delivered = true;
            await Shell.Current.GoToAsync("RoundRunningView");

            _appShellView.RoundRunningVisible = false;

        }
    }


    public void SelectNewlyAddedParticipant(RoundBuilderElement roundBuilder)
    {
        Debug.WriteLine($"Du valde raden med Runda {roundBuilder.GameRoundId} och spelare: {roundBuilder.ParticipantName}");
    }

    #endregion

}
