<template>
  <div
    class="form-section-container"
    :style="{ borderBottom: props.section.df.hide_border ? 'none' : '' }"
  >
    <div
      :class="[
        'form-section',
        hovered ? 'hovered' : '',
        store.selected(section.df.name) ? 'selected' : '',
      ]"
      :title="section.df.fieldname"
      @click.stop="selectSection"
      @mouseover.stop="hovered = true"
      @mouseout.stop="hovered = false"
    >
      <div
        :class="[
          'section-header',
          section.df.label || section.df.collapsible ? 'has-label' : '',
          collapsed ? 'collapsed' : '',
        ]"
        :hidden="!section.df.label && store.readOnly"
      >
        <div class="section-label">
          <EditableInput
            :text="section.df.label"
            :placeholder="t('Section Title')"
            v-model="section.df.label"
          />
          <div
            v-if="section.df.collapsible"
            class="collapse-indicator"
          >
            <Icon :icon="collapsed ? 'mdi:chevron-down' : 'mdi:chevron-up'" class="icon-sm" />
          </div>
        </div>
        <Dropdown v-if="!store.readOnly" :options="options" @click.stop />
      </div>
      <div v-if="section.df.description" class="section-description">
        {{ section.df.description }}
      </div>
      <div
        class="section-columns"
        :class="{
          hidden: section.df.collapsible && collapsed,
          'has-one-column': section.columns.length === 1,
        }"
      >
        <draggable
          class="section-columns-container"
          v-model="section.columns"
          group="columns"
          item-key="id"
          :delay="isTouchScreenDevice() ? 200 : 0"
          :animation="200"
          :easing="store.getAnimation"
          :disabled="store.readOnly"
        >
          <template #item="{ element }">
            <Column
              :section="section"
              :column="element"
              :data-is-user-generated="store.isUserGeneratedField(element)"
            />
          </template>
        </draggable>
      </div>
    </div>
  </div>
</template>

<script setup>
import draggable from "vuedraggable";
import Column from "./Column.vue";
import EditableInput from "./EditableInput.vue";
import Dropdown from "./Dropdown.vue";
import { ref, computed } from "vue";
import { useFormBuilderStore } from "../store";
import {
  sectionBoilerplate,
  moveChildrenToParent,
  confirmDialog,
  isTouchScreenDevice,
} from "../utils";
import { useMagicKeys, whenever } from "@vueuse/core";
import { Icon } from '@iconify/vue';
import { t } from '@/shared/i18n';

const props = defineProps(["tab", "section"]);
const store = useFormBuilderStore();

// delete/backspace to delete the field
const { Backspace } = useMagicKeys();
whenever(Backspace, (value) => {
  if (value && selected.value && store.notUsingInput) {
    removeSection();
  }
});

const hovered = ref(false);
const collapsed = ref(false);
const selected = computed(() => store.selected(props.section.df.name));
const column = computed(() => props.section.columns[props.section.columns.length - 1]);

// section
function addSectionBelow() {
  let index = props.tab.sections.indexOf(props.section);
  props.tab.sections.splice(index + 1, 0, sectionBoilerplate(store.getDf));
}

function isSectionEmpty() {
  return !props.section.columns.some(
    (column) => (store.isCustomizeForm && !column.df.is_custom_field) || column.fields.length
  );
}

function removeSection() {
  if (store.isCustomizeForm && props.section.df.is_custom_field === 0) {
    alert(t("Cannot delete standard field. You can hide it if you want"));
    throw "cannot delete standard field";
  } else if (store.hasStandardField(props.section)) {
    deleteSection();
  } else if (isSectionEmpty()) {
    deleteSection(true);
  } else {
    confirmDialog(
      t("Delete Section"),
      t("Are you sure you want to delete the section? All the columns along with fields in the section will be moved to the previous section."),
      () => deleteSection(),
      t("Delete section"),
      () => deleteSection(true),
      t("Delete entire section with fields")
    );
  }
}

function deleteSection(withChildren) {
  let sections = props.tab.sections;
  let index = sections.indexOf(props.section);

  if (!withChildren) {
    if (index > 0) {
      let prevSection = sections[index - 1];
      if (!isSectionEmpty()) {
        prevSection.columns = [...prevSection.columns, ...props.section.columns];
      }
    } else if (index === 0 && !isSectionEmpty()) {
      sections.unshift({
        df: store.getDf("Section Break"),
        columns: props.section.columns,
        is_first: true,
      });
      index++;
    }
  }

  sections.splice(index, 1);
  store.form.selected_field = null;
}

function selectSection() {
  if (props.section.df.collapsible) {
    collapsed.value = !collapsed.value;
  }
  store.form.selected_field = props.section.df;
}

function moveSectionsToTab() {
  let newTab = moveChildrenToParent(props, "tab", "section", store.form.layout, store.getDf);
  store.form.active_tab = newTab;
}

// column
function addColumn() {
  props.section.columns.push({
    fields: [],
    df: store.getDf("Column Break"),
  });
}

function removeColumn() {
  if (store.isCustomizeForm && column.value.df.is_custom_field === 0) {
    alert(t("Cannot delete standard field. You can hide it if you want"));
    throw "cannot delete standard field";
  } else if (column.value.fields.length === 0 || store.hasStandardField(column.value)) {
    deleteColumn();
  } else {
    confirmDialog(
      t("Delete Column"),
      t("Are you sure you want to delete the column? All the fields in the column will be moved to the previous column."),
      () => deleteColumn(),
      t("Delete column"),
      () => deleteColumn(true),
      t("Delete entire column with fields")
    );
  }
}

function deleteColumn(withChildren) {
  let columns = props.section.columns;
  let index = columns.length - 1;

  if (withChildren && index === 0 && columns.length === 1) {
    if (column.value.fields.length === 0) {
      alert(t("Section must have at least one column"));
      throw "section must have at least one column";
    }

    columns.unshift({
      df: store.getDf("Column Break"),
      fields: [],
      is_first: true,
    });
    index++;
  }

  if (!withChildren) {
    if (index > 0) {
      let prevColumn = columns[index - 1];
      prevColumn.fields = [...prevColumn.fields, ...column.value.fields];
    } else {
      if (column.value.fields.length === 0) {
        let nextColumn = columns[index + 1];
        if (nextColumn) {
          nextColumn.is_first = true;
        } else {
          alert(t("Section must have at least one column"));
          throw "section must have at least one column";
        }
      } else {
        columns.unshift({
          df: store.getDf("Column Break"),
          fields: column.value.fields,
          is_first: true,
        });
        index++;
      }
    }
  }

  columns.splice(index, 1);
  store.form.selected_field = null;
}

const options = computed(() => {
  let groups = [
    {
      group: t("Section"),
      items: [
        { label: t("Add section below"), onClick: addSectionBelow },
        { label: t("Remove section"), onClick: removeSection },
      ],
    },
    {
      group: t("Column"),
      items: [{ label: t("Add column"), onClick: addColumn }],
    },
  ];

  if (props.section.columns.length > 1) {
    groups[1].items.push({
      label: t("Remove column"),
      tooltip: t("Remove last column"),
      onClick: removeColumn,
    });
  } else if (props.section.columns[0].fields.length) {
    groups[1].items.push({
      label: t("Empty column"),
      tooltip: t("Remove all fields in the column"),
      onClick: () => deleteColumn(true),
    });
  }

  if (props.tab.sections.indexOf(props.section) > 0) {
    groups[0].items.push({
      label: t("Move sections to new tab"),
      tooltip: t("Move current and all subsequent sections to a new tab"),
      onClick: moveSectionsToTab,
    });
  }

  return groups;
});
</script>

<style lang="scss" scoped>
.form-section-container {
  border-bottom: 1px solid #e5e7eb;
  background-color: #fff;

  &:last-child {
    border-bottom: none;
  }

  .form-section {
    background-color: inherit;
    border: 1px solid transparent;
    border-radius: 8px;
    padding: 1rem;
    cursor: pointer;

    &:last-child {
      border-bottom-left-radius: 8px;
      border-bottom-right-radius: 8px;
    }

    &.hovered,
    &.selected {
      border-color: #3b82f6;
    }

    .section-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding-bottom: 0.75rem;

      &.collapsed {
        padding-bottom: 0;
      }

      &.has-label {
        display: flex;
      }

      .section-label {
        display: flex;
        align-items: center;

        :deep(span) {
          font-weight: 600;
          color: #111827;
        }

        .collapse-indicator {
          margin-left: 7px;
        }
      }

      .section-actions {
        display: flex;
        gap: 4px;
        align-items: center;
      }
    }

    .section-description {
      margin-bottom: 10px;
      font-size: 12px;
      color: #6b7280;
    }

    .section-columns-container {
      display: flex;
      min-height: 2rem;
      border-radius: 8px;
    }
  }
}

.icon-sm {
  width: 14px;
  height: 14px;
}

.hidden {
  display: none;
}
</style>
