<template>
  <NuxtLayout name="default" :menu="adminMenu">
    <div class="container-fluid">
      <div class="row justify-content-center">
        <template v-if="canView">
          <!--start: show content if user entered the from title or is edit mode -->
          <div v-if="isFormTitleEntered" class="col">
            <h5 class="mb-4">
              {{ keyValue?.value ?? "عنوان فرم وارد نشده است." }}

              <button-component
                classes="d-inline-flex"
                @click="openNewFormModal"
                buttonText=""
              >
                <span class="tavasi tavasi-Component-242--1"></span>
              </button-component>
            </h5>

            <div class="row no-gutters justify-content-center">
              <div class="col">
                <div class="list-and-actions-container">
                  <!-- load Simple/Tab component -->
                  <keep-alive>
                    <component
                      :ref="formMode"
                      :is="formMode"
                      :formTitleData="form"
                      :newFormItem="newFormItem"
                      @open-new-form-item="openNewFormItem"
                    ></component>
                  </keep-alive>

                  <!--start: form actions ( save/preview form) -->
                  <div
                    class="d-flex justify-content-end mt-5 ms-3 form-actions"
                  >
                    <button-component
                      classes="btn btn-secondary mx-2"
                      @click="showFormPreView"
                      buttonText="پیش نمایش فرم"
                    >
                    </button-component>

                    <button-component
                      classes="btn btn-primary"
                      @click="saveFinalForm"
                      buttonText="ذخیره"
                    >
                    </button-component>
                  </div>
                  <!--end: form actions ( save/preview form) -->
                </div>
              </div>
              <!-- start: create new form element -->
              <div class="col-auto" v-if="showNewFormItem">
                <NewFormItem
                  :key="changeDetectionCounter"
                  @close-new-form-item="closeNewFormItem"
                  @add-item-content="addFormItemToFormElements"
                  :editFormData="editFormData"
                ></NewFormItem>
              </div>
              <!-- end: create new form element -->
            </div>
          </div>
          <!--end: show content if user entered the from title or is edit mode -->
        </template>
        <no-data v-else>
          <the-content-loading v-if="fetchingData"></the-content-loading>

          <div v-else class="d-flex justify-content-center align-items-center">
            <div
              class="alert alert-warning d-flex justify-content-center align-items-center"
            >
              <span
                class="tavasi tavasi-warning-circle color-inherit ms-1 text__32"
              ></span>
              عدم دسترسی
            </div>
          </div>
        </no-data>
      </div>

      <!-- create new form modal -->
      <base-modal
        v-if="showNewFormTitleModal"
        modalSize="modal-md"
        modalTitle="فرم جدید"
        @close="closeFormModal"
        @save="saveFormTitle"
      >
        <form-builder
          ref="titleFormBuilder"
          :formElements="formItem"
          :formData="form"
        ></form-builder>
      </base-modal>

      <!--form preview modal -->
      <base-modal
        v-if="showPreviewModal"
        :showSaveButton="false"
        modalSize="modal-lg"
        modalTitle="فرم پیش نمایش"
        @close="closePreviewModal"
        @save="saveFinalForm"
      >
        <!-- displayMode : horizontal | vertical -->
        <form-builder
          ref="previewFormBuilder"
          displayMode="horizontal"
          :formElements="previewFormItems"
          :formData="previewFormItemsData"
        ></form-builder>
      </base-modal>
    </div>
  </NuxtLayout>
</template>
<script>
import keyValueApi from "~/apis/keyValueApi";
import adminMenu from "~/json/admin/json/menu.json";
// import HttpService from "@services/httpService";
// import { mapActions } from "vuex";
import { mapState, mapActions } from "pinia";
import { useCommonStore } from "~/stores/commonStore";
import { defineAsyncComponent } from "vue";

export default {
  name: "newForm",
  setup() {
    definePageMeta({
      name: "newForm",
      layout: false,
    });
  },
  beforeMount() {
    // this.httpService = new HttpService();
    this.httpService = useNuxtApp()["$http"];
  },
  mounted() {
    this.checkPermisionBeforGetList();
  },
  data() {
    return {
      adminMenu: adminMenu,
      canView: false,
      changeDetectionCounter: 0,
      isFormTitleEntered: false,

      fetchingData: false,
      httpService: undefined,

      // show/hide preview modal
      showPreviewModal: false,
      previewFormItems: [],
      previewFormItemsData: {},

      // show/hide new form title
      showNewFormTitleModal: false,

      showNewFormItem: false,
      newFormItem: undefined,

      formMode: "SimpleForm",
      // formMode: "TabForm",
      // store form-item when user clicked on the table edit button in the simple/tab.
      editFormData: undefined,
      changeDetection: true,

      // form model.
      form: {
        title: "",
        comment: null,
        type: 1,
      },
      keyValue: {
        key: "",
        value: "",
        value_json: null,
        project_id: 0,
        organ_code: 0,
      },
      // FormItem model.
      formItem: {
        title: "",
        items: [
          {
            key: "title",
            label: "عنوان",
            type: "string",
            placeholder: "عنوان را وارد کنید",
            required: "1",
            validation_regex: "{3-100}",
            validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
            multi_select: "0",
            options: [],
          },
          {
            key: "comment",
            label: "توضیحات",
            type: "textarea",
            placeholder: "توضیحات را وارد کنید",
            required: "1",
            validation_regex: "{3-100}",
            validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
            multi_select: "0",
            options: [],
          },
          {
            key: "type",
            label: "نوع",
            type: "select",
            placeholder: "نوع را وارد کنید",
            required: "1",
            validation_regex: "{3-100}",
            validation_error: "عبارت باید حداقل 3 و حداکثر 100 حرف باشد",
            multi_select: "0",
            options: [
              {
                value: 1,
                title: "فرم ساده",
              },
              {
                value: 2,
                title: "فرم چند بخشی",
              },
            ],
          },
        ],
      },
    };
  },
  methods: {
    // ...mapActions(["checkPermissions"]),
    ...mapActions(useCommonStore, ["checkPermissions"]),
    checkPermisionBeforGetList() {
      const isEditMode = Boolean(this.$route.params.id);
      this.checkPermissions({
        permission: isEditMode ? "forms_edit" : "forms_new",
        _this: this,
      })
        .then(() => {
          if (this.$route.params.id) {
            this.getForm(this.$route.params.id)
              .then(() => {
                this.canView = true;
              })
              .catch(() => {
                this.canView = false;
              })
              .finally(() => {
                this.fetchingData = false;
              });
          } else this.openNewFormModal();
        })
        .catch(() => {
          this.canView = false;
        });
    },
    /*
       summary: save final form
       
       description: saving the edited/created form with its meta and table_columns.

       @fires when user clicks on the save button.

       @return void.
    */
    saveFinalForm() {
      if (this.buttonLoading) return;
      this.buttonLoading = true;

      const url =
        this.keyValueUrl() + this.$route.params.id
          ? keyValueApi.forms.edit
          : keyValueApi.forms.add;

      // const formData = this.$refs[this.formMode].localMainFormElements;
      const formData = {};

      formData.value = this.form.title;
      formData.value_json = {
        type: this.formMode == "SimpleForm" ? 1 : 2,
        table_columns: JSON.stringify(formData.table_columns),
        form: JSON.stringify(this.$refs[this.formMode].localMainFormElements),
      };
      // formData.table_columns = null;
      // formData.table_columns =  JSON.stringify(formData.table_columns);

      this.httpService
        .postRequest(url, formData)
        .then((res) => {
          mySwalToast({
            title: res.message,
            html: null,
            icon: "success",
          });
          this.form.meta = JSON.parse(this.form.meta);
          this.form.table_columns = JSON.parse(this.form.table_columns);
        })

        .finally(() => {
          this.buttonLoading = false;
        });
    },
    showFormPreView() {
      this.previewFormItems = this.$refs[this.formMode].localMainFormElements;
      this.showPreviewModal = true;

      setTimeout(() => {
        $("#base-modal").modal({ backdrop: "static", keyboard: false }, "show");
      }, 500);
    },
    // close preview modal
    closePreviewModal() {
      $("#base-modal").modal("hide");

      setTimeout(() => {
        this.showPreviewModal = false;
      }, 500);
    },

    // open new form modal
    openNewFormModal() {
      this.showNewFormTitleModal = true;
      setTimeout(() => {
        $("#base-modal").modal({ backdrop: "static", keyboard: false }, "show");
      }, 500);
    },
    // close new form modal
    closeFormModal() {
      if (!this.$route.params.id) this.$router.push({ name: "formList" });

      $("#base-modal").modal("hide");

      setTimeout(() => {
        this.showNewFormTitleModal = false;
      }, 500);
    },
    // get form details
    async getForm(formId) {
      if (this.fetchingData) return;
      this.fetchingData = true;

      const url = this.keyValueUrl()+ keyValueApi.forms.get;
      return await this.httpService
        .getRequest(url + "/" + formId)
        .then((res) => {
          this.keyValue = res.data;
          // this.form.type = "TabForm";
          // this.openNewFormModal();

          this.form.title = this.keyValue.value;

          let meta = JSON.parse(this.keyValue.value_json);
          this.form.table_columns = meta.table_columns;
          this.form.meta = meta.form;

          if (meta.type == 1) this.formMode = "SimpleForm";
          else if (meta.type == 2) this.formMode = "TabForm";

          this.isFormTitleEntered = true;
        });
    },
    // save new form title
    saveFormTitle() {
      if (this.buttonLoading) return;
      this.buttonLoading = true;

      this.form = this.$refs.titleFormBuilder.localFormData;
      const url =
      this.keyValueUrl() + this.$route.params.id
          ? keyValueApi.forms.edit
          : keyValueApi.forms.add;

      const { title, comment, id = undefined, type } = this.form;
      const formData = {
        title,
        comment,
        id,
        type,
      };

      this.httpService
        .postRequest(url, formData)
        .then((res) => {
          mySwalToast({
            title: "تبریک",
            html: res.message,
            icon: "success",
          });

          this.form = res.data;

          this.form.meta = this.form.meta ? JSON.parse(this.form.meta) : null;
          this.form.table_columns = this.form.table_columns
            ? JSON.parse(this.form.table_columns)
            : null;

          if (type == 1) this.formMode = "SimpleForm";
          else if (type == 2) this.formMode = "TabForm";

          this.isFormTitleEntered = true;

          this.closeFormModal();
        })

        .finally(() => {
          this.buttonLoading = false;
        });
    },

    // new form item methods
    addFormItemToFormElements(newFormItem) {
      this.newFormItem = structuredClone(newFormItem);
    },
    // open new form item panel
    openNewFormItem(data = undefined) {
      this.showNewFormItem = true;
      this.editFormData = data;
      this.changeDetectionCounter += 1;
    },
    // close new form item panel
    closeNewFormItem() {
      this.showNewFormItem = false;
    },
  },
  components: {
    // NewFormItem: () => import("@forms/forms/NewFormItem.vue"),
    // SimpleForm: () => import("@forms/components/SimpleForm.vue"),
    // TabForm: () => import("@forms/components/TabForm.vue"),
    TabForm: defineAsyncComponent(() =>
      import("@/components/admin/components/TabForm.vue")
    ),
    SimpleForm: defineAsyncComponent(() =>
      import("@/components/admin/components/SimpleForm.vue")
    ),
    NewFormItem: defineAsyncComponent(() =>
      import("@/components/admin/components/NewFormItem.vue")
    ),
  },
};
</script>

<style lang="scss">
.list-and-actions-container {
  position: relative;

  .form-actions {
    // position: absolute;
    // bottom: 1em;
    // left: 2em;

    background-image: linear-gradient(to bottom, transparent, #fff);
  }
}
</style>
