// <auto-generated/>
#pragma warning disable 1591
#pragma warning disable 0414
#pragma warning disable 0649
#pragma warning disable 0169

namespace SyncfusionSchedulerDeleteBug.Blazor.Server.Pages
{
    #line hidden
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Components;
#nullable restore
#line 1 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\_Imports.razor"
using System.Net.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\_Imports.razor"
using Microsoft.AspNetCore.Authorization;

#line default
#line hidden
#nullable disable
#nullable restore
#line 3 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\_Imports.razor"
using Microsoft.AspNetCore.Components.Authorization;

#line default
#line hidden
#nullable disable
#nullable restore
#line 4 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\_Imports.razor"
using Microsoft.AspNetCore.Components.Forms;

#line default
#line hidden
#nullable disable
#nullable restore
#line 5 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\_Imports.razor"
using Microsoft.AspNetCore.Components.Routing;

#line default
#line hidden
#nullable disable
#nullable restore
#line 6 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\_Imports.razor"
using Microsoft.AspNetCore.Components.Web;

#line default
#line hidden
#nullable disable
#nullable restore
#line 7 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\_Imports.razor"
using Microsoft.JSInterop;

#line default
#line hidden
#nullable disable
#nullable restore
#line 8 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\_Imports.razor"
using SyncfusionSchedulerDeleteBug.Blazor.Server;

#line default
#line hidden
#nullable disable
#nullable restore
#line 9 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\_Imports.razor"
using SyncfusionSchedulerDeleteBug.Blazor.Server.Shared;

#line default
#line hidden
#nullable disable
#nullable restore
#line 10 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\_Imports.razor"
using SyncfusionSchedulerDeleteBug.Blazor.Server.Components;

#line default
#line hidden
#nullable disable
#nullable restore
#line 3 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\Pages\Calendar.razor"
using Syncfusion.Blazor.Schedule;

#line default
#line hidden
#nullable disable
#nullable restore
#line 4 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\Pages\Calendar.razor"
using Syncfusion.Blazor.Navigations;

#line default
#line hidden
#nullable disable
#nullable restore
#line 6 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\Pages\Calendar.razor"
using SyncfusionSchedulerDeleteBug.Business.Events;

#line default
#line hidden
#nullable disable
#nullable restore
#line 7 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\Pages\Calendar.razor"
using SyncfusionSchedulerDeleteBug.Blazor.Server.Data;

#line default
#line hidden
#nullable disable
#nullable restore
#line 8 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\Pages\Calendar.razor"
using SyncfusionSchedulerDeleteBug.Blazor.Server.Components.Scheduler;

#line default
#line hidden
#nullable disable
#nullable restore
#line 10 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\Pages\Calendar.razor"
using Csla.Blazor;

#line default
#line hidden
#nullable disable
#nullable restore
#line 11 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\Pages\Calendar.razor"
using Csla;

#line default
#line hidden
#nullable disable
#nullable restore
#line 13 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\Pages\Calendar.razor"
using Microsoft.Extensions.Logging;

#line default
#line hidden
#nullable disable
    [Microsoft.AspNetCore.Components.RouteAttribute("/calendar")]
    public partial class Calendar : Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
        }
        #pragma warning restore 1998
#nullable restore
#line 175 "D:\src\PTCalendar - Copy\SyncfusionSchedulerDeleteBug.BlazorServer\Pages\Calendar.razor"
 
        #region properties

    private CalendarEventEditDialog editDialog;

    private SfSchedule<CalendarEventInfo> ScheduleRef;
    private View CurrentView { get; set; }

    private DateTime DefaultDate { get; set; }
    private DateTime CurrentDate { get; set; }

    private DateTime CurrentViewFrom { get; set; }
    private DateTime CurrentViewTo { get; set; }
    private List<CalendarEventInfo> CurrentViewEvents { get; set; }

    public string[] GroupData = new string[] { "Projects", "Workers" };

    private bool RefreshChildren { get; set; }

    private List<ProjectData> Projects { get; set; }
    private List<UserProjectData> Workers { get; set; }

    private TimeSpan? UserOffset;

    [CascadingParameter]
    public Error Error { get; set; }

    private bool CanCreate { get; set; }
    private bool CanEdit { get; set; }
    private bool CanDelete { get; set; }

    #endregion

    #region code behind only

    #region lifecycle

    protected override async Task OnInitializedAsync()
    {
        CanCreate = true;
        CanEdit = true;
        CanDelete = true;

        CurrentView = View.TimelineMonth;

        DefaultDate = DateTime.Today;
        CurrentDate = DateTime.Today;
        CurrentViewFrom = new DateTime(CurrentDate.Year, CurrentDate.Month, CurrentDate.Day);
        CurrentViewTo = new DateTime(CurrentDate.Year, CurrentDate.Month, DateTime.DaysInMonth(CurrentDate.Year, CurrentDate.Month));

        Projects = new List<ProjectData>();
        Workers = new List<UserProjectData>();

        await RefreshEvents();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            //do not bind before render
            eventsViewModel.ModelChanging += async (o, n) => { await OnModelChanging(o, n); };
            await tzService.ApplyOffset(eventsViewModel.Model);
            RefreshCurrentViewEvents(eventsViewModel.Model);
        }

        RefreshChildren = false; //block refresh until event is saved
    }

    #endregion

    private async Task RefreshEvents()
    {
        DateRangeCriteria dates = new DateRangeCriteria(CurrentDate.AddYears(-1), CurrentDate.AddYears(+1));

        try
        {
            await eventsViewModel.RefreshAsync(() => DataPortal.FetchAsync<CalendarEventsList>(dates));
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Unable to refresh events due to an error");
        }
    }

    private async Task OnModelChanging(CalendarEventsList oldModel, CalendarEventsList newModel)
    {
        await tzService.ApplyOffset(newModel);

        RefreshCurrentViewEvents(newModel);
    }

    private void ReadCurrentViewDates()
    {
        try
        {
            //read from scheduler control
            var currentViewDates = ScheduleRef.GetCurrentViewDates();

            CurrentViewFrom = currentViewDates.Min();
            CurrentViewTo = currentViewDates.Max();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Unable to read current view dates due to an error");
        }
    }

    private void RefreshCurrentViewEvents(CalendarEventsList events)
    {
        if (events is null)
            return;

        try
        {
            CurrentViewEvents = events.GetEventsForRange(CurrentViewFrom, CurrentViewTo);

            RefreshProjectsGroup(CurrentViewEvents);
            RefreshWorkersGroup(CurrentViewEvents);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Unable to refresh current view events due to an error");
        }

        StateHasChanged();
    }

    private void RefreshProjectsGroup(IList<CalendarEventInfo> events)
    {
        try
        {
            Projects = (from e in events.GroupBy(x => new { x.ProjectId, x.ProjectName })
                        select new ProjectData()
                        {
                            ProjectId = e.Key.ProjectId,
                            ProjectName = e.Key.ProjectName
                        }).OrderBy(x => x.ProjectName).ToList();

        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Unable to refresh projects group due to an error");
        }
    }

    private void RefreshWorkersGroup(IList<CalendarEventInfo> events)
    {
        try
        {
            Workers = (from e in events.GroupBy(x => new { x.WorkerId, x.WorkersFullName, x.CompanyId, x.ProjectId, x.ProjectName, x.CompanyName, x.CountryId, x.Country })
                       select new UserProjectData()
                       {
                           ProjectId = e.Key.ProjectId,
                           WorkerId = e.Key.WorkerId,
                           WorkerName = e.Key.WorkersFullName,
                           CompanyId = e.Key.CompanyId,
                           CompanyName = e.Key.CompanyName,
                           ProjectName = e.Key.ProjectName,
                           CountryId = e.Key.CountryId,
                           Country = e.Key.Country
                       }).OrderBy(x => x.WorkerName).ToList();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Unable to refresh workers group due to an error");
        }
    }

    #endregion


    #region scheduler

    public void OnActionBegin(ActionEventArgs<CalendarEventInfo> args)
    {
        switch (args.ActionType)
        {

            case ActionType.EventRemove:
                //never gets here anymore

                break;
        }
    }

    public void OnActionComplete(ActionEventArgs<CalendarEventInfo> args)
    {
        switch (args.ActionType)
        {
            case ActionType.EventRemove:

                //never gets here anymore
                if (!CanDelete)
                    return;

                var deleted = args.DeletedRecords;
                var changed = args.ChangedRecords;

                scheduleController.EventDelete(deleted, changed);
                break;

            default:
                break;

        }
    }

    public async Task OnPopupOpen(PopupOpenEventArgs<CalendarEventInfo> args)
    {
        if (args.Type == PopupType.QuickInfo)
        {
            if (args.Data.Id == 0)
                args.Cancel = true; //do not show the quick info form for a new event
        }
        else if (args.Type == PopupType.Editor)
        {
            args.Cancel = true;

            if (args.Data.Id == 0)
            {
                await CreateEvent(args.Data);
            }
            else
            {
                CurrentAction action = ScheduleRef.GetCurrentAction();
                switch (action)
                {
                    case CurrentAction.EditOccurrence:
                        await EditOccurence(args.Data.Id, args.Data.StartTime);
                        break;
                    default:
                        await EditEvent(args.Data.Id);
                        break;
                }
            }
        }
        else if(args.Type == PopupType.RecurrenceAlert)
        {
            if (!CanEdit)
                args.Cancel = true;
        }
    }

    private async Task EditEvent(int eventId)
    {
        if (!CanEdit)
            return;

        await editDialog.Edit(eventId);
    }

    private async Task EditOccurence(int eventId, DateTime occurenceDate)
    {
        if (!CanEdit)
            return;

        await editDialog.EditOccurence(eventId, occurenceDate);
    }

    private async Task CreateEvent(CalendarEventInfo data)
    {
        if (!CanCreate)
            return;

        //each workerid/projectid combo should be unique, set the default company id for a new event accordingly
        UserProjectData project = Workers.Where(x => x.WorkerId == data.WorkerId && x.ProjectId == data.ProjectId).FirstOrDefault();

        if (project is null)
            return; //what will this do?
        else
        {
            data.CompanyId = project.CompanyId;
            data.CountryId = project.CountryId;
        }

        var start = DateTime.Now;
        var end = DateTime.Now;

        CalendarEventCreateCriteria criteria = new CalendarEventCreateCriteria()
        {
            WorkerId = data.WorkerId,
            CompanyId = data.CompanyId,
            ProjectId = data.ProjectId,
            CountryId = data.CountryId,
            StartDate = start,
            EndDate = end
        };

        await editDialog.Create(criteria);
    }

    public void OnDragged(Syncfusion.Blazor.Schedule.DragEventArgs<CalendarEventInfo> args)
    {
        CalendarEventInfo item = args.Data;
        //CalendarEventEdit savedItem = DataPortal.Fetch<CalendarEventEdit>(item.Id);
        //if (savedItem.WorkerId != item.WorkerId || savedItem.ProjectId != item.ProjectId)
        //{
        //    args.Cancel = true;
        //}
    }

    private async void EventSaved(int eventId)
    {
        await RefreshEvents();

        RefreshChildren = true;

        StateHasChanged();
    }

    #endregion

    #region toolbar

    public async Task AddEventClick(ClickEventArgs args)
    {
        var start = DateTime.Now;
        var end = DateTime.Now;

        await editDialog.Create(start, end);
    }

    #endregion


#line default
#line hidden
#nullable disable
        [global::Microsoft.AspNetCore.Components.InjectAttribute] private ILogger<Calendar> logger { get; set; }
        [global::Microsoft.AspNetCore.Components.InjectAttribute] private TimeZoneService tzService { get; set; }
        [global::Microsoft.AspNetCore.Components.InjectAttribute] private ScheduleController scheduleController { get; set; }
        [global::Microsoft.AspNetCore.Components.InjectAttribute] private ViewModel<CalendarEventsList> eventsViewModel { get; set; }
    }
}
#pragma warning restore 1591
