import CastorcitoForm from './components/Form/castorcito_form.js';
import CastorcitoGlobalMixin from './castorcito_global_mixin.js';

const fields = drupalSettings.field_components;
Object.entries(fields).forEach(([key, field]) => {
  const app = Vue.createApp({
    components: {
      'castorcito-form': CastorcitoForm
    },
    data() {
      const isUniqueComponent = field.components.length === 1 && field.cardinality === 1;
      const componentList = Object.entries(field.components).reduce((acc, [key, value]) => {
        acc[value] = drupalSettings.components[value].label;
        return acc;
      }, {});

      return {
        formData: [],
        showButtonAddComponent: true,
        componentList,
        isUniqueComponent,
        defaultTranslations: drupalSettings.default_translations
      };
    },
    mounted() {
      const textareas = document.querySelectorAll(`textarea[name^="${key}["]`);
      textareas.forEach((textarea) => {
        if (textarea.value) {
          try {
            let textareaJson = JSON.parse(textarea.value);
            this.setFormData('', textarea, textareaJson);
          } catch (error) {
            console.error(`Error parsing JSON in textarea: ${error.message}`);
          }
        }
        else {
          if (this.isUniqueComponent) {
            this.setFormData(field.components[0], textarea);
          }
        }
      });
    },
    methods: {
      setFormData(type, textarea = {}, storedModel = {}) {
        let component = {};
        let model = {};
        if (type) {
          component = drupalSettings.components?.[type];
          model = structuredClone(component);
          if (!component) {
            console.warn(`Component ID ${type} was not found.`);
            return;
          }
        }

        const fieldsSettings = drupalSettings.components_fields_settings[storedModel.type || type];
        if (Object.keys(storedModel).length !== 0) {
          const definedModel = drupalSettings.components[storedModel.type];
          const mergeModel = this.mergeModel(storedModel, definedModel);
          model = this.orderFields(mergeModel, fieldsSettings);
        }
        const componentId = storedModel.type || type;

        textarea.value = JSON.stringify(model);

        this.formData.push({
          componentModel: model,
          fieldsSettings: fieldsSettings,
          fieldNameDrupal: key,
          componentId: componentId,
          componentOverriddenSettings: field.overridden_components_settings[componentId]
        });

        if (field.cardinality !== -1 && field.cardinality <= this.formData.length) {
          this.handleToggleShowButton(false);
        }
      },
      orderFields(component, fieldsSettings) {
        if (!fieldsSettings?.order_fields || !component?.fields) {
          return component;
        }

        const orderedFields = {};
        fieldsSettings.order_fields.forEach((key) => {
          const field = component.fields[key];
          if (field) {
            if (field.type === 'container' && Array.isArray(field.items)) {
              field.items = field.items.map((item) => {
                const itemSettings = drupalSettings.components_fields_settings[item.type];
                return this.orderFields(item, itemSettings);
              });
            }
            if (field.type === 'advanced_container' && Array.isArray(field.items)) {
              field.items = field.items.map((item) => {
                const itemHeadSettings = drupalSettings.components_fields_settings[item.head.type];
                item.head = this.orderFields(item.head, itemHeadSettings);
                const itemBodySettings = drupalSettings.components_fields_settings[item.body.type];
                item.body = this.orderFields(item.body, itemBodySettings);
                return item;
              });
            }

            orderedFields[key] = field;
          }
        });

        component.fields = orderedFields;
        return component;
      },
      addComponent(event) {
        const parent = event.target.parentElement;

        if (field.components.length === 1 && field.cardinality !== 1) {
          this.setFormData(field.components[0]);
        }
        else {
          const selectElement = parent.querySelector(`#${key}_select_component`);

          if (selectElement.value === '') {
            selectElement.reportValidity();
            selectElement.focus();
          }
          else {
            this.setFormData(selectElement.value);
          }
        }

        if (field.cardinality === -1) {
          this.triggerAddAnotherComponent(field.field_name_class);
        }
      },
      async pasteComponent(event) {
        try {
          const component = JSON.parse(await navigator.clipboard.readText());
          const componentModel = component.componentModel;
          const fieldName = event.target.parentElement.getAttribute('data-field-name');
          const field = drupalSettings.field_components[fieldName];
          if (!field.components.includes(componentModel['type'])) {
            this.actionMessages(event, this.defaultTranslations.not_valite_to_paste);
            return;
          }
          const index = this.formData.length;
          const textarea = document.querySelectorAll(`textarea[name^="${fieldName}[${index}]"]`);
          componentModel.label = componentModel.label + ' - ' + this.defaultTranslations.paste;
          this.setFormData('', textarea[0], componentModel);
          this.actionMessages(event, this.defaultTranslations.paste_component);
          if (field.cardinality === -1) {
            this.triggerAddAnotherComponent(field.field_name_class);
          }
        }
        catch (err) {
          this.actionMessages(event, this.defaultTranslations.not_valite_to_paste);
          console.error("Paste error:", err);
        }
      },
      handleToggleShowButton(show) {
        this.showButtonAddComponent = show;
      },
      mergeModel(storedModel, definedModel) {
        if (typeof storedModel !== 'object' || storedModel === null) return {};
        if (typeof definedModel !== 'object' || definedModel === null) return storedModel;

        const result = {};
        for (const key in definedModel) {
          if (!storedModel.hasOwnProperty(key)) {
            result[key] = structuredClone(definedModel[key]);
          }
          else if (Array.isArray(storedModel[key]) && Array.isArray(definedModel[key])) {
            result[key] = storedModel[key].map((item, index) => {
              if (typeof item === 'object' && item !== null) {
                const itemDefinedModel = structuredClone(drupalSettings.components[item.type]);
                return this.mergeModel(item, itemDefinedModel);
              }
              return item;
            });
          }
          else if (typeof storedModel[key] === 'object' && typeof definedModel[key] === 'object') {
            result[key] = this.mergeModel(storedModel[key], definedModel[key]);
          }
          else {
            result[key] = storedModel[key];
          }
        }

        return result;
      },
      isCollapseComponentEnabled() {
        if (!this.isUniqueComponent) {
          return false;
        }

        const { componentOverriddenSettings, fieldsSettings } = this.formData[0] || {};
        return (
          componentOverriddenSettings?.settings?.collapse_component ??
          fieldsSettings?.settings.collapse_component
        );
      },
    }
  });

  // Define globals methods
  app.mixin(CastorcitoGlobalMixin);

  app.mount(`#app_${key} .castorcito-form-container`);
});
