/**
 * @author 1902 Software
 * @copyright Copyright © 2023 1902 Software (https://1902software.com/magento/)
 * @package WriteTextAI_WriteTextAI
 */

define([
    'jquery',
    'uiComponent',
    'WriteTextAI_WriteTextAI/js/model/edit',
    'WriteTextAI_WriteTextAI/js/categories/model/edit',
    'WriteTextAI_WriteTextAI/js/model/history-log',
    'mage/translate',
    'mage/calendar',
    'accordion',
    'Magento_Ui/js/modal/modal'
], function ($, Component, editData, categoyEditData, historyLog, $t) {
    'use strict';

    /**
     * @var {Component} self
     */
    var self;

    return Component.extend({
        defaults: {
            historyLogModal: null,
            historyLogModalSelector: '',
            users: [],
            userOptionCaption: $t('Filter by user'),
            formSelector: '',
            accordionSelector: '',
            historyEntries: [],
            nextPageToken: '',
            append: false,
            isLoading: false,
            isLastPage: false,
            storeId: 0,
            recordId: null,
            categoryId: null,
            hitoryType: null,
            classes: {
                modalClass: 'wtai-edit-history-log',
                overlayClass:
                    'modals-overlay wtai-history-log-overlay'
            },
            selectors: {
                modal: '.wtai-edit-history-log',
                overlay: '.wtai-history-log-overlay',
                gridButton: '.page-header-actions .wtai-history-log.action',
                startDateCalendar: '.wtai-calendar[name="start_date"]',
                endDateCalendar: '.wtai-calendar[name="end_date"]'
            },
            startDate: null,
            endDate: null
        },

        /** @inheritdoc */
        initObservable: function () {
            this._super().observe([
                'users',
                'historyEntries',
                'nextPageToken',
                'isLoading',
                'isLastPage',
                'storeId',
                'recordId',
                'startDate',
                'endDate',
                'historyType'
            ]);

            return this;
        },

        /** @inheritdoc */
        initialize: function () {
            this._super();

            self = this;

            this.initModal();

            historyLog.recordId.subscribe(function (recordId) {
                $(self.formSelector)[0].reset();
                self.reset();
                self.recordId(recordId);
            });

            historyLog.storeId.subscribe(function (storeId) {
                self.storeId(storeId);
            });

            historyLog.users.subscribe(function (users) {
                self.users(users);
                $(self.selectors.gridButton).prop('disabled', false);
            });

            historyLog.update.subscribe(function (update) {
                if (update) {
                    self.submitForm($(self.formSelector));
                } else {
                    self.historyEntries([]);
                    self.reset();
                }
            });

            this.startDate.subscribe(function (startDate) {
                $(self.selectors.endDateCalendar).datepicker(
                    'option',
                    'minDate',
                    new Date(startDate)
                );
            });

            this.endDate.subscribe(function (endDate) {
                $(self.selectors.startDateCalendar).datepicker(
                    'option',
                    'maxDate',
                    new Date(endDate)
                );
            });
        },

        /**
         * Initialize history log modal.
         */
        initModal: function () {
            this.historyLogModal = $(this.historyLogModalSelector).modal({
                type: 'slide',
                title: $.mage.__('History log'),
                innerScroll: true,
                modalClass: self.classes.modalClass,
                overlayClass: self.classes.overlayClass,
                buttons: [],
                opened: function () {
                    $(self.formSelector)[0].reset();
                    self.reset();
                    self.submitForm($(self.formSelector));
                    self.bindCalendar();
                    self.bindFilter();
                    self.adjustZIndex();
                },
                closed: function () {
                    $(self.selectors.overlay).remove();
                    self.historyEntries([]);
                    self.reset();
                    self.endDate(null);
                    self.startDate(null);
                    $('.wtai-calendar').datepicker(
                        'option',
                        {
                            minDate: null,
                            maxDate: new Date()
                        }
                    );
                }
            });
        },

        /**
         * Bind date filter calendar.
         */
        bindCalendar: function () {
            $('.wtai-calendar').calendar({
                dateFormat: 'Y-m-d',
                maxDate: new Date(),
                buttonText: "",
            });
        },

        /**
         * Bind accordion.
         */
        bindAccordion: function () {
            $(self.accordionSelector).accordion({
                active: [],
                collapsible: true,
                openedState: '_show',
                closedState: '_hide',
                multipleCollapsible: true,
                trigger: '[data-role=trigger]'
            });
        },

        /**
         * Bind filter.
         */
        bindFilter: function () {
            $(self.formSelector).on('submit', function (e) {
                e.preventDefault();
                self.reset();
                self.submitForm($(this));
            });
        },

        /**
         * Submit filter form.
         *
         * @param {Element} form
         * @returns {void}
         */
        submitForm: function (form) {
            this.ajaxSubmit(form);
        },

        /**
         * Send filter form ajax request.
         *
         * @param {Element} form
         * @returns {void}
         */
        ajaxSubmit: function (form) {
            var formData = new FormData(form[0]),
                settings = {};

            if (self.nextPageToken().length > 0) {
                formData.append('token', self.nextPageToken());
            }

            if (self.isLoading()) {
                return;
            }

            if (formData.get('start_date') && !this.isDateValid(formData.get('start_date'))) {
                return;
            }

            if (formData.get('end_date') && !this.isDateValid(formData.get('end_date'))) {
                return;
            }

            self.isLoading(true);

            settings = {
                url: form.attr('action'),
                data: formData,
                type: 'post',
                dataType: 'json',
                processData: false,
                contentType: false,
                beforeSend: function () {
                    if (!self.append) {
                        self.historyEntries([]);
                    }
                }
            };

            if (self.recordId()) {
                settings.showWriteTextAILoader = true;
            }

            $.ajax(settings)
                .done(function (response) {
                    if (response.success) {
                        Object.keys(response.entries).forEach(key => {
                            self.historyEntries.push(response.entries[key]);
                        });

                        if (response.next_page_token.length === 0) {
                            self.isLastPage(true);
                        }

                        self.nextPageToken(response.next_page_token);
                        self.bindAccordion();
                    }
                })
                .always(function () {
                    self.isLoading(false);
                });
        },

        /**
         * Get text type label.
         *
         * @param {String} type
         * @returns {String}
         */
        getTextTypeLabel: function (type) {
            var mapping = {
                'page title': $t('Meta title'),
                'page description': $t('Meta description'),
                'product description': $t('Description'),
                'excerpt': $t('Short description'),
                'open graph text': $t('Open Graph text')
            };

            return mapping[type] || type;
        },

        /**
         * Open product edit page.
         *
         * @param {Number} recordId
         * @param {Number} storeId
         *
         * @returns {void}
         */
        showProduct: function (recordId, storeId) {
            $(self.historyLogModalSelector).modal('closeModal');

            if (self.historyType() == 'Category') {
                var category = { categoryId: recordId, storeId: storeId };
                categoyEditData.currentCategory(category);
            } else {
                var product = { productId: recordId, storeId: storeId };
                editData.currentProduct(product);
            }
        },

        /**
         * Load more history entries.
         */
        loadMore: function () {
            self.append = true;
            self.submitForm($(self.formSelector));
        },

        /**
         * Reset history log.
         */
        reset: function () {
            self.append = false;
            self.isLastPage(false);
            self.nextPageToken('');
        },

        /**
         * make sure history log is over edit page modal
         */
        adjustZIndex: function () {
            var mainModalZIndex = $(
                '.wtai-edit-modal.wtai-edit-main'
            ).css('z-index'),
                overlayZIndex = mainModalZIndex + 1;

            $(self.selectors.modal).css('z-index', overlayZIndex + 1);
            $(self.selectors.overlay).css('z-index', overlayZIndex);
        },

        /**
         * Validate date string.
         *
         * @param {String} dateStr
         * @returns {Boolean}
         */
        isDateValid: function (dateStr) {
            return !isNaN(new Date(dateStr));
        }
    });
});
