<script setup>
import { computed, onBeforeMount } from "vue";
import draggable from "vuedraggable/src/vuedraggable.js";

import NavNodeBranch from "./NavNodeEditor.vue";

defineOptions({ name: "NavNodeEditor" });

import BaseButton from "../../components/base/BaseButton.vue";
import BaseCheckbox from "../../components/base/BaseCheckbox.vue";
import BaseInputText from "../../components/base/BaseInputText.vue";
import BaseSelect from "../../components/base/BaseSelect.vue";
import BaseTag from "../../components/base/BaseTag.vue";

const props = defineProps({
  node: { type: Object, required: true },
  modules: { type: Array, default: () => [] },
  permissions: { type: Array, default: () => [] },
  depth: { type: Number, default: 0 },
  /** Lighter panel when nested under a parent’s “Sub-items” list */
  embedded: { type: Boolean, default: false },
});

const emit = defineEmits(["remove"]);

const moduleOptions = computed(() => [
  { label: "(none)", value: null },
  ...props.modules.map((m) => ({
    label: `${m.label} (${m.slug})`,
    value: m.slug,
  })),
]);

const permissionOptions = computed(() => [
  { label: "(none)", value: null },
  ...props.permissions.map((p) => ({ label: p, value: p })),
]);

const moduleSlugModel = computed({
  get() {
    return props.node.module_slug ?? null;
  },
  set(v) {
    props.node.module_slug = v;
  },
});

const permissionModel = computed({
  get() {
    return props.node.permission ?? null;
  },
  set(v) {
    props.node.permission = v;
  },
});

function ensureChildren() {
  if (!Array.isArray(props.node.children)) {
    props.node.children = [];
  }
}

onBeforeMount(() => {
  ensureChildren();
});

function removeChild(index) {
  ensureChildren();
  props.node.children.splice(index, 1);
}

function removeSelf() {
  emit("remove");
}

const isRoot = computed(() => props.node.key === "root");

const childCount = computed(() => (props.node.children || []).length);

const hierarchyTag = computed(() => {
  if (isRoot.value) {
    return { label: "Root", severity: "info" };
  }
  if (props.depth <= 1) {
    return { label: "Main sidebar item", severity: "success" };
  }
  return { label: "Sub-sidebar link", severity: "secondary" };
});

const panelWrapperClass = computed(() => {
  if (props.embedded) {
    return "rounded-lg bg-surface-50 dark:bg-surface-900/40 border border-surface-200 dark:border-surface-700 p-3 mb-2";
  }
  return "border border-surface-200 dark:border-surface-700 rounded-lg p-4 mb-3 bg-surface-0 dark:bg-surface-950 shadow-[0_1px_2px_rgba(0,0,0,0.04)] dark:shadow-none";
});

const indentStyle = computed(() => {
  if (props.embedded || !props.depth) {
    return {};
  }
  const px = Math.min(props.depth * 12, 48);
  return { marginLeft: `${px}px` };
});
</script>

<template>
  <div :class="panelWrapperClass" :style="indentStyle">
    <div class="flex flex-wrap items-start justify-between gap-3 mb-3">
      <div class="flex flex-wrap items-center gap-2 min-w-0">
        <span class="font-semibold text-surface-900 dark:text-surface-0 truncate">
          {{ isRoot ? "Navigation root" : (node.label || "Untitled") }}
        </span>
        <BaseTag
          :value="hierarchyTag.label"
          :severity="hierarchyTag.severity"
          class="text-xs shrink-0"
        />
        <code
          v-if="!isRoot"
          class="text-xs text-surface-500 dark:text-surface-400 font-normal truncate max-w-[12rem] sm:max-w-xs"
          >{{ node.key }}</code
        >
      </div>
      <BaseButton
        v-if="!isRoot"
        variant="danger"
        icon="trash"
        text
        rounded
        :icon-only="true"
        aria-label="Remove node"
        type="button"
        @click="removeSelf"
      />
    </div>

    <p
      v-if="isRoot"
      class="text-xs text-surface-500 dark:text-surface-400 m-0 mb-3 leading-relaxed"
    >
      Root of the sidebar tree — edit the entries below; nested links appear in
      the vertical sub-sidebar when applicable.
    </p>

    <section class="mb-5">
      <h3
        class="text-sm font-semibold text-surface-800 dark:text-surface-100 m-0 mb-2"
      >
        Sub-items
        <span
          class="font-normal text-surface-500 dark:text-surface-400"
          >({{ childCount }})</span
        >
      </h3>
      <p
        v-if="!childCount"
        class="text-sm text-surface-500 dark:text-surface-400 mb-0"
      >
        No sub-items under this node.
      </p>
      <draggable
        v-else
        v-model="node.children"
        item-key="key"
        handle=".nav-drag-handle"
        tag="div"
        class="flex flex-col gap-2"
        :animation="180"
      >
        <template #item="{ element: child, index: idx }">
          <div
            v-show="child.module_is_enabled !== false"
            class="rounded-lg border border-surface-200 dark:border-surface-700 bg-surface-0 dark:bg-surface-950 overflow-hidden group"
          >
            <div class="flex items-stretch gap-0">
              <button
                type="button"
                class="nav-drag-handle shrink-0 flex items-center justify-center px-2 border-r border-surface-200 dark:border-surface-700 bg-surface-100/80 dark:bg-surface-900/50 text-surface-400 hover:text-surface-600 dark:hover:text-surface-300 cursor-grab active:cursor-grabbing touch-none"
                aria-label="Drag to reorder"
                tabindex="-1"
              >
                <i class="pi pi-bars text-sm" aria-hidden="true" />
              </button>
              <details class="flex-1 min-w-0">
                <summary
                  class="flex flex-wrap items-center justify-between gap-2 cursor-pointer select-none list-none px-3 py-2.5 text-sm bg-surface-50 dark:bg-surface-900/60 hover:bg-surface-100 dark:hover:bg-surface-800/80 transition-colors"
                >
                  <span class="font-medium text-surface-900 dark:text-surface-0">
                    {{ child.label || "Untitled" }}
                    <span
                      class="text-xs font-normal text-surface-500 dark:text-surface-400 ml-1"
                      >{{ child.key }}</span
                    >
                  </span>
                  <span
                    class="text-xs text-surface-500 dark:text-surface-400 shrink-0"
                  >
                    Click to expand
                  </span>
                </summary>
                <div class="border-t border-surface-200 dark:border-surface-700 p-2">
                  <NavNodeBranch
                    :node="child"
                    :modules="modules"
                    :permissions="permissions"
                    :depth="depth + 1"
                    embedded
                    @remove="removeChild(idx)"
                  />
                </div>
              </details>
            </div>
          </div>
        </template>
      </draggable>
    </section>

    <section v-if="!isRoot" class="border-t border-surface-200 dark:border-surface-700 pt-5">
      <h3
        class="text-sm font-semibold text-surface-800 dark:text-surface-100 m-0 mb-2"
      >
        Properties
      </h3>
      <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
        <BaseInputText
          v-model="node.key"
          label="Key"
          class="w-full"
        />
        <BaseInputText
          v-model="node.label"
          label="Label"
          class="w-full"
        />
        <BaseInputText
          v-model="node.route"
          label="Route path"
          placeholder="/dashboard"
          class="w-full md:col-span-2"
        />
        <BaseInputText
          v-model="node.icon"
          label="Icon class"
          placeholder="pi pi-fw pi-home"
          class="w-full md:col-span-2"
        />
        <BaseInputText
          v-model="node.description"
          label="Description"
          class="w-full md:col-span-2"
        />
        <BaseSelect
          v-model="moduleSlugModel"
          label="Module"
          :options="moduleOptions"
          option-label="label"
          option-value="value"
          placeholder="Optional"
          class="w-full"
          :show-clear="true"
        />
        <BaseSelect
          v-model="permissionModel"
          label="Permission"
          :options="permissionOptions"
          option-label="label"
          option-value="value"
          placeholder="Optional"
          class="w-full"
          :filter="true"
          :show-clear="true"
        />
        <div class="flex flex-wrap gap-4 items-center md:col-span-2">
          <BaseCheckbox
            v-model="node.is_header"
            :binary="true"
            label="Section header"
          />
          <BaseCheckbox
            v-model="node.pinned_bottom"
            :binary="true"
            label="Pin to bottom"
          />
        </div>
      </div>
    </section>
  </div>
</template>

<style scoped>
:deep(summary::-webkit-details-marker) {
  display: none;
}
</style>
