using Client.DataStructures;
using Client.Helpers;
using Client.ISServiceRef;
using Client.View;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using WpfAsyncPack.Command;

namespace Client.ViewModel
{
    public class InfoPanelViewModel : ViewModelBase
    {

        public ObservableCollection<RequestDto> Requests { get; set; }
        public ObservableCollection<PersonalEventDto> PersonalEvents { get; set; }

        public ICommand ShowRequestDetailCommand { get; set; }
        public ICommand ShowPersonalEventDetailCommand { get; set; }
        
        public int RequestsCount { get; set; }
        public int PersonalEventsCount { get; set; }
        public double WorkedHours { get; set; }

        public string UnprocessedRequestsText { get; set; }
        public string PersonalRequestsText { get; set; }

        public InfoPanelViewModel()
        {
            #region clientSetup
            _requestClient.ClientCredentials.UserName.UserName = UserManager.Instance.CurrentUser.Login;
            _requestClient.ClientCredentials.UserName.Password = UserManager.Instance.CurrentUser.Password;
            _requestClient.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;

            _attendanceRecordServiceClient.ClientCredentials.UserName.UserName = UserManager.Instance.CurrentUser.Login;
            _attendanceRecordServiceClient.ClientCredentials.UserName.Password = UserManager.Instance.CurrentUser.Password;
            _attendanceRecordServiceClient.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;

            _personalEventClient.ClientCredentials.UserName.UserName = UserManager.Instance.CurrentUser.Login;
            _personalEventClient.ClientCredentials.UserName.Password = UserManager.Instance.CurrentUser.Password;
            _personalEventClient.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
            #endregion clientSetup

            Task.Run(async () =>
            {
                await LoadRequestsAsync();
                await LoadPersonalEventsAsync();
                await CalculateWorkHours();
            });

            ShowRequestDetailCommand = new AsyncCommand<RequestDto>(ShowRequestDetailAsync);
            ShowPersonalEventDetailCommand = new AsyncCommand<PersonalEventDto>(ShowPersonalEventDetailAsync);
        }

        private async Task LoadRequestsAsync()
        {
            var filterDto = BuildRequestFilter();
            var attendanceRecords = await _requestClient.GetRequestsAsync(filterDto);
            Requests = new ObservableCollection<RequestDto>(attendanceRecords);
            RequestsCount = Requests.Count;

            UnprocessedRequestsText = RequestsCount > 0 ? Properties.Resources.RequestsAny : Properties.Resources.RequestsNone;
        }

        private async Task LoadPersonalEventsAsync()
        {
            var filterDto = BuildPersonalEventFilter();
            var personalEvents = await _personalEventClient.GetPersonalEventsAsync(filterDto);
            PersonalEvents = new ObservableCollection<PersonalEventDto>(personalEvents);
            PersonalEventsCount = PersonalEvents.Count;

            PersonalRequestsText = PersonalEventsCount > 0 ? Properties.Resources.PersonalEventsAny : Properties.Resources.PersonalEventsNone;

        }

        private async Task CalculateWorkHours()
        {
            var attendanceRecords = await _attendanceRecordServiceClient.GetAttendanceRecordsAsync(BuildAttendanceFilter());

            var monthlyAttendanceData = new MonthlyAttendanceData()
            {
                AttendanceRecords = attendanceRecords
            };

            var statisticsViewModel = new AttendanceStatisticsViewModel(monthlyAttendanceData, false);
            WorkedHours = Math.Round(statisticsViewModel.TotalHours - statisticsViewModel.LunchBreakHours, 1);
        }

        private async Task ShowRequestDetailAsync(RequestDto selectedRequest)
        {
            if (selectedRequest == null) return;

            var detailView = new RequestDetailView(selectedRequest);
            detailView.ShowDialog();
            await LoadRequestsAsync();
        }

        private async Task ShowPersonalEventDetailAsync(PersonalEventDto selectedPersonalEvent)
        {
            if (selectedPersonalEvent == null) return;

            var detailView = new PersonalEventDetailView(selectedPersonalEvent);
            detailView.ShowDialog();
            await LoadPersonalEventsAsync();
        }

        private FilterDto BuildRequestFilter()
        {
            var filter = new FilterDto()
            {
                Conditions = new List<ConditionItemDto>()
                 {
                      new ConditionItemDto()
                      {
                           Column = nameof(RequestDto.SupervisorId),
                           Type = ConditionTypeEnum.Equal,
                           Value = UserManager.Instance.CurrentUser.Id.ToString()
                      },
                      new ConditionItemDto()
                      {
                           Column = nameof(RequestDto.RequestState),
                           Type = ConditionTypeEnum.Equal,
                           Value = RequestState.Waiting.ToString()
                      },
                 },
                Sorting = new List<SortingItemDto>()
                 {
                      new SortingItemDto()
                      {
                           Ascending = false,
                           Column = nameof(RequestDto.TimeStamp),
                      }
                 }
            };

            return filter;
        }

        private FilterDto BuildPersonalEventFilter()
        {
            int diff = (7 + (DateTime.Now.DayOfWeek - DayOfWeek.Monday)) % 7;
            var from = DateTime.Now.AddDays(-1 * diff).Date;
            var to = from.AddDays(7);

            var filter = new FilterDto()
            {
                Conditions = new List<ConditionItemDto>()
                 {
                      new ConditionItemDto()
                      {
                           Column = nameof(PersonalEventDto.EmployeeId),
                           Type = ConditionTypeEnum.Equal,
                           Value = UserManager.Instance.CurrentUser.Id.ToString()
                      },
                      new ConditionItemDto()
                      {
                           Column = nameof(PersonalEventDto.DateTime),
                           Type = ConditionTypeEnum.GreaterOrEqual,
                           Value = from.ToString("yyyy-MM-dd HH:mm:ss.fff")
                      },
                      new ConditionItemDto()
                      {
                           Column = nameof(PersonalEventDto.DateTime),
                           Type = ConditionTypeEnum.LessOrEqual,
                           Value = to.ToString("yyyy-MM-dd HH:mm:ss.fff")
                      },
                },
                Sorting = new List<SortingItemDto>()
                 {
                      new SortingItemDto()
                      {
                           Ascending = false,
                           Column = nameof(PersonalEventDto.DateTime),
                      }
                 }
            };

            return filter;
        }

        private FilterDto BuildAttendanceFilter()
        {

            DateTime from = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            var lastDayOfMonth = from.AddMonths(1).AddDays(-1);
            DateTime to = new DateTime(DateTime.Now.Year, DateTime.Now.Month, lastDayOfMonth.Day, 23, 59, 59);

            var filter = new FilterDto()
            {
                Conditions = new List<ConditionItemDto>()
                {
                      new ConditionItemDto()
                      {
                           Column = nameof(AttendanceRecordDto.EmployeeId),
                           Type = ConditionTypeEnum.Equal,
                           Value = UserManager.Instance.CurrentUser.Id.ToString()
                      },
                      new ConditionItemDto()
                      {
                           Column = nameof(AttendanceRecordDto.TimeStamp),
                           Type = ConditionTypeEnum.GreaterOrEqual,
                           Value = from.ToString("yyyy-MM-dd HH:mm:ss.fff")
                      },
                      new ConditionItemDto()
                      {
                           Column = nameof(AttendanceRecordDto.TimeStamp),
                           Type = ConditionTypeEnum.LessOrEqual,
                           Value = to.ToString("yyyy-MM-dd HH:mm:ss.fff")
                      }
                },
                Sorting = new List<SortingItemDto>()
                {
                      new SortingItemDto()
                      {
                           Ascending = false,
                           Column = nameof(AttendanceRecordDto.TimeStamp),
                      }
                }
            };

            return filter;
        }

        RequestServiceClient _requestClient = new RequestServiceClient();
        PersonalEventServiceClient _personalEventClient = new PersonalEventServiceClient();
        AttendanceRecordServiceClient _attendanceRecordServiceClient = new AttendanceRecordServiceClient();

    }
}
