using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using iElection.Models;
using iElection.Models.Dto;
using iElection.Models.Entities;
using iElection.Services.Contracts;
using iElection.Utilities;
using iElection.Views;
using Refit;

namespace iElection.ViewModels
{
    public class MainPageViewModel : ViewModelBase<MainPageDto>
    {
        public ICommand AddNewContactCommand { get; set; }
        public ICommand SelectContactCommand { get; set; }
        public ICommand SelectNotificationCommand { get; set; }
        public ICommand ContactsRefreshCommand { get; set; }
        public ICommand ActivitiesRefreshCommand { get; set; }
        public ICommand ResomeRefreshCommand { get; set; }
        public ICommand NotificationsRefreshCommand { get; set; }
        public ICommand LogOutCommand { get; set; }
        public bool IsWorking { get; set; } = false;
        public bool IsContactsRefreshing { get; set; } = false;
        private bool isContactsRefreshing = false;
        public bool IsResomeRefreshing { get; set; } = false;
        private bool isResomeRefreshing = false;
        public bool IsActivityRefreshing { get; set; } = false;
        private bool isActivityRefreshing = false;
        public bool IsNotificationRefreshing { get; set; } = false;
        private bool isNotificationRefreshing = false;
        public string Text { get; set; }
        public string FullName { get; set; }
        public ObservableCollection<string> Images { get; set; } = new ObservableCollection<string>();
        public MainPageViewModel(INavigationService navigationService , IRestWrapper restWrapper)  : base(navigationService,restWrapper)
        {
        }

        public override async void Initialize(INavigationParameters parameters)
        {
            base.Initialize(parameters);
            try
            {
                if (IsWorking)
                    return;
                IsWorking = true;
                FullName = UtilitiesWrapper.Instance.UserUtilities.FullName;
                GetActivities();
                GetContacts();
                GetNotifications();
                await GetResome();

            }
            catch (ApiException e)
            {
                await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                RestWrapper.UnhandledExceptionRaiser(e,NavigationService);
            }
            catch (Exception e)
            {
                await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                UtilitiesWrapper.Instance.PopUpUtilities.PushError(e.Message);
            }
            finally
            {
                IsWorking = false;
            }
        }

        public async Task GetActivities()
        {
            try
            {
                if (isActivityRefreshing)
                    return;
                PageDto.Activities.Clear();
                isActivityRefreshing = true;
                var restActive = await RestWrapper.CrudApiRest<Activity, int>(Address.ActivityController)
                    .ReadAll(UtilitiesWrapper.Instance.UserUtilities.UserToken);
                if (restActive.IsSuccess)
                {
                    restActive.Data.ForEach(a => PageDto.Activities.Add(a));
                }

            }
            catch (ApiException e)
            {
                await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                RestWrapper.UnhandledExceptionRaiser(e, NavigationService);
            }
            catch (Exception e)
            {
                await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                UtilitiesWrapper.Instance.PopUpUtilities.PushError(e.Message);
            }
            finally
            {
                isActivityRefreshing = false;
                IsActivityRefreshing = false;
            }
        }
        public async Task GetResome()
        {
            try
            {
                if (isResomeRefreshing)
                    return;
                Images.Clear();
                isResomeRefreshing = true;
                var restCV = await RestWrapper.PageRestApi.GetInfoCv(UtilitiesWrapper.Instance.UserUtilities.UserToken);
                if (restCV.IsSuccess)
                {
                    Text = restCV.Data.Text;
                    restCV.Data.Images.ForEach(i => Images.Add(i));
                    Title = restCV.Data.Title;
                }

            }
            catch (ApiException e)
            {
                await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                RestWrapper.UnhandledExceptionRaiser(e, NavigationService);
            }
            catch (Exception e)
            {
                await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                UtilitiesWrapper.Instance.PopUpUtilities.PushError(e.Message);
            }
            finally
            {
                IsResomeRefreshing = false;
                isResomeRefreshing = false;
            }
        }
        public async Task GetNotifications()
        {
            try
            {
                if (isNotificationRefreshing)
                    return;
                PageDto.Notifications.Clear();
                isNotificationRefreshing = true;
                var rest = await RestWrapper.CrudApiRest<Notification, int>(Address.NotificationController)
                    .ReadAll(UtilitiesWrapper.Instance.UserUtilities.UserToken);
                if (rest.IsSuccess)
                    rest.Data.ForEach(n => PageDto.Notifications.Add(n));

            }
            catch (ApiException e)
            {
                await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                RestWrapper.UnhandledExceptionRaiser(e, NavigationService);
            }
            catch (Exception e)
            {
                await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                UtilitiesWrapper.Instance.PopUpUtilities.PushError(e.Message);
            }
            finally
            {
                isNotificationRefreshing = false;
                IsNotificationRefreshing = false;
            }
        }
        public async Task GetContacts()
        {
            try
            {
                if(isContactsRefreshing)
                    return;
                PageDto.Contacts.Clear();
                isContactsRefreshing = true;
                var restContact = await RestWrapper.CrudApiRest<Contact, int>(Address.ContactController)
                    .ReadAll(UtilitiesWrapper.Instance.UserUtilities.UserToken);
                if (restContact.IsSuccess)
                    restContact.Data.ForEach(c => PageDto.Contacts.Add(c));

            }
            catch (ApiException e)
            {
                await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                RestWrapper.UnhandledExceptionRaiser(e, NavigationService);
            }
            catch (Exception e)
            {
                await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                UtilitiesWrapper.Instance.PopUpUtilities.PushError(e.Message);
            }
            finally
            {
                isContactsRefreshing = false;
                IsContactsRefreshing = false;
            }
        }

        public override void InitializeCommand()
        {
            base.InitializeCommand();

            AddNewContactCommand = new DelegateCommand(() =>
            {
                NavigationService.NavigateAsync("AddContactPage");
            });
            SelectContactCommand = new DelegateCommand<Contact>(async (contact) =>
            {
                try
                {
                    UtilitiesWrapper.Instance.PopUpUtilities.PushIndicator();
                    var rest = await RestWrapper.CrudApiRest<Contact, int>(Address.ContactController)
                        .ReadOne(contact.Id, UtilitiesWrapper.Instance.UserUtilities.UserToken);
                    if (rest.IsSuccess)
                    {
                        await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                        var param = new NavigationParameters();
                        param.Add("Contact",new InviteContactDto
                        {
                            Age = rest.Data.Age,
                            District = rest.Data.District,
                            FirstName = rest.Data.FirstName,
                            LastName = rest.Data.LastName,
                            Job = rest.Data.Job,
                            Phone = rest.Data.Phone,
                            Gender = rest.Data.Gender!="مرد"?GenderType.Male:GenderType.Female
                        });
                        await NavigationService.NavigateAsync("AddContactPage", param);
                    }
                }
                catch (ApiException e)
                {
                    RestWrapper.UnhandledExceptionRaiser(e, NavigationService);
                }
                catch (Exception e)
                {
                    UtilitiesWrapper.Instance.PopUpUtilities.PushError(e.Message);
                }
            });
            SelectNotificationCommand = new DelegateCommand<Notification>(async (notify) =>
            {
                try
                {
                    UtilitiesWrapper.Instance.PopUpUtilities.PushIndicator();
                    var rest = await RestWrapper.CrudApiRest<Notification, int>(Address.NotificationController)
                        .ReadOne(notify.Id, UtilitiesWrapper.Instance.UserUtilities.UserToken);
                    if (rest.IsSuccess)
                    {
                        await UtilitiesWrapper.Instance.PopUpUtilities.PopAsync();
                        await UtilitiesWrapper.Instance.PopUpUtilities.PushAsync(new NotificationPopUp(rest.Data));
                    }
                }
                catch (ApiException e)
                {
                    RestWrapper.UnhandledExceptionRaiser(e, NavigationService);
                }
                catch (Exception e)
                {
                    UtilitiesWrapper.Instance.PopUpUtilities.PushError(e.Message);
                }
                
            });
            ContactsRefreshCommand = new DelegateCommand(async () => await GetContacts());
            NotificationsRefreshCommand = new DelegateCommand(async () => await GetNotifications());
            ActivitiesRefreshCommand = new DelegateCommand(async () => await GetActivities());
            ResomeRefreshCommand = new DelegateCommand(async () => await GetResome());
            LogOutCommand = new DelegateCommand(async () =>
            {
                UtilitiesWrapper.Instance.UserUtilities.LogOut();
                await NavigationService.NavigateAsync("myapp:///NavigationPage/LoginPage");
            });
        }
    }
}
