@inject DialogService DialogService

<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0.5rem" class="rz-p-4 rz-mb-6 rz-border-radius-1" Style="border: var(--rz-grid-cell-border);height:4rem;">
    <RadzenLabel Text="Number of days to view:" />
    <RadzenSlider @bind-Value=@sliderNumberOfDays TValue="int" Min="1" Max="14" Style="margin-left:1.5rem;margin-right:1.5rem;" Change="NumberOfDaysChange" />
    <RadzenLabel Text="@($"{sliderNumberOfDays}")" />
    @if(sliderNumberOfDays==2)
    {
        <RadzenText TextStyle="TextStyle.Caption" Text="@($"(default)")" Style="margin-left:0.1rem;margin-top:0.5rem;" />
    }
    <div class="rz-w-25" />
    <RadzenLabel Text="Advance days:" />
    <RadzenSlider @bind-Value=@sliderAdvanceDays TValue="int" Min="1" Max="14" Style="margin-left:1.5rem;margin-right:1.5rem;" />
    <RadzenLabel Text="@($"{sliderAdvanceDays}")" />
    @if (sliderAdvanceDays == 1)
    {
        <RadzenText TextStyle="TextStyle.Caption" Text="@($"(default)")" Style="margin-left:0.1rem;margin-top:0.5rem;" />
    }
</RadzenStack>

<RadzenScheduler @ref=@scheduler SlotRender=@OnSlotRender style="height: 768px;" TItem="Appointment" Data=@appointments StartProperty="Start" EndProperty="End"
TextProperty="Text" SelectedIndex="2"
SlotSelect=@OnSlotSelect AppointmentSelect=@OnAppointmentSelect AppointmentRender=@OnAppointmentRender
AppointmentMove=@OnAppointmentMove >
    <RadzenDayView />
    <RadzenWeekView />
    <RadzenMultiDayView NumberOfDays="@sliderNumberOfDays" AdvanceDays="@sliderAdvanceDays" />
    <RadzenMonthView />
</RadzenScheduler>

<EventConsole @ref=@console />

@code {
    RadzenScheduler<Appointment> scheduler;
    EventConsole console;
    Dictionary<DateTime, string> events = new Dictionary<DateTime, string>();

    int sliderNumberOfDays { get; set; } = 2;
    int sliderAdvanceDays { get; set; } = 1;

    IList<Appointment> appointments = new List<Appointment>
    {
        new Appointment { Start = DateTime.Today.AddDays(-2), End = DateTime.Today.AddDays(-2), Text = "Birthday" },
        new Appointment { Start = DateTime.Today.AddDays(-11), End = DateTime.Today.AddDays(-10), Text = "Day off" },
        new Appointment { Start = DateTime.Today.AddDays(-10), End = DateTime.Today.AddDays(-8), Text = "Work from home" },
        new Appointment { Start = DateTime.Today.AddHours(10), End = DateTime.Today.AddHours(12), Text = "Online meeting" },
        new Appointment { Start = DateTime.Today.AddHours(10), End = DateTime.Today.AddHours(13), Text = "Skype call" },
        new Appointment { Start = DateTime.Today.AddHours(14), End = DateTime.Today.AddHours(14).AddMinutes(30), Text = "Dentist appointment" },
        new Appointment { Start = DateTime.Today.AddDays(1), End = DateTime.Today.AddDays(12), Text = "Vacation" },
    };

    void NumberOfDaysChange()
    {
        StateHasChanged();
    }

    void OnSlotRender(SchedulerSlotRenderEventArgs args)
    {
        // Highlight today in month view
        if (args.View.Text == "Month" && args.Start.Date == DateTime.Today)
        {
            args.Attributes["style"] = "background: var(--rz-scheduler-highlight-background-color, rgba(255,220,40,.2));";
        }

        // Highlight working hours (9-18)
        if ((args.View.Text == "Week" || args.View.Text == "Day") && args.Start.Hour > 8 && args.Start.Hour < 19)
        {
            args.Attributes["style"] = "background: var(--rz-scheduler-highlight-background-color, rgba(255,220,40,.2));";
        }
    }

    async Task OnSlotSelect(SchedulerSlotSelectEventArgs args)
    {
        console.Log($"SlotSelect: Start={args.Start} End={args.End}");

        if (args.View.Text != "Year")
        {
            Appointment data = await DialogService.OpenAsync<AddAppointmentPage>("Add Appointment",
                new Dictionary<string, object> { { "Start", args.Start }, { "End", args.End } });

            if (data != null)
            {
                appointments.Add(data);
                // Either call the Reload method or reassign the Data property of the Scheduler
                await scheduler.Reload();
            }
        }
    }

    async Task OnAppointmentSelect(SchedulerAppointmentSelectEventArgs<Appointment> args)
    {
        console.Log($"AppointmentSelect: Appointment={args.Data.Text}");

        var copy = new Appointment
        {
            Start = args.Data.Start,
            End = args.Data.End,
            Text = args.Data.Text
        };

        var data = await DialogService.OpenAsync<EditAppointmentPage>("Edit Appointment", new Dictionary<string, object> { { "Appointment", copy } });

        if (data != null)
        {
            // Update the appointment
            args.Data.Start = data.Start;
            args.Data.End = data.End;
            args.Data.Text = data.Text;
        }

        await scheduler.Reload();
    }

    void OnAppointmentRender(SchedulerAppointmentRenderEventArgs<Appointment> args)
    {
        // Never call StateHasChanged in AppointmentRender - would lead to infinite loop

        if (args.Data.Text == "Birthday")
        {
            args.Attributes["style"] = "background: red";
        }
    }

    async Task OnAppointmentMove(SchedulerAppointmentMoveEventArgs args)
    {
        var draggedAppointment = appointments.FirstOrDefault(x => x == args.Appointment.Data);

        if (draggedAppointment != null)
        {
            draggedAppointment.Start = draggedAppointment.Start + args.TimeSpan;

            draggedAppointment.End = draggedAppointment.End + args.TimeSpan;

            await scheduler.Reload();
        }
    }
}