let currentListDate = new Date();
let eventTasks = [];
let dpc, dpm;

const selectors = {
    addEventModalForm: '#add-event-modal-form',
    eventId: '#event-id',
    eventName: '#event-name',
    eventCase: '#event-case',
    eventLocation: '#event-location',
    eventDescription: '#event-description',
    eventStart: '#event-start',
    eventEnd: '#event-end',
    addEventURL: '#AddEventURL',
    updateEventURL: '#UpdateEventURL',
    deleteEventURL: '#DeleteEventURL',
    eventsListURL: '#EventsListURL',
    calendarType: '#calendar-type',
    eventTypes: '#event-types',
    addEventModal: '#add-event-modal',
    currentDatesTitle: '#currentDatesTitle',
    prev: "#prev",
    next: "#next",
    calendarNavigation: '.calendar-navigation',
    dpc: '#dpc',
    dpm: '#dpm',
    newEventLoc: '#NewEventLOC',
    editEventLoc: '#EditEventLOC',
    deleteEventLoc: '#DeleteEventLOC',
    confirmDeleteLoc: '#ConfirmDeleteLOC',
    cancelDeleteLoc: '#CancelDeleteLOC',
    modalTitle: '#event-modal-title',
    saveButton: '#save-button',
    deleteButton: '#delete-button',
    parentCase: '#ParentCase',
    selectedCase: '#select2-event-case-container',
    organizer: '#Organizer',
    defaultOrganizer: '#DefaultOrganizer',
    dateAndTimeFormatUpper: '#DateAndTimeFormatUpperLOC',
    calendarCodeThemis: '#CalendarCodeThemis',
    calendarCodeTravelOrder: '#CalendarCodeTravelOrder',
    calendarCodeAbsence: '#CalendarCodeAbsence',
    calendarLegalDocumentCode: '#CalendarLegalDocumentCode',
    calendarLegalEventCode: '#CalendarLegalEventCode',
    participants: '#Participants',
    calendarQId: '#calendar-qid',
    dpList: '#dpList',
    showPastEventsContainer: '#show-past-events-container',
    showPastEvents: '#show-past-events',
    editCaseUrl: '#EditCaseURL',
    MondayLoc: '#MondayLoc',
    TuesdayLoc: '#TuesdayLoc',
    WednesdayLoc: '#WednesdayLoc',
    ThursdayLoc: '#ThursdayLoc',
    FridayLoc: '#FridayLoc',
    SaturdayLoc: '#SaturdayLoc',
    SundayLoc: '#SundayLoc',
    JanuaryLoc: '#JanuaryLoc',
    FebruaryLoc: '#FebruaryLoc',
    MarchLoc: '#MarchLoc',
    AprilLoc: '#AprilLoc',
    MayLoc: '#MayLoc',
    JuneLoc: '#JuneLoc',
    JulyLoc: '#JulyLoc',
    AugustLoc: '#AugustLoc',
    SeptemberLoc: '#SeptemberLoc',
    OctoberLoc: '#OctoberLoc',
    NovemberLoc: '#NovemberLoc',
    DecemberLoc: '#DecemberLoc'
};

const calendarTypes = {
    day: "day",
    week: "week",
    month: "month",
    list: "list"
};

const calendarCodes = {
    themis: $(selectors.calendarCodeThemis).val(),
    absence: $(selectors.calendarCodeAbsence).val(),
    travelOrder: $(selectors.calendarCodeTravelOrder).val()
};

const calendarTaskCodes = {
    document: $(selectors.calendarLegalDocumentCode).val(),
    event: $(selectors.calendarLegalEventCode).val()
}

$(document).ready(function () {
    initializeEvents();

    if (!$(selectors.calendarType).val()) {
        $(selectors.calendarType).val(calendarTypes.week);
    }
    setupCalendarTypeChangeHandler();

    loadEvents();
    $(selectors.calendarNavigation).show();

    setTimeout(() => {
        if ($(selectors.calendarType).val() !== calendarTypes.week) {
            $(selectors.calendarType).val(calendarTypes.week);
            switchCalendarView(calendarTypes.week);
        }
    }, 10);

    $(selectors.addEventModalForm).submit(function (e) {
        e.preventDefault();
        addEvent();
    });
});

function navigateCalendar(direction) {
    const calendarType = $(selectors.calendarType).val();

    if (calendarType === calendarTypes.list) {
        navigateListView(direction);
    } else if (calendarType === calendarTypes.month) {
        navigateMonths(direction);
    } else {
        const dayMapping = {
            [calendarTypes.day]: 1,
            [calendarTypes.week]: 7
        };
        navigateDays(direction * dayMapping[calendarType]);
    }
}

function navigateMonths(months) {
    const dateProvider = dpm;
    dateProvider.startDate = dateProvider.startDate.addMonths(months);

    dateProvider.update();
    updateDatesTitle();
    loadEvents();
}

function navigateDays(days) {
    const dateProvider = dpc;
    dateProvider.startDate = dateProvider.startDate.addDays(days);

    dateProvider.update();
    updateDatesTitle();
    loadEvents();
}

function navigateListView(months) {
    currentListDate = new Date(currentListDate.getFullYear(), currentListDate.getMonth() + (months * 3), 1);

    updateDatesTitle();
    loadEvents();
}

function initializeEvents() {
    currentListDate = new Date(new Date().getFullYear(), new Date().getMonth(), 1);

    document.getElementById('show-past-events').checked = false;

    DayPilot.Locale.US = {
            dayNames: [
                $(selectors.SundayLoc).val(),
                $(selectors.MondayLoc).val(), 
                $(selectors.TuesdayLoc).val(),
                $(selectors.WednesdayLoc).val(),
                $(selectors.ThursdayLoc).val(),
                $(selectors.FridayLoc).val(),
                $(selectors.SaturdayLoc).val()
            ],
            dayNamesShort: [
                $(selectors.SundayLoc).val().substring(0,2),
                $(selectors.MondayLoc).val().substring(0,2),
                $(selectors.TuesdayLoc).val().substring(0,2),
                $(selectors.WednesdayLoc).val().substring(0,2),
                $(selectors.ThursdayLoc).val().substring(0,2),
                $(selectors.FridayLoc).val().substring(0,2),
                $(selectors.SaturdayLoc).val().substring(0,2)
            ],
            monthNames: [
                $(selectors.JanuaryLoc).val(),
                $(selectors.FebruaryLoc).val(),
                $(selectors.MarchLoc).val(),
                $(selectors.AprilLoc).val(),
                $(selectors.MayLoc).val(),
                $(selectors.JuneLoc).val(),
                $(selectors.JulyLoc).val(),
                $(selectors.AugustLoc).val(),
                $(selectors.SeptemberLoc).val(),
                $(selectors.OctoberLoc).val(),
                $(selectors.NovemberLoc).val(),
                $(selectors.DecemberLoc).val()
            ],
            monthNamesShort: [
                $(selectors.JanuaryLoc).val().substring(0,3),
                $(selectors.FebruaryLoc).val().substring(0,3),
                $(selectors.MarchLoc).val().substring(0,3),
                $(selectors.AprilLoc).val().substring(0,3),
                $(selectors.MayLoc).val().substring(0,3),
                $(selectors.JuneLoc).val().substring(0,3),
                $(selectors.JulyLoc).val().substring(0,3),
                $(selectors.AugustLoc).val().substring(0,3),
                $(selectors.SeptemberLoc).val().substring(0,3),
                $(selectors.OctoberLoc).val().substring(0,3),
                $(selectors.NovemberLoc).val().substring(0,3),
                $(selectors.DecemberLoc).val().substring(0,3)
            ],
            timePattern: 'h:mm tt',
            datePattern: 'M/d/yyyy',
            dateTimePattern: 'M/d/yyyy h:mm tt',
            timeFormat: 'Clock12Hours',
            weekStarts: 0
        };
    
    initializeDayPilotCalendar();
    initializeDayPilotMonth();
    initializeEventsList();
    setupEventHandlers();
}

function initializeDayPilotCalendar() {
    dpc = new DayPilot.Calendar(selectors.dpc.slice(1));
    dpc.viewType = "Week";
    dpc.timeFormat = "Clock24Hours";
    dpc.headerDateFormat = "ddd, d MMM yyyy";
    dpc.headerHeight = 50;
    dpc.update();
   
    
    dpc.onBeforeEventRender = function (args) {
        if (args.data.calendarCode === calendarCodes.absence
            || args.data.calendarCode === calendarCodes.travelOrder) {
            args.data.html = `<div class='event-title' >${args.data.calendarEntryTypeName} ${args.data.organizer}</div>`;
        }
        else {
            args.data.html = `<div class='event-title'>${args.data.text} ${args.data.caseView} ${args.data.organizer}</div>`;
        }

        args.data.backColor = args.data.color;
        args.data.barHidden = true;
        args.data.toolTip = `${args.data.text} ${args.data.caseView} ${args.data.organizer}`
    };

    let expandedTasks = {};

    dpc.onBeforeHeaderRender = function (args) {
        const calendarType = $(selectors.calendarType).val();
        const dateProvider = getDateProvider(calendarType);
        const { startDate, endDate } = getDateRange(dateProvider, calendarType);
        if (!this.prevButtonListenerAdded) {
            addPrevNextButtonListeners();
            this.prevButtonListenerAdded = true;
        }

        const taskCountByDate = getTaskCountByDate(eventTasks);
        const tasksInRange = getTasksInRange(eventTasks, startDate, endDate);
        const headerDate = new Date(args.header.start.value);
        const tasks = getTasksForHeaderDate(eventTasks, headerDate);
        const showArrow = tasks.length > 3;
        const maxTasksPerDay = Math.max(...Object.values(taskCountByDate));
        const isExpanded = expandedTasks[headerDate] || false;
        const tasksHtml = generateTaskHtml(tasks, isExpanded);
        const arrowHtml = showArrow ? generateArrowHtml(headerDate, isExpanded) : '';

        args.header.html = generateHeaderHtml(args.header, tasksHtml, arrowHtml);

        adjustHeaderHeight(tasksInRange, maxTasksPerDay);

        window.toggleTasks = function (date) {
            toggleTaskExpansion(date, maxTasksPerDay);
        };
    };

    dpc.init();
    updateDatesTitle();
}

function initializeDayPilotMonth() {
    dpm = new DayPilot.Month(selectors.dpm.slice(1));
    dpm.viewType = "Month";
    dpm.headerDateFormat = "ddd, d MMM yyyy";
    dpm.locale = "US";
    dpm.weekStarts = 1;
    dpm.cellHeaderHeight = 25;
    dpm.headerHeight = 25;
    dpm.update();
    
    dpm.onBeforeEventRender = function (args) {
        if (args.data.calendarCode === calendarCodes.absence
            || args.data.calendarCode === calendarCodes.travelOrder) {
            args.data.html = `<div class='event-title'>${args.data.calendarEntryTypeName} ${args.data.organizer}</div>`;
        }
        else {
            args.data.html = `<div class='event-title'>${args.data.text} ${args.data.caseView} ${args.data.organizer}</div>`;
        }

        args.data.backColor = args.data.color;
        args.data.barHidden = true;
        args.data.toolTip = `${args.data.text} ${args.data.caseView} ${args.data.organizer}`
    };

    dpm.init();
}

function getDateProvider(calendarType) {
    if (calendarType === calendarTypes.list) {
        return null;
    }
    const provider = (calendarType === calendarTypes.month) ? dpm : dpc;
    return provider;
}

function getDateRange(dateProvider, calendarType) {
    const start = dateProvider.visibleStart().toString("yyyy-MM-dd");
    const end = (calendarType !== calendarTypes.day) ? dateProvider.visibleEnd().addDays(-1).toString("yyyy-MM-dd") : start;
    const startDate = new Date(start)
    const endDate = new Date(end)
    return { startDate, endDate };
}
function addPrevNextButtonListeners() {
    ['prev', 'next'].forEach(id =>
        document.getElementById(id).addEventListener('click', () => expandedTasks = {})
    );
}

function getTaskCountByDate(tasks) {
    return tasks.reduce((map, task) => {
        map[task.End] = (map[task.End] || 0) + 1;
        return map;
    }, {});
}

function getTasksInRange(tasks, startDate, endDate) {
    return tasks.filter(task => {
        const end = endDate ? endDate : startDate;
        startDate.setHours(0, 0, 0, 0);
        end.setHours(23, 59, 59, 999);
        task.End.setHours(0, 0, 0, 0);

        return task.End >= startDate && task.End <= end;
    });
}

function getTasksForHeaderDate(tasks, headerDate) {
    return tasks.filter(task => {
        return task.End.toDateString() === headerDate.toDateString();
    });
}

function generateTaskHtml(tasks, isExpanded) {
    return tasks.map((task, index) =>
        `<div class='header-item' style='display: ${index >= 3 && !isExpanded ? 'none' : 'block'};'>${task.Text}</div>`
    ).join('');
}

function generateArrowHtml(headerDate, isExpanded) {
    return `<div class='show-more-arrow' onclick='toggleTasks("${headerDate}")' style='cursor: pointer;'>
                <i class='fas ${!isExpanded ? 'fa-chevron-down' : 'fa-chevron-up'}'></i>
            </div>`;
}

function generateHeaderHtml(header, tasksHtml, arrowHtml) {
    return `<div class='main-header'>
                <div class='header-day'>${header.start.toString("ddd, d MMM yyyy")}</div>
                <div class='header-divider'></div>
                <div class='header-items'>${tasksHtml}${arrowHtml}</div>
            </div>`;
}

function adjustHeaderHeight(tasksInRange, maxTasksPerDay) {
    if (!tasksInRange.length) {
        dpc.headerHeight = 50;
        document.querySelectorAll(".calendar_default_colheader, .calendar_default_corner, .calendar_default_cornerright")
            .forEach(header => (header.style.height = "50px"));
        return;
    }

    const heightMap = { 1: 100, 2: 130, 3: 160 };
    const baseHeight = heightMap[maxTasksPerDay] || 190;
    dpc.headerHeight = baseHeight;
    setHeaderHeight(baseHeight)
}

function toggleTaskExpansion(date, maxTasksPerDay) {
    expandedTasks[date] = !expandedTasks[date];
    const height = expandedTasks[date] ? dpc.headerHeight + (maxTasksPerDay - 3) * 30 : dpc.headerHeight;
    dpc.update();
    setHeaderHeight(height)

}

function setHeaderHeight(height) {
    document.querySelectorAll(".calendar_default_colheader, .calendar_default_corner, .calendar_default_cornerright")
        .forEach(header => (header.style.height = `${height}px`));
}

function setupEventHandlers() {
    setupNavigationHandlers();
    setupModalHandlers();
    setupCalendarTypeChangeHandler();
    setupDayPilotEventHandlers();

    $(selectors.deleteButton).on('click', function () {
        $().customModal({
            destroyOnClose: true,
            showCloseButton: true,
            type: 'alert',
            text: $(selectors.deleteEventLoc).val(),
            buttons: [
                {
                    icon: 'fa fa-times',
                    text: $(selectors.cancelDeleteLoc).val(),
                    closeOnAction: true,
                    type: 'ghost'
                },
                {
                    text: $(selectors.confirmDeleteLoc).val(),
                    closeOnAction: true,
                    type: 'primary',
                    action: function () {
                        const calendarQId = $(selectors.calendarQId).val();
                        deleteEvent(calendarQId);
                        disableButton("delete-button", "#delete-button", "fa fa-trash m-r-xs")
                    },
                    icon: 'fa fa-check'
                }
            ]
        });
    });

    $('#show-past-events').on('change', function () {
        renderEventsList();
    });
}

function setupNavigationHandlers() {
    $(selectors.prev).click(function () {
        navigateCalendar(-1);
    });

    $(selectors.next).click(function () {
        navigateCalendar(1);
    });
};

function setupModalHandlers() {
    $(selectors.addEventModal).on('hidden.bs.modal', clearSelections);

    $(selectors.organizer).on('changed.bs.select', function () {
        updateParticipantsList();
    });
}

function setupCalendarTypeChangeHandler() {
    $(selectors.calendarType)
        .off('change')
        .on('change', function () {
            const viewType = $(this).val() || calendarTypes.week;

            if (this.hasAttribute('data-auto-trigger')) {
                return;
            }

            $(selectors.showPastEvents).prop('checked', false);

            switchCalendarView(viewType);
            loadEvents();
        });
}

function setupDayPilotEventHandlers() {
    dpc.onTimeRangeSelected = (args) => openModalForNewEvent(args.start, args.end);
    dpm.onTimeRangeSelected = (args) => openModalForNewEvent(args.start, args.end);

    dpc.onEventClick = (args) => openModalForEditEvent(args.e);
    dpm.onEventClick = (args) => openModalForEditEvent(args.e);

    dpc.onEventMoved = (args) => updateEvent(args.e);
    dpm.onEventMoved = (args) => updateEvent(args.e);

    dpc.onEventResized = (args) => updateEvent(args.e);
    dpm.onEventResized = (args) => updateEvent(args.e);

    dpc.onEventMove = (args) => disableEventMoveResize(args)
    dpm.onEventMove = (args) => disableEventMoveResize(args)

    dpc.onEventResize = (args) => disableEventMoveResize(args)
    dpm.onEventResize = (args) => disableEventMoveResize(args)
}

function disableEventMoveResize(args) {
    if (args.e.data.calendarCode === calendarCodes.absence
        || args.e.data.calendarCode === calendarCodes.travelOrder
        || args.e.data.calendarTaskCode === calendarTaskCodes.document) {

        args.preventDefault();
    }
}

function updateDatesTitle() {
    const calendarType = $(selectors.calendarType).val();

    if (calendarType === calendarTypes.list) {
        const firstDay = new DayPilot.Date(currentListDate).firstDayOfMonth();
        const lastDay = new DayPilot.Date(currentListDate).addMonths(2).lastDayOfMonth();

        const startFormatted = firstDay.toString("d MMM");
        const endFormatted = lastDay.toString("d MMM yyyy");

        $(selectors.currentDatesTitle).text(`${startFormatted} - ${endFormatted}`);
        return;
    }

    const dateProvider = getDateProvider(calendarType);
    const startDate = dateProvider.visibleStart();
    const endDate = (calendarType !== calendarTypes.day) ?
        dateProvider.visibleEnd().addDays(-1) : null;

    if (calendarType === calendarTypes.month) {
        const startFormatted = startDate.toString("d MMM");
        const endFormatted = endDate.toString("d MMM yyyy");
        $(selectors.currentDatesTitle).text(`${startFormatted} - ${endFormatted}`);
        return;
    }

    const title = `${formatDate(startDate)}${endDate ? ` - ${formatDate(endDate)}` : ""}`;
    $(selectors.currentDatesTitle).text(title);
}

function formatDate(date) {
    return date.toString("d MMM");
}

function openModalForNewEvent(start, end) {
    const defaultOrganizer = $(selectors.defaultOrganizer).val();
    const title = $(selectors.newEventLoc).val();
    $(selectors.modalTitle).text(title);
    $(selectors.deleteButton).prop('disabled', true);
    clearModalFields();
    $(selectors.eventStart).val(start.toString($("#DateTimeFormat").val()));
    $(selectors.eventEnd).val(end.toString($("#DateTimeFormat").val()));
    $(selectors.addEventModal).modal('show');
    $(selectors.organizer).val(defaultOrganizer);
    $(selectors.organizer).trigger('change');

    updateParticipantsList();
}

function openModalForEditEvent(event) {
    if (event.data.calendarCode === calendarCodes.absence
        || event.data.calendarCode === calendarCodes.travelOrder
        || event.data.calendarTaskCode === calendarTaskCodes.document) {
        return;
    }


    $(selectors.deleteButton).prop('disabled', false);
    $(selectors.modalTitle).text($(selectors.editEventLoc).val());
    $(selectors.eventId).val(event.id());
    $(selectors.calendarQId).val(event.data.calendarQId);
    $(selectors.eventName).val(event.text());
    $(selectors.selectedCase).text(event.data.case);
    $(selectors.eventStart).val(event.start().toString($("#DateTimeFormat").val()));
    $(selectors.eventEnd).val(event.end().toString($("#DateTimeFormat").val()));
    $(selectors.eventLocation).val(event.data.location);
    $(selectors.eventDescription).val(event.data.description);

    updateSelectedDropdownValue(selectors.organizer, event.data.organizerId);
    updateSelectedDropdownValue(selectors.eventCase, event.data.case);

    updateParticipantsList();
    updateSelectedParticipants(event.data.participantIds);

    $(selectors.addEventModal).modal('show');
}

function updateSelectedDropdownValue(selector, value) {
    if ($(selector).find(`option[value='${value}']`).length === 0) {
        $(selector).append(new Option(value, value, true, true)).trigger('change');
    } else {
        $(selector).val(value).trigger('change');
    }
}

function updateSelectedParticipants(participantIds) {
    if (!participantIds) {
        $(selectors.participants).val(null).trigger('change')
        return;
    }

    const ids = Array.isArray(participantIds) ? participantIds : [participantIds];
    $(selectors.participants).val(ids).trigger('change');
}

function clearModalFields() {
    const parentCase = $(selectors.parentCase).val();

    $(selectors.eventId).val('');
    $(selectors.calendarQId).val('');
    $(selectors.eventName).val('');
    $(selectors.eventCase).val(parentCase);
    $(selectors.eventLocation).val('');
    $(selectors.eventDescription).val('');
    $(selectors.eventStart).val('');
    $(selectors.eventEnd).val('');
    $(selectors.participants).val(null).trigger('change');

    $(selectors.eventCase).trigger('change');
}

function disableInteractions() {
    $(selectors.saveButton).prop('disabled', true);
    $(selectors.deleteButton).prop('disabled', true);
    dpc.eventMoveHandling = "Disabled";
    dpc.eventResizeHandling = "Disabled";
    dpm.eventMoveHandling = "Disabled";
    dpm.eventResizeHandling = "Disabled";
}

function enableInteractions() {
    $(selectors.saveButton).prop('disabled', false);
    $(selectors.deleteButton).prop('disabled', false);
    dpc.eventMoveHandling = "Update";
    dpc.eventResizeHandling = "Update";
    dpm.eventMoveHandling = "Update";
    dpm.eventResizeHandling = "Update";
}

function addEvent() {
    disableInteractions();
    const eventId = $(selectors.eventId).val();
    const eventName = $(selectors.eventName).val();
    const eventCase = $(selectors.eventCase).val();
    const eventStart = $(selectors.eventStart).val();
    const eventEnd = $(selectors.eventEnd).val();
    const eventLocation = $(selectors.eventLocation).val();
    const eventDescription = $(selectors.eventDescription).val();
    const organizerId = $(selectors.organizer).val();
    const participantIds = $(selectors.participants).val();

    if (eventId) {
        updateEventById(eventId, eventName, eventCase, eventStart, eventEnd, eventLocation, eventDescription, organizerId, participantIds);
    } else {
        createNewEvent(eventName, eventCase, eventStart, eventEnd, eventLocation, eventDescription, organizerId, participantIds);
    }
}

function createNewEvent(eventName, eventCase, eventStart, eventEnd, eventLocation, eventDescription, organizerId, participantIds) {
    disableButton("save-button", "#save-button", "fa fa-check m-r-xs")
    $.ajax({
        url: $(selectors.addEventURL).val(),
        type: 'POST',
        data: {
            Text: eventName,
            Case: eventCase,
            Start: eventStart,
            End: eventEnd,
            Location: eventLocation,
            Description: eventDescription,
            OrganizerId: organizerId,
            ParticipantIds: participantIds
        },
        success: handleAddEventSuccess,
        error: handleAjaxError
    });
}

function updateEventById(eventId, eventName, eventCase, eventStart, eventEnd, eventLocation, eventDescription, organizerId, participantIds) {
    disableButton("save-button", "#save-button", "fa fa-check m-r-xs")
    disableInteractions();

    $.ajax({
        url: $(selectors.updateEventURL).val(),
        type: 'POST',
        data: {
            Id: eventId,
            Text: eventName,
            Case: eventCase,
            Start: eventStart,
            End: eventEnd,
            Location: eventLocation,
            Description: eventDescription,
            OrganizerId: organizerId,
            ParticipantIds: participantIds,
        },
        success: handleAddEventSuccess,
        error: handleAjaxError
    });

}

function handleAddEventSuccess(response) {
    if (!response.success) {
        //TODO Uncomment when emailing data is ready
        //$().customModal({
        //    destroyOnClose: true,
        //    showCloseButton: true,
        //    type: "alert",
        //    text: response.message,
        //});
        enableButton("save-button", "#save-button", "fa fa-check m-r-xs")
        enableInteractions();
    }

    if (response.success || response.isEventCreated) {
        enableButton("save-button", "#save-button", "fa fa-check m-r-xs")
        $(selectors.addEventModal).modal('hide');
        loadEvents();
    }
}

function handleAjaxError(error) {
    $().customModal({
        destroyOnClose: true,
        showCloseButton: true,
        type: "alert",
        text: "An error occurred: " + error,
    });
    enableInteractions();
    enableButton("save-button", "#save-button", "fa fa-check m-r-xs")
}

function loadEvents() {
    const calendarType = $(selectors.calendarType).val();
    let dateFrom, dateTo;

    if (calendarType === calendarTypes.list) {
        const showPastEvents = document.getElementById('show-past-events').checked;
        const today = new Date();
        today.setHours(0, 0, 0, 0);

        if (showPastEvents) {
            dateFrom = new Date(currentListDate.getFullYear(), currentListDate.getMonth(), -60, 0);
        } else {
            dateFrom = today;
        }

        dateTo = new Date(currentListDate.getFullYear(), currentListDate.getMonth() + 60, 0);
    } else {
        const dateProvider = getDateProvider(calendarType);
        dateFrom = dateProvider.visibleStart();
        dateTo = dateProvider.visibleEnd();
    }

    const data = {
        Organizers: $("#Organizers").val(),
        Cases: $(".document-head #Cases").val(),
        CalendarTypes: $(selectors.eventTypes).val(),
        DateFrom: dateFrom,
        DateTo: dateTo
    };

    $.ajax({
        url: $(selectors.eventsListURL).val(),
        data: JSON.stringify(data),
        type: "POST",
        contentType: "application/json",
        dataType: "json",
        success: updateEvents,
        error: handleAjaxError
    });
}

function convertDate(msString) {
    const timestamp = parseInt(msString.match(/\d+/)[0]);
    return new Date(timestamp);
}

function updateEvents(response) {
    const updatedEventsResponse = response.CalendarEvents.map(item => ({
        id: item.Id,
        text: item.Text,
        case: item.Case,
        caseView: item.CaseView,
        location: item.Location,
        description: item.Description,
        start: convertToLocalDateTime(item.Start),
        end: convertToLocalDateTime(item.End),
        organizer: item.Organizer,
        organizerId: item.OrganizerId,
        participantIds: item.ParticipantIds,
        calendarCode: item.CalendarCode,
        calendarTaskCode: item.CalendarTaskCode,
        calendarEntryTypeName: item.CalendarEntryTypeName,
        color: item.Color,
        calendarQId: item.CalendarQId
    }));

    const documentEventsMapped = response.DocumentEvents.map(item => {
        return {
            id: item.Id,
            text: item.Text || '',
            caseView: '',
            start: convertToLocalDateTime(item.End),
            end: convertToLocalDateTime(item.End),
            organizer: '',
            calendarCode: item.CalendarCode,
            calendarTaskCode: item.CalendarTaskCode,
            location: '',
            color: item.Color
        };
    });


    eventTasks = response.DocumentEvents.map(task => ({
        ...task,
        Start: convertDate(task.Start),
        End: convertDate(task.End),
    }));

    const combinedEvents = updatedEventsResponse.concat(documentEventsMapped);

    dpc.events.list = updatedEventsResponse;
    dpm.events.list = combinedEvents;

    enableInteractions();
    updateCalendarView();
}

function convertToLocalDateTime(dateTime) {
    return moment.utc(dateTime).local().format('YYYY-MM-DDTHH:mm:ss');
}

function updateCalendarView() {
    const calendarType = $(selectors.calendarType).val();

    if (calendarType !== calendarTypes.list) {
        const dateProvider = getDateProvider(calendarType);
        dateProvider.update();
    } else {
        renderEventsList();
    }
}

function switchCalendarView(viewType) {

    if (!viewType) {
        viewType = calendarTypes.week;
        $(selectors.calendarType).val(viewType);
    }

    $(selectors.dpc).hide();
    $(selectors.dpm).hide();
    $(selectors.dpList).hide();
    $(selectors.showPastEventsContainer).hide();


    if (viewType === calendarTypes.list) {
        $(selectors.dpList).show();
        $(selectors.calendarNavigation).hide();
        $(selectors.showPastEventsContainer).show();
        renderEventsList();
    } else {
        $(selectors.calendarNavigation).show();
        if (viewType === calendarTypes.month) {
            $(selectors.dpm).show();
        } else {
            $(selectors.dpc).show();
        }
    }

    const dateProvider = getDateProvider(viewType);
    if (dateProvider) {
        dateProvider.viewType = capitalizeFirstLetter(viewType);
        dateProvider.update();
    }
    updateDatesTitle();
}

function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

function clearSelections() {
    clearModalFields();
    dpc.clearSelection();
    dpm.clearSelection();
}

function updateEvent(event) {
    disableInteractions();

    const eventId = event.id();
    const eventName = event.text();
    const eventCase = event.data.case;
    const eventLocation = event.data.location;
    const eventDescription = event.data.description;
    const eventStart = event.start().value;
    const eventEnd = event.end().value;
    const organizerId = event.data.organizerId;
    const participantIds = event.data.participantIds;

    $.ajax({
        url: $(selectors.updateEventURL).val(),
        type: 'POST',
        data: {
            Id: eventId,
            Text: eventName,
            Case: eventCase,
            Start: eventStart,
            End: eventEnd,
            Location: eventLocation,
            Description: eventDescription,
            OrganizerId: organizerId,
            ParticipantIds: participantIds
        },
        success: handleAddEventSuccess,
        error: handleAjaxError
    });
}

function deleteEvent(calendarQId) {
    $.ajax({
        url: $(selectors.deleteEventURL).val(),
        type: 'DELETE',
        data: { calendarQId },
        success: function (response) {
            if (!response.success) {
                $().customModal({
                    destroyOnClose: true,
                    showCloseButton: true,
                    type: "alert",
                    text: response.message,
                });
                enableButton("delete-button", "#delete-button", "fa fa-trash m-r-xs")
                enableInteractions();
            }

            if (response.success || response.isEventDeleted) {
                enableButton("delete-button", "#delete-button", "fa fa-trash m-r-xs")
                $(selectors.addEventModal).modal('hide');
                loadEvents();
            }
        },
        error: handleAjaxError
    });
}

function disableButton(buttonName, buttonId, icon) {
    swapLoadingIcon(true, buttonName, icon);
    $(buttonId).addClass("print-btn-disable");
}

function enableButton(buttonName, buttonId, icon) {
    swapLoadingIcon(false, buttonName, icon);
    $(buttonId).removeClass("print-btn-disable");
}

function updateParticipantsList() {
    const selectedOrganizerId = $(selectors.organizer).val();

    $(selectors.participants + ' option').prop('disabled', false).show();

    $(selectors.participants + ' option[value="' + selectedOrganizerId + '"]')
        .prop('disabled', true)
        .prop('selected', false)
        .hide();

    $(selectors.participants).selectpicker('refresh');
}

function initializeEventsList() {
    let sortDirection = 'desc';

    $('.sortable').click(function () {
        const icon = $(this).find('i');
        sortDirection = sortDirection === 'desc' ? 'asc' : 'desc';

        icon.removeClass('fa-sort fa-sort-up fa-sort-down')
            .addClass(sortDirection === 'desc' ? 'fa-sort-down' : 'fa-sort-up');

        renderEventsList(sortDirection);
    });
}

function renderEventsList(sortDirection) {
    if (!sortDirection) {
        sortDirection = 'asc';
    }

    const pageSize = Math.ceil(($('#dpList').height() / 40));
    const currentScrollTop = $('#dpList').scrollTop();
    const visibleStart = Math.floor(currentScrollTop / 40);

    const allEvents = [...dpc.events.list]
        .filter((event, index, self) =>
            index === self.findIndex((e) => e.id === event.id)
        )
        .sort((a, b) => {
            const dateA = new Date(a.start);
            const dateB = new Date(b.start);
            return sortDirection === 'asc' ? dateA - dateB : dateB - dateA;
        });

    if (!allEvents || allEvents.length === 0) {
        const noEventsMessage = $('#NoEventsFoundLoc').val();
        $('#eventsList').html(`
            <tr>
                <td colspan="6" class="text-center text-muted py-4">
                    ${noEventsMessage}
                </td>
            </tr>
        `);
        return;
    }

    const visibleEvents = allEvents.slice(visibleStart, visibleStart + pageSize + 10);

    const html = visibleEvents.map(event => `
        <tr>
            <td class="col-date text-center">${moment(event.start).format('DD.MM.YYYY.')}</td>
            <td class="col-type text-center">
                <span class="event-color" style="background-color: ${event.color}"></span>
            </td>
            <td class="col-duration text-center">${moment(event.start).format('HH:mm')} - ${moment(event.end).format('HH:mm')}</td>
            <td class="col-event">${event.text || ''}</td>
            <td class="col-organizer">${event.organizer || ''}</td>
            <td class="col-case">
                ${event.case ? `<a href="${$(selectors.editCaseUrl).val()}?costDrv=${event.case}" class="case-link">${event.case}</a>` : ''}
            </td>
        </tr>
    `).join('');

    $('#eventsList').html(html);
}
