@extends ('layouts.patient')

@section('inner-content')



    <?php

    function adjustBrightness($hex, $steps) {
        $steps = max(-255, min(255, $steps));
        $hex = str_replace('#', '', $hex);
        if (strlen($hex) == 3) {
            $hex = str_repeat(substr($hex,0,1), 2).str_repeat(substr($hex,1,1), 2).str_repeat(substr($hex,2,1), 2);
        }
        $color_parts = str_split($hex, 2);
        $return = '#';
        foreach ($color_parts as $color) {
            $color   = hexdec($color); // Convert to decimal
            $color   = max(0,min(255,$color + $steps)); // Adjust color
            $return .= str_pad(dechex($color), 2, '0', STR_PAD_LEFT); // Make two char hex code
        }
        return $return;
    }

    $palette = [
        ["bc" => '#522e92', "fc" => "#ffffff", "ac" => adjustBrightness('#522e92', 180) . 'aa'],
        ["bc" => '#003152', "fc" => "#ffffff", "ac" => adjustBrightness('#003152', 180) . 'aa'],
        ["bc" => '#111e6c', "fc" => "#ffffff", "ac" => adjustBrightness('#111e6c', 180) . 'aa'],
        ["bc" => '#1034a6', "fc" => "#ffffff", "ac" => adjustBrightness('#1034a6', 180) . 'aa'],
        ["bc" => '#0f52ba', "fc" => "#ffffff", "ac" => adjustBrightness('#0f52ba', 180) . 'aa'],
        ["bc" => '#447684', "fc" => "#ffffff", "ac" => adjustBrightness('#447684', 180) . 'aa'],
        ["bc" => '#d86700', "fc" => "#ffffff", "ac" => adjustBrightness('#d86700', 180) . 'aa'],
        ["bc" => '#643c07', "fc" => "#ffffff", "ac" => adjustBrightness('#643c07', 180) . 'aa'],
        ["bc" => '#ff3f3f', "fc" => "#ffffff", "ac" => adjustBrightness('#ff3f3f', 180) . 'aa'],
        ["bc" => '#ffa395', "fc" => "#222222", "ac" => adjustBrightness('#ffa395', 180) . 'aa'],
        ["bc" => '#6450ff', "fc" => "#ffffff", "ac" => adjustBrightness('#6450ff', 180) . 'aa'],
        ["bc" => '#8ec7f4', "fc" => "#222222", "ac" => adjustBrightness('#8ec7f4', 180) . 'aa'],
        ["bc" => '#522e92', "fc" => "#ffffff", "ac" => adjustBrightness('#522e92', 180) . 'aa'],
        ["bc" => '#111e6c', "fc" => "#ffffff", "ac" => adjustBrightness('#111e6c', 180) . 'aa'],
        ["bc" => '#003152', "fc" => "#ffffff", "ac" => adjustBrightness('#003152', 180) . 'aa'],
        ["bc" => '#1034a6', "fc" => "#ffffff", "ac" => adjustBrightness('#1034a6', 180) . 'aa'],
        ["bc" => '#0f52ba', "fc" => "#ffffff", "ac" => adjustBrightness('#0f52ba', 180) . 'aa'],
        ["bc" => '#447684', "fc" => "#ffffff", "ac" => adjustBrightness('#447684', 180) . 'aa'],
        ["bc" => '#d86700', "fc" => "#ffffff", "ac" => adjustBrightness('#d86700', 180) . 'aa'],
        ["bc" => '#643c07', "fc" => "#ffffff", "ac" => adjustBrightness('#643c07', 180) . 'aa'],
        ["bc" => '#ff3f3f', "fc" => "#ffffff", "ac" => adjustBrightness('#ff3f3f', 180) . 'aa'],
        ["bc" => '#ffa395', "fc" => "#222222", "ac" => adjustBrightness('#ffa395', 180) . 'aa'],
        ["bc" => '#6450ff', "fc" => "#ffffff", "ac" => adjustBrightness('#6450ff', 180) . 'aa'],
        ["bc" => '#8ec7f4', "fc" => "#222222", "ac" => adjustBrightness('#8ec7f4', 180) . 'aa'],
    ];
    ?>



    <link href="/select2/select2.min.css" rel="stylesheet" />
    <script src="/select2/select2.min.js"></script>
    <link href='/fullcalendar-5.3.2/lib/main.css' rel='stylesheet' />
    <script src='/fullcalendar-5.3.2/lib/main.js'></script>

    <?php
    if(!$currentAppointment || !$currentAppointment->id) {
        $currentAppointment = false;
    }
    ?>

    <div id="calendarApp">
        <div class="d-flex align-items-center mb-2">
            <h4 class="font-weight-bold m-0 font-size-16">
                {{ $patient->displayName() }}'s Calendar
            </h4>
            <button v-on:click.prevent="clickThruMode = !clickThruMode"
                    class="ml-3 btn btn-sm outline-0" :class="clickThruMode ? 'btn-info font-weight-bold' : 'btn-outline-info'">
                Click Through Mode
            </button>
            <div class="ml-auto d-inline-flex align-items-center">
                <label class="mr-2 my-0 text-secondary">Show</label>
                <select id="eventTypes"
                        class="form-control form-control-sm w-180"
                        v-model="eventTypes"
                        v-on:change="refreshEvents()">
                    <option value="APPOINTMENTS">Active Appointments</option>
                    <option value="APPOINTMENTS_ALL">All Appointments</option>
                    <option value="PRO_AVAILABILITY">Pro Availability</option>
                    <option value="BOTH">Pro Availability &amp; Active Appointments</option>
                    <option value="BOTH_ALL">Pro Availability &amp; All Appointments</option>
                </select>
            </div>
            <div class="ml-3 d-inline-flex align-items-center">
                <label class="mr-2 my-0 text-secondary">Timezone</label>
                <select id="eventTz" name="timeZone"
                        class="form-control form-control-sm w-180"
                        v-model="timezone">
                    <option value="EASTERN" selected>Eastern</option>
                    <option value="CENTRAL">Central</option>
                    <option value="MOUNTAIN">Mountain</option>
                    <option value="PACIFIC">Pacific</option>
                    <option value="ALASKA">Alaska</option>
                    <option value="HAWAII">Hawaii</option>
                    <option value="PUERTO_RICO">Puerto Rico</option>
                </select>
            </div>
        </div>
        <div class="d-block appt-form">
            <form class="appt-form-col w-100 d-flex align-items-center mb-2">
                <label class="mr-2 my-0 text-secondary text-nowrap">Show all appointments for</label>
                <select id="eventPros" name="proUid" xprovider-search
                        class="form-control form-control-sm flex-grow-1" multiple
                        v-model="proIds">
                    <?php
                    $proIndex = 0;
                    $proMeta = [];
                    ?>
                    @foreach($pros as $iPro)
                        <option value="{{$iPro->id}}"
                                data-bc="{{$palette[$proIndex]["bc"]}}"
                                data-fc="{{$palette[$proIndex]["fc"]}}"
                                data-initials="{{$iPro->initials()}}">
                            {{$iPro->displayName()}}
                        </option>
                        <?php
                        $proMeta[$iPro->uid] = [
                            "bc" => $palette[$proIndex]["bc"],
                            "fc" => $palette[$proIndex]["fc"],
                            "ac" => $palette[$proIndex]["ac"],
                            "initials" => $iPro->initials()
                        ];
                        $proIndex++;
                        if($proIndex >= count($palette)) $proIndex = 0;
                        ?>
                    @endforeach
                </select>
            </form>
            <hr class="my-2">
            <div class="appt-calendar-col" :class="clickThruMode ? 'click-through' : ''">
                <div class="stag-fc-container"></div>
            </div>
        </div>
        <div class="stag-popup stag-popup-sm mcp-theme-1" stag-popup-key="client-add-appointment">
            <form method="POST" action="/api/appointment/create" id="newApptForm">
                <h3 class="stag-popup-title">
                    <span>Book New Appointment</span>
                    <a href="#" class="ml-auto text-secondary"
                       onclick="return closeStagPopup()"><i class="fa fa-times-circle"></i></a>
                </h3>
                <input type="hidden" name="clientUid" :value="newAppointment.clientUid">
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Patient
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="text"
                               class="form-control form-control-sm"
                               :value="client.nameStr" readonly>
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Pro
                    </div>
                    <div class="col-9 font-weight-bold">
                        <select id="addApptPro" name="proUid" xprovider-search required
                                v-model="newAppointment.proUid"
                                class="form-control form-control-sm">
                            @foreach($pros as $iPro)
                                <option value="{{$iPro->uid}}">
                                    {{$iPro->displayName()}}
                                </option>
                            @endforeach
                        </select>
                    </div>
                </div>
                <hr class="my-2">
                <input type="hidden" name="referringProUid" value="{{ $pro->uid }}">
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Date
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="date" name="date" required
                               class="form-control form-control-sm"
                               v-model="newAppointment.date">
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Start Time
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="time" name="startTime" required
                               class="form-control form-control-sm"
                               v-model="newAppointment.startTime">
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        End Time
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="time" name="endTime"
                               class="form-control form-control-sm"
                               v-model="newAppointment.endTime">
                    </div>
                </div>
                <input type="hidden" name="timeZone" :value="timezone">
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Timezone
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="text"
                               class="form-control form-control-sm"
                               :value="timezone" readonly>
                        <div class="text-secondary font-weight-normal py-1 text-sm">Timezone as set in the calendar</div>
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Title
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="text" name="title"
                               class="form-control form-control-sm"
                               v-model="newAppointment.title">
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Description
                    </div>
                    <div class="col-9 font-weight-bold">
                        <textarea name="description"
                                  class="form-control form-control-sm"
                                  v-model="newAppointment.description"></textarea>
                    </div>
                </div>
                <div class="d-flex align-items-center justify-content-center">
                    <button class="btn btn-sm btn-primary mr-2"
                            :disabled="inProgress"
                            v-on:click.prevent="addAppointment()">Submit</button>
                    <button class="btn btn-sm btn-default border"
                            onclick="return closeStagPopup()">Cancel</button>
                </div>
            </form>
        </div>
        <div class="stag-popup stag-popup-sm mcp-theme-1" stag-popup-key="client-edit-appointment">
            <form method="POST" action="/api/appointment/update" id="editApptForm">
                <h3 class="stag-popup-title">
                    <span>Edit Appointment</span>
                    <a href="#" class="ml-auto text-secondary"
                       onclick="return closeStagPopup()"><i class="fa fa-times-circle"></i></a>
                </h3>
                <input type="hidden" name="uid" :value="editAppointment.uid">
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Patient
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="text"
                               class="form-control form-control-sm"
                               :value="editAppointment.clientName" readonly>
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Pro
                    </div>
                    <div class="col-9 font-weight-bold">
                        <select id="editApptPro" name="proUid" xprovider-search required
                                v-model="editAppointment.proUid"
                                class="form-control form-control-sm">
                            @foreach($pros as $iPro)
                                <option value="{{$iPro->uid}}">
                                    {{$iPro->displayName()}}
                                </option>
                            @endforeach
                        </select>
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Date
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="date" name="date" required
                               class="form-control form-control-sm"
                               v-model="editAppointment.date">
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Start Time
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="time" name="startTime" required
                               class="form-control form-control-sm"
                               v-model="editAppointment.startTime">
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        End Time
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="time" name="endTime"
                               class="form-control form-control-sm"
                               v-model="editAppointment.endTime">
                    </div>
                </div>
                <input type="hidden" name="timeZone" :value="timezone">
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Timezone
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="text"
                               class="form-control form-control-sm"
                               :value="timezone" readonly>
                        <div class="text-secondary font-weight-normal py-1 text-sm">Timezone as set in the calendar</div>
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Status
                    </div>
                    <div class="col-9 font-weight-bold">
                        <select id="editApptStatus" name="status" required
                                v-model="editAppointment.status"
                                class="form-control form-control-sm font-weight-bold px-1">
                            <option value="CREATED">CREATED</option>
                            <option value="CONFIRMED">CONFIRMED</option>
                            <option value="CANCELLED">CANCELLED</option>
                            <option value="COMPLETED">COMPLETED</option>
                            <option value="ABANDONED">ABANDONED</option>
                        </select>
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Title
                    </div>
                    <div class="col-9 font-weight-bold">
                        <input type="text" name="title"
                               class="form-control form-control-sm"
                               v-model="editAppointment.title">
                    </div>
                </div>
                <div class="row mb-2">
                    <div class="col-3 text-secondary">
                        Description
                    </div>
                    <div class="col-9 font-weight-bold">
                        <textarea name="description"
                                  class="form-control form-control-sm"
                                  v-model="editAppointment.description"></textarea>
                    </div>
                </div>
                <div class="d-flex align-items-center justify-content-center">
                    <button class="btn btn-sm btn-primary mr-2"
                            :disabled="inProgress"
                            v-on:click.prevent="updateAppointment()">Submit</button>
                    <button class="btn btn-sm btn-default border"
                            onclick="return closeStagPopup()">Cancel</button>
                </div>
            </form>
        </div>
    </div>
    <script>
        (function() {

            <?php
            $patient->nameStr = $patient->displayName();
            $clientObject = json_encode($patient);
            ?>

            function init() {
                window.calendarApp = new Vue({
                    el: '#calendarApp',
                    data: {
                        client: {!! json_encode($patient) !!},
                        eventTypes: '{{ $currentAppointment ? 'BOTH_ALL' : 'BOTH' }}',
                        calendar: null,
                        proMeta: {!! json_encode($proMeta) !!},
                        proIds: ['{{ $currentAppointment ? $currentAppointment->pro_id : $pro->id }}'],
                        timezone: '{{ $currentAppointment ? $currentAppointment->timezone : 'EASTERN' }}',
                        today: new Date('{{ date('Y-m-d 00:00:00') }}'),

                        // user clicks/selection
                        selectedSlot: null,
                        selectedEvent: null,

                        // new appt.
                        newAppointment: {
                            proUid: '',
                            referringProUid: '',
                            date: '',
                            startTime: '',
                            endTime: '',
                            timeZone: '',
                            title: '',
                            description: '',
                        },

                        // edit appt.
                        editAppointment: {
                            proUid: '',
                            clientName: '',
                            date: '',
                            startTime: '',
                            endTime: '',
                            timeZone: '',
                            title: '',
                            description: '',
                            status: '',
                        },

                        // availability
                        availability: {},

                        inProgress: false,
                        editHonored: false,

                        clickThruMode: false,
                    },
                    methods: {
                        // init
                        init: function() {
                            this.initSelect2();
                            this.initCalendar();
                        },
                        initSelect2: function () {
                            let self = this;
                            $('#eventTz')
                                .select2({
                                    templateResult: function(_state) {
                                        return $('<span class="mcp-theme-1"><span>' + _state.text + '</span></span>');
                                    }
                                })
                                .on('change', function() {
                                    self.timezone = $(this).val();
                                    localStorage.stagCalendarTZ = self.timezone;
                                    self.refreshEvents();
                                });
                            $('#eventPros')
                                .select2({
                                    closeOnSelect: false,

                                    // dropdown options
                                    templateResult: function(_state) {
                                        let element = _state.element;
                                        if(!element || !element.value) {
                                            return $('<span class="mcp-theme-1"><span>' + _state.text + '</span></span>');
                                        }
                                        element = $(element);
                                        return $('<span class="mcp-theme-1 pro-option" ' +
                                            'data-initials="' + element.attr('data-initials') + '" ' +
                                            'data-bc="' + element.attr('data-bc') + '" ' +
                                            'data-fc="' + element.attr('data-fc') + '"><span>' +
                                            '<span class="pro-option-initials" ' +
                                            'style="background: ' + element.attr('data-bc') + '; color: ' + element.attr('data-fc') + '">' +
                                            element.attr('data-initials') + '</span>' +
                                            _state.text +
                                            '</span></span>');
                                    },

                                    // selected items
                                    templateSelection: function(_state) {
                                        let element = _state.element;
                                        if(!element || !element.value) {
                                            return $('<span class="mcp-theme-1"><span>' + _state.text + '</span></span>');
                                        }
                                        element = $(element);
                                        return $('<span class="pro-selection" style="background: ' + element.attr('data-bc') + '; color: ' + element.attr('data-fc') + '">' +
                                            _state.text + '</span>');
                                    }
                                })
                                .on('change', function() {
                                    self.proIds = $(this).val();
                                    localStorage.stagCalendarProIds = JSON.stringify(self.proIds);
                                    self.refreshEvents();
                                });
                            $('#addApptPro')
                                .select2({
                                    width: '100%',
                                    templateResult: function(_state) {
                                        return $('<span class="mcp-theme-1"><span>' + _state.text + '</span></span>');
                                    },
                                    placeholder: '-- Select Pro --'
                                })
                                .on('change', function() {
                                    self.newAppointment.proUid = $(this).val();
                                });
                            $('#editApptPro')
                                .select2({
                                    width: '100%',
                                    templateResult: function(_state) {
                                        return $('<span class="mcp-theme-1"><span>' + _state.text + '</span></span>');
                                    },
                                    placeholder: '-- Select Pro --'
                                })
                                .on('change', function() {
                                    self.editAppointment.proUid = $(this).val();
                                });
                        },
                        initCalendar: function () {
                            let self = this;
                            <?php
                            $initialDate = date('Y-m-d');
                            if($currentAppointment) {
                                $initialDate = trim(preg_replace("/ .*/", "", $currentAppointment->start_time));
                            }
                            ?>
                            this.calendar = new FullCalendar.Calendar($('.stag-fc-container')[0], {
                                headerToolbar: {
                                    left: 'prev,next today',
                                    center: 'title',
                                    right: 'dayGridMonth,timeGridWeek,timeGridDay'
                                },
                                initialView: 'timeGridWeek',
                                initialDate: '{{ $initialDate }}',
                                editable: true,
                                selectable: true,
                                navLinks: true,
                                dayMaxEvents: false,
                                slotMinTime: '00:00',
                                slotMaxTime: '23:59',
                                scrollTime: '06:00:00',
                                slotDuration: '00:15:00',
                                events: function(info, successCallback, failureCallback) {
                                    // if(!self.proIds || !self.proIds.length) {
                                    //     successCallback([]); // no events if no pro selected
                                    //     return;
                                    // }
                                    if(!self.timezone) {
                                        successCallback([]); // no events if no tz selected
                                        return;
                                    }
                                    $.get('/appointment/getAllAppointmentsForPros' +
                                        '?proIds=' + self.proIds +
                                        '&clientId=' + self.client.id +
                                        '&start=' + info.startStr.substr(0, 10) +
                                        '&end=' + info.endStr.substr(0, 10) +
                                        '&timeZone=' + self.timezone, function(_data) {
                                        if(_data && Array.isArray(_data)) {
                                            let events = _data, displayEvents = [];
                                            for(let e in events) {
                                                if(events.hasOwnProperty(e) && self.proMeta[events[e].proUid]) {
                                                    let ev = events[e], meta = self.proMeta[ev.proUid];
                                                    if(ev.type === 'appointment') {
                                                        if(self.eventTypes.indexOf('APPOINTMENTS') === 0 || self.eventTypes.indexOf('BOTH') === 0) {
                                                            ev.backgroundColor =  meta.bc;
                                                            ev.borderColor = meta.bc;
                                                            ev.textColor = meta.fc;
                                                            ev.initials = meta.initials;
                                                            ev.display = 'block';
                                                            ev.editable = true;

                                                            // active/all
                                                            if(['CANCELLED', 'COMPLETED', 'ABANDONED'].indexOf(ev.status) !== -1) {
                                                                if(self.eventTypes === 'APPOINTMENTS_ALL' || self.eventTypes === 'BOTH_ALL') {
                                                                    displayEvents.push(ev);
                                                                }
                                                            }
                                                            else {
                                                                displayEvents.push(ev);
                                                            }
                                                        }
                                                    }
                                                    else {
                                                        if(self.eventTypes === 'PRO_AVAILABILITY' || self.eventTypes.indexOf('BOTH') === 0) {
                                                            ev.backgroundColor = meta.ac;
                                                            ev.borderColor = meta.bc;
                                                            ev.textColor = meta.bc;
                                                            ev.initials = meta.initials;
                                                            ev.display = 'block';
                                                            ev.editable = false;
                                                            displayEvents.push(ev);
                                                        }
                                                    }
                                                }
                                            }
                                            successCallback(displayEvents);
                                        }
                                        else {
                                            failureCallback('Unable to refresh appointments!');
                                        }
                                    }, 'json');
                                },
                                eventDidMount: function(arg) {
                                    self.afterRenderingEvents();
                                    if(arg.event.extendedProps.type === 'appointment') {
                                        console.log(arg.event)
                                    }
                                },
                                eventClassNames: function(arg) {
                                    let classes = [];
                                    if (arg.event.extendedProps.clientOnly) {
                                        classes.push('client-only');
                                    }
                                    if (arg.event.extendedProps.otherClient) {
                                        classes.push('other-client');
                                    }
                                    if (arg.event.extendedProps.type === 'availability') {
                                        classes.push('availability');
                                    }
                                    if (['CANCELLED', 'COMPLETED', 'ABANDONED'].indexOf(arg.event.extendedProps.status) !== -1) {
                                        classes.push('inactive-appointment');
                                    }
                                    if (arg.event.extendedProps.type === 'appointment') {
                                        classes.push('appointment-' + arg.event.extendedProps.appointmentUid);
                                    }
                                    return classes;
                                },
                                loading: function(bool) {

                                },
                                eventClick: function(info) {
                                    self.selectedEvent = info.event;
                                    self.showEditAppointmentModal();
                                },
                                selectAllow: function(info) { // allow only single selections
                                    let seconds = info.end.getTime() - info.start.getTime(),
                                        maxDelta = 86400000;
                                    console.log(seconds);
                                    if(!info.allDay) {
                                        maxDelta = 1800000;
                                    }
                                    return seconds <= maxDelta;
                                },
                                select: function(info) {
                                    self.selectedSlot = info;
                                    if(self.today.getTime() <= self.selectedSlot.start.getTime()) {
                                        $('<a href="#" class="add-overlay ' +
                                            (info.allDay ? 'add-overlay-day-grid' : 'add-overlay-time-grid') + '">Add</a>')
                                            .on('mousedown', function() {
                                                self.showAddAppointmentModal();
                                                return false;
                                            })
                                            .appendTo('.fc-highlight');
                                    }
                                },
                                eventDrop: self.eventMovedOrResized,
                                eventResize: self.eventMovedOrResized
                            });
                            $(document).on('mousedown', '.fc-highlight', function() {
                                 if(self.selectedSlot && self.today.getTime() <= self.selectedSlot.start.getTime()) {
                                     self.showAddAppointmentModal();
                                 }
                            });
                            this.calendar.render();
                        },
                        afterRenderingEvents: function() {
                            let self = this;
                            $('.fc .availability').each(function () {
                                $(this).parent('.fc-timegrid-event-harness').css('pointer-events', 'none');
                            });
                            @if($currentAppointment)
                            if(!self.editHonored) {
                                window.setTimeout(function() {
                                    let allEvents = self.calendar.getEvents();
                                    if(allEvents) {
                                        let currentEvent = allEvents.filter(function(_ev) {
                                            return _ev.extendedProps.appointmentUid === '{{ $currentAppointment->uid }}';
                                        });
                                        if(currentEvent) currentEvent = currentEvent[0];
                                        if(currentEvent) {
                                            self.selectedEvent = currentEvent;
                                            self.showEditAppointmentModal();
                                            self.editHonored = true;
                                        }
                                    }
                                }, 250);
                            }
                            @endif
                        },
                        dateStr: function(_dateTime) {
                            return _dateTime.getFullYear() + "-" +
                                ("0"+(_dateTime.getMonth()+1)).slice(-2) + "-" +
                                ("0" + _dateTime.getDate()).slice(-2);
                        },
                        timeStr: function(_dateTime) {
                            return ("0" + _dateTime.getHours()).slice(-2) + ":" +
                                ("0" + _dateTime.getMinutes()).slice(-2);
                        },
                        eventMovedOrResized: function (info) {
                            let self = this;
                            if(!window.confirm('Are you sure?')) {
                                this.refreshEvents();
                                return;
                            }
                            let date = this.dateStr(info.event.start);
                            let startTime = this.timeStr(info.event.start);
                            let endTime = null;
                            if(info.event.end) {
                                endTime = this.timeStr(info.event.end);
                            }
                            $.post('/api/appointment/updateDateAndTime', {
                                uid: info.event.extendedProps.appointmentUid,
                                date: date,
                                startTime: startTime,
                                endTime: endTime,
                                timeZone: this.timezone,
                            }, function(_data) {
                                self.refreshEvents();
                                if(_data) {
                                    if(!_data.success) {
                                        toastr.error(_data.message);
                                    }
                                }
                                else {
                                    toastr.error('Unable to update the appointment!');
                                }
                            }, 'json');
                        },
                        refreshEvents: function() {
                            this.calendar.refetchEvents();
                        },
                        showAddAppointmentModal: function() {
                            // setup model data
                            this.inProgress = false;
                            let startTime = this.timeStr(this.selectedSlot.start);
                            let endTime = this.timeStr(this.selectedSlot.end);
                            this.newAppointment.clientUid = this.client.uid;
                            this.newAppointment.proUid = '';
                            this.newAppointment.referringProUid = '';
                            this.newAppointment.date = this.dateStr(this.selectedSlot.start);
                            this.newAppointment.startTime = startTime === '00:00' ? '' : startTime;
                            this.newAppointment.endTime = (this.selectedSlot.allDay || endTime === '00:00') ? '' : endTime;
                            this.newAppointment.timeZone = this.timezone;
                            this.newAppointment.title = '';
                            this.newAppointment.description = '';
                            Vue.nextTick(function() {
                                $('#addApptPro').find('option').prop('selected', false);
                                $('#addApptPro').trigger('change');
                                showStagPopup('client-add-appointment', true);
                            });
                        },
                        addAppointment: function() {
                            let form = $('#newApptForm');
                            if(!form[0].checkValidity()) {
                                form[0].reportValidity();
                                return false;
                            }
                            this.inProgress = true;
                            let self = this;
                            showMask();
                            $.post(form.attr('action'), form.serialize(), function(_data) {
                                if(_data) {
                                    if(_data.success) {
                                        self.refreshEvents();
                                        closeStagPopup();
                                    }
                                    else {
                                        toastr.error(_data.message);
                                    }
                                }
                                else {
                                    toastr.error('Unable to book appointment!');
                                }
                                self.inProgress = false;
                                hideMask();
                            }, 'json');
                        },
                        showEditAppointmentModal: function() {
                            // setup model data
                            this.inProgress = false;
                            this.editAppointment.uid = this.selectedEvent.extendedProps.appointmentUid;
                            this.editAppointment.clientName = this.selectedEvent.extendedProps.clientName;
                            this.editAppointment.proUid = this.selectedEvent.extendedProps.proUid;
                            this.editAppointment.date = this.dateStr(this.selectedEvent.start);
                            this.editAppointment.startTime = this.timeStr(this.selectedEvent.start);
                            this.editAppointment.endTime = this.selectedEvent.end ? this.timeStr(this.selectedEvent.end) : '';
                            this.editAppointment.timeZone = this.timezone;
                            this.editAppointment.title = this.selectedEvent.extendedProps._title;
                            this.editAppointment.description = this.selectedEvent.extendedProps.description;
                            this.editAppointment.status = this.selectedEvent.extendedProps.status;
                            Vue.nextTick(function() {
                                $('#editApptPro').trigger('change');
                                showStagPopup('client-edit-appointment', true);
                            });
                        },
                        updateAppointment: function() {
                            let form = $('#editApptForm');
                            if(!form[0].checkValidity()) {
                                form[0].reportValidity();
                                return false;
                            }

                            // confirming if changing to cancelled, completed or abandoned
                            if(this.selectedEvent.extendedProps.status !== this.editAppointment.status &&
                                ['CANCELLED', 'COMPLETED', 'ABANDONED'].indexOf(this.editAppointment.status) !== -1) {
                                if(!window.confirm('CANCELLED, COMPLETED and ABANDONED appointments will ' +
                                    'not be displayed in the calendar by default.\n\n' +
                                    'Are you sure you want to update the status of this appointment to ' + this.editAppointment.status + '?')) {
                                    return false;
                                }
                            }

                            this.inProgress = true;
                            let self = this;
                            showMask();
                            $.post(form.attr('action'), form.serialize(), function(_data) {
                                if(_data) {
                                    if(_data.success) {
                                        self.refreshEvents();
                                        closeStagPopup();
                                    }
                                    else {
                                        toastr.error(_data.message);
                                    }
                                }
                                else {
                                    toastr.error('Unable to update appointment!');
                                }
                                self.inProgress = false;
                                hideMask();
                            }, 'json');
                        },
                    },
                    mounted: function() {
                        this.init();
                        @if(!$currentAppointment)
                        if(localStorage.stagCalendarTZ) {
                            this.timezone = localStorage.stagCalendarTZ;
                            Vue.nextTick(function() {
                                $('#eventTz').trigger('change');
                            });
                        }
                        if(localStorage.stagCalendarProIds) {
                            this.proIds = JSON.parse(localStorage.stagCalendarProIds);
                            Vue.nextTick(function() {
                                $('#eventPros').trigger('change');
                            });
                        }
                        @endif
                    }
                });
            }

            addMCInitializer('patient-calendar', init, '#calendarApp');
        })();
    </script>
@endsection
