class PcSponsorships {

    init() {

        this.baseName = 'purecharity_plugin_sponsorship_settings';
        this.baseClass = 'pc';

        this.config = {
            selectors: {
                input: {
                    showBackLink: `[name="${this.baseName}[show_back_link]"]`,
                    showMoreLink: `[name="${this.baseName}[show_more_link]"]`,
                    pluginStyle: `[name="${this.baseName}[plugin_style]"]`,
                    customFieldInput: `.${this.baseClass}-custom-field-input`,
                    customFieldInputValue: `.${this.baseClass}-custom-field-input-value`,
                    customFieldInputKey: `.${this.baseClass}-custom-field-input-key`,
                    customFieldsValue: `#custom_fields_value`,
                    exampleProgramSlug: `#example-program-slug`,
                },
                link: {
                    addCustomField: `.${this.baseClass}-add-custom-field`,
                    editCustomField: `.${this.baseClass}-edit-custom-field`,
                    saveCustomField: `.${this.baseClass}-save-custom-field`,
                    removeCustomField: `.${this.baseClass}-remove-custom-field`,
                    customFieldsExample: `#custom-fields-example`,
                    customFieldsExampleCancel: `#custom-fields-example-cancel`,
                },
                list: {
                    customFieldLast: `ul.pcs_custom_field:last`,
                    sortableList: `ul.pcs_custom_field.sortable`,
                },
                listItems: {
                    customField: `.${this.baseClass}-custom-field-item`,
                },
                block: {
                    customFieldsLoader: `#custom-fields-loader`,
                    customFieldKey: `.${this.baseClass}-custom-field-key`,
                },
                button: {
                    generateExample: `#generate-example`,
                },
            },
            unlockValue: 'pure-sponsorships-option3',
            markup: {
                customField: `
                <li class="custom_field pc-custom-field-item">
                    <div class="left">

                        <b>Display Value</b>
                        <input type="text" value="Display Value" class="pc-custom-field-input pc-custom-field-input-value">
                        <a href="#" class="edit pc-edit-custom-field">edit</a>
                        <a href="#" class="save pc-save-custom-field">save</a>
                    </div>

                    <div class="right">

                        <b class="pc-custom-field-key">CustomFieldIdentifier</b>
                        <input type="text" value="CustomFieldIdentifier" class="pc-custom-field-input pc-custom-field-input-key">
                        <a href="#" class="edit pc-edit-custom-field">edit</a>
                        <a href="#" class="save pc-save-custom-field">save</a>
                    </div>
                    
                    <div class="options">

                        <a href="#" class="remove pc-remove-custom-field">remove</a>
                    </div>
                    
                    <br style="clear:both" />
                </li>
                `,
            },
        };

        this.domElements = this.prepareDomElements(this.config.selectors);

        this.initDefaults();

        this.initEventHandlers();
    }

    prepareDomElements(selectors) {

        const domElements = {};

        Object.keys(selectors).forEach(function (key, index) {

            const selector = selectors[key];
            if (typeof selector === 'string') {

                domElements[key] = jQuery(selector);
            } else if (typeof selector === 'object') {

                if (typeof domElements[key] === 'undefined') {

                    domElements[key] = {};
                }

                domElements[key] = Object.assign(
                    domElements[key],
                    window.PcSponsorships.prepareDomElements(selector)
                );
            }
        });

        return domElements;
    }

    initDefaults() {

        this.initSortable();
        this.toggleLinkFields();
    }

    initSortable() {

        window.PcSponsorships.domElements.list.sortableList.sortable({
            stop: () => {
                window.PcSponsorships.saveCustomField();
            },
            axis: 'Y'
        });

        window.PcSponsorships.domElements.list.sortableList.disableSelection();
    }

    initEventHandlers() {

        jQuery(document).on('change', [
            window.PcSponsorships.config.selectors.input.showBackLink,
            window.PcSponsorships.config.selectors.input.showMoreLink
        ], this.toggleLinkFields);

        jQuery(document).on('change', window.PcSponsorships.config.selectors.input.pluginStyle, this.handlePluginStyle);

        jQuery(document).on('click', window.PcSponsorships.config.selectors.link.addCustomField, this.handleAddCustomField);

        jQuery(document).on('click', window.PcSponsorships.config.selectors.link.editCustomField, this.handleEditCustomField);

        jQuery(document).on('click', window.PcSponsorships.config.selectors.link.saveCustomField, this.handleSaveCustomField);

        jQuery(document).on('click', window.PcSponsorships.config.selectors.link.removeCustomField, this.handleRemoveCustomField);

        jQuery(document).on('keydown', window.PcSponsorships.config.selectors.input.customFieldInput, this.handleKeydownCustomField);

        jQuery(document).on('click', window.PcSponsorships.config.selectors.link.customFieldsExample, this.handleCustomFieldsExample);

        jQuery(document).on('click', window.PcSponsorships.config.selectors.link.customFieldsExampleCancel, this.handleCustomFieldsExampleCancel);

        jQuery(document).on('click', window.PcSponsorships.config.selectors.button.generateExample, this.handleGenerateExample);
    }

    toggleLinkFields(event) {

        const showBackLink = window.PcSponsorships.domElements.input.showBackLink;
        const showMoreLink = window.PcSponsorships.domElements.input.showMoreLink;

        if (showBackLink.prop('checked')) {
            showBackLink.parents('tr').next().show();
        } else {
            showBackLink.parents('tr').next().hide();
        }

        if (showMoreLink.prop('checked')) {
            showMoreLink.parents('tr').next().show();
        } else {
            showMoreLink.parents('tr').next().hide();
        }
    }

    handlePluginStyle(event) {

        const target = jQuery(event.target);
        const value = target.val();

        const showBackLink = window.PcSponsorships.domElements.input.showBackLink;
        const showMoreLink = window.PcSponsorships.domElements.input.showMoreLink;

        if (value === window.PcSponsorships.config.unlockValue) {
            showBackLink.attr({ disabled: false })
            showMoreLink.attr({ disabled: false })
        } else {
            showBackLink.attr({ disabled: true })
            showMoreLink.attr({ disabled: true })
        }
    }

    handleAddCustomField(event) {

        event.preventDefault();
        window.PcSponsorships.domElements.list.customFieldLast.append(window.PcSponsorships.config.markup.customField);
        return undefined;
    }

    handleEditCustomField(event) {

        event.preventDefault();

        const target = jQuery(event.target).closest(window.PcSponsorships.config.selectors.link.editCustomField);

        target.hide();
        target.parent().find('b').hide();
        target.parent().find('input').show();
        target.parent().find('.save').show();

        return undefined;
    }

    handleSaveCustomField(event) {

        event.preventDefault();

        const target = jQuery(event.target).closest(window.PcSponsorships.config.selectors.link.saveCustomField);
        const text = target.parent().find('input').val();

        if (text.trim().length === 0) {

            alert('Value can\'t be empty.');
            return false;
        }

        target.hide();
        target.parent().find('b').show().text(text);
        target.parent().find('input').hide();
        target.parent().find(window.PcSponsorships.config.selectors.link.editCustomField).show();

        window.PcSponsorships.saveCustomField();

        return undefined;
    }

    saveCustomField() {

        window.PcSponsorships.domElements = window.PcSponsorships.prepareDomElements(window.PcSponsorships.config.selectors);

        const customFields = [];

        window.PcSponsorships.domElements.listItems.customField.each(function () {

            const key = jQuery(this).find(window.PcSponsorships.config.selectors.input.customFieldInputKey).val().trim();
            const value = jQuery(this).find(window.PcSponsorships.config.selectors.input.customFieldInputValue).val().trim();
            const data = `${key}|${value}`;

            customFields.push(data);
        });

        const finalData = customFields.join(';');
        window.PcSponsorships.domElements.input.customFieldsValue.val(finalData);

        return false;
    }

    handleRemoveCustomField(event) {

        event.preventDefault();

        const target = jQuery(event.target).closest(window.PcSponsorships.config.selectors.link.removeCustomField);

        if (confirm('Are you sure you want to remove this field?')) {

            const customField = target.closest(window.PcSponsorships.config.selectors.listItems.customField);

            customField.remove();

            window.PcSponsorships.saveCustomField();
        }

        return false;
    }

    handleKeydownCustomField(event) {

        if (event.keyCode !== 13) { return event; }

        event.preventDefault();

        const target = jQuery(event.target).closest(window.PcSponsorships.config.selectors.input.customFieldInput);

        const saveButton = target.parent().find(window.PcSponsorships.config.selectors.link.saveCustomField);

        saveButton.trigger('click');

        return false;
    }

    handleCustomFieldsExample(event) {

        event.preventDefault();

        const target = jQuery(event.target).closest(window.PcSponsorships.config.selectors.link.customFieldsExample);
        target.hide();

        window.PcSponsorships.domElements.link.customFieldsExampleCancel.show();
        window.PcSponsorships.domElements.block.customFieldsLoader.show();

        return undefined;
    }

    handleCustomFieldsExampleCancel(event) {

        event.preventDefault();

        const target = jQuery(event.target).closest(window.PcSponsorships.config.selectors.link.customFieldsExampleCancel);

        target.hide();
        window.PcSponsorships.domElements.block.customFieldsLoader.hide();

        window.PcSponsorships.domElements.link.customFieldsExample.show();

        return false;
    }

    handleGenerateExample(event) {

        event.preventDefault();

        const target = jQuery(event.target).closest(window.PcSponsorships.config.selectors.button.generateExample);
        target.text('Loading...');

        const sponsorshipId = window.PcSponsorships.domElements.input.exampleProgramSlug.val().trim();

        jQuery.ajax({
            type: 'POST',
            url: window.pcPublicConfig.scripts.ajaxUrl,
            data: {
                action: 'generateSponsorshipsCustomFieldsExample',
                sponsorshipId: sponsorshipId,
            },
            success: (response) => {

                const result = JSON.parse(response);

                if (!result.success) {

                    alert(result.data);
                    return false;
                }

                if (Object.keys(result.data).length === 0) {
                    return false;
                }

                const existingFields = [];
                const exampleFields = result.data;

                Object.keys(exampleFields).forEach((key, index) => {

                    if (window.PcSponsorships.fieldExists(key)) {

                        existingFields.push(key);
                    } else {
                        
                        const value = exampleFields[key];
                        window.PcSponsorships.newExampleCustomField(key, value);
                    }
                });

                window.PcSponsorships.saveCustomField();

                if (existingFields.length > 0) {

                    alert(`The following fields already exist and were not imported:\n${existingFields.join('\n')}`);
                }
            },
            error: function (response) { 
                console.error(response);
            },
            complete: function (response) {
                jQuery('#generate-example').text('Load Example');
            }
        });
    }

    fieldExists(key) {

        let exists = false;
        window.PcSponsorships.domElements.listItems.customField.each(function () {

            const text = jQuery(this).find(window.PcSponsorships.config.selectors.input.customFieldInputKey).val().trim();

            if (
                !exists &&
                text === key
            ) {
                exists = true;
                return exists;
            }
        });

        return exists;
    }

    newExampleCustomField(original, display) {

        const html = '<li class="custom_field pc-custom-field-item">'
            + '<div class="left">'
            + '<b>'+ display +'</b>'
            + '<input type="text" value="'+ display +'" class="pc-custom-field-input pc-custom-field-input-value">'
            + ' <a href="#" class="edit pc-edit-custom-field">edit</a>'
            + ' <a href="#" class="save pc-save-custom-field">save</a>'
            + '</div>'
            + '<div class="right">'
            + '<b>'+ original +'</b>'
            + '<input type="text" value="'+ original +'" class="pc-custom-field-input pc-custom-field-input-key">'
            + ' <a href="#" class="edit pc-edit-custom-field">edit</a>'
            + ' <a href="#" class="save pc-save-custom-field">save</a>'
            + '</div>'
            + '<div class="options">'
            + '<a href="#" class="remove pc-remove-custom-field">remove</a>'
            + '</div>'
            + '<br style="clear:both" />'
            + '</li>';

        window.PcSponsorships.domElements.list.customFieldLast.append(html);
    }
}

window.PcSponsorships = new PcSponsorships;