<script setup>
import { ref, computed, watchEffect, onMounted, onUnmounted } from "vue";
import draggable from "vuedraggable";
import ReusableDataTable from "./ReusableDataTable.vue";
import ToggleSwitch from "primevue/toggleswitch";
import Badge from "primevue/badge";
import Button from "primevue/button";
import Paginator from "primevue/paginator";
import Avatar from "primevue/avatar"; // ✅ Added Avatar

const props = defineProps({
  data: { type: Array, default: () => [] },
  loading: { type: Boolean, default: false },
  totalRecords: { type: Number, default: 0 },
  rows: { type: Number, default: 10 },
  columns: { type: Array, required: true },
  actions: { type: Array, default: () => [] },
  actionFilter: { type: Function, default: null },
  lazy: { type: Boolean, default: true },
  paginator: { type: Boolean, default: true },
  dataKey: { type: String, default: "id" },
  sortField: { type: String, default: "" },
  sortOrder: { type: Number, default: 0 },
  rowsPerPageOptions: { type: Array, default: () => [10, 25, 50] },
  tableClass: { type: String, default: "" },
  size: { type: String, default: "normal" },
  allowDrag: { type: Boolean, default: true },
  reordering: { type: Boolean, default: false },
  rowSelected: { type: Function, default: null },
  toggling: { type: Object, default: () => new Set() },
});

const emit = defineEmits([
  "reorder",
  "page",
  "sort",
  "action-click",
  "toggle-enabled",
  "row-select",
  "row-unselect",
  "selection-change",
  "row-click",
]);

const draggedData = ref([]);
const isDragging = ref(false);
const tableKey = ref(0);

// Build the grid columns from the actual column count so the wrapper works for
// any table (5 cols, 6 cols, ...): [drag handle] [title (wide)] [...rest] [actions].
const gridTemplateColumns = computed(() => {
  const n = props.columns?.length || 0;
  if (n <= 0) return "50px 1fr 120px";
  const rest = n > 1 ? ` repeat(${n - 1}, minmax(0, 1fr))` : "";
  return `50px minmax(160px, 2.2fr)${rest} 120px`;
});

watchEffect(() => {
  draggedData.value = [...props.data];
});

const onDragStart = () => {
  isDragging.value = true;
};

const onDragEnd = (evt) => {
  isDragging.value = false;
  if (evt.oldIndex !== evt.newIndex) {
    emit("reorder", {
      data: draggedData.value,
      oldIndex: evt.oldIndex,
      newIndex: evt.newIndex,
    });
    tableKey.value += 1;
  }
};

const handleSort = (event) => emit("sort", event);
const handleActionClick = (event) => emit("action-click", event);
const handleToggle = (rowData) => emit("toggle-enabled", rowData);

// Status badge (same look as the Pages listing)
const getBadgeClass = (val) => (!val ? "badge-gray" : "badge-active");
const formatBadgeLabel = (val) => (val ? String(val).replace(/_/g, " ") : "-");

// ---- Overflow (⋮) actions menu — matches the Pages listing design ----
const activeMenu = ref({ visible: false, x: 0, y: 0, rowData: null, index: null, actions: [] });

const getVisibleActions = (rowData) =>
  props.actions.filter((a) => {
    if (typeof a.condition === "function") return a.condition(rowData);
    if (typeof a.show === "function") return a.show(rowData);
    return true;
  });

const isActionDisabled = (action, rowData) => {
  if (typeof action.disabled === "function") return action.disabled(rowData);
  return action.disabled || false;
};

const getMenuText = (action, rowData) => {
  const text = action.label || action.tooltip;
  if (typeof text === "function") return text(rowData);
  return text || action.action || "";
};

const getActionIcon = (action, rowData) =>
  typeof action.icon === "function" ? action.icon(rowData) : action.icon || "";

const getActionTo = (action, rowData) => {
  if (typeof action.to === "function") return action.to(rowData);
  return action.to || null;
};

const closeActionMenu = () => {
  activeMenu.value.visible = false;
};

const toggleActionMenu = (event, rowData, index) => {
  if (activeMenu.value.visible && activeMenu.value.index === index) {
    closeActionMenu();
    return;
  }
  const rect = event.currentTarget.getBoundingClientRect();
  activeMenu.value = {
    visible: true,
    x: rect.left - 130,
    y: rect.bottom + window.scrollY + 4,
    rowData,
    index,
    actions: getVisibleActions(rowData),
  };
};

const executeAction = (action) => {
  emit("action-click", {
    action,
    rowData: activeMenu.value.rowData,
    index: activeMenu.value.index,
  });
  closeActionMenu();
};

onMounted(() => {
  document.addEventListener("click", closeActionMenu);
  window.addEventListener("scroll", closeActionMenu, true);
});
onUnmounted(() => {
  document.removeEventListener("click", closeActionMenu);
  window.removeEventListener("scroll", closeActionMenu, true);
});

const currentPage = ref(0);
const rowsPerPage = computed(() => props.rows || 10);
const firstRecord = computed(() => currentPage.value * rowsPerPage.value);

const handlePage = (event) => {
  currentPage.value = event.page;
  emit("page", event);
};

// ✅ HELPER: Initials for Avatar
const getInitials = (name) =>
  name
    ? name
        .split(" ")
        .map((n) => n[0])
        .slice(0, 2)
        .join("")
        .toUpperCase()
    : "";

// ✅ HELPER: Avatar Colors
const getAvatarColor = (name) => {
  const colors = [
    "#6366f1",
    "#8b5cf6",
    "#10b981",
    "#f59e0b",
    "#ec4899",
    "#3b82f6",
  ];
  let hash = 0;
  if (name)
    for (let i = 0; i < name.length; i++)
      hash = name.charCodeAt(i) + ((hash << 5) - hash);
  return colors[Math.abs(hash) % colors.length];
};

const formatCellValue = (value, column) => {
  if (value === null || value === undefined) return "";
  if (column.template === "badge") return String(value);
  return value;
};

const getBadgeSeverity = (column, value) => {
  if (column.field === "status" || column.header === "Status") {
    return value === "Active" || value === true ? "success" : "danger";
  }
  return "info";
};
</script>

<template>
  <div class="draggable-table-wrapper" :key="tableKey">
    <div v-if="reordering" class="reordering-overlay">
      <div
        class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"
      ></div>
    </div>

    <ReusableDataTable
      v-if="loading || !allowDrag"
      v-bind="props"
      @page="handlePage"
      @sort="handleSort"
      @action-click="handleActionClick"
    />

    <div v-else class="beautiful-table-container">
      <div class="beautiful-table-header">
        <div class="table-grid-layout px-6 w-full min-h-[50px] items-center" :style="{ gridTemplateColumns }">
          <div
            class="flex justify-center text-[0.6875rem] font-bold text-[#475569] uppercase tracking-[0.05em]"
          >
            <i class="pi pi-arrows-v" />
          </div>
          <div
            v-for="column in columns"
            :key="column.field"
            class="flex items-center gap-2 text-[0.6875rem] font-bold text-[#475569] uppercase tracking-[0.05em] cursor-pointer hover:text-slate-700"
            @click="
              column.sortable
                ? handleSort({
                    sortField: column.field,
                    sortOrder:
                      sortField === column.field
                        ? sortOrder === 1
                          ? -1
                          : 1
                        : 1,
                  })
                : null
            "
          >
            <span>{{ column.header }}</span>
            <i v-if="column.sortable" class="pi pi-sort-alt opacity-50" />
          </div>
          <div
            class="flex justify-center text-[0.6875rem] font-bold text-[#475569] uppercase tracking-[0.05em]"
          >
            Actions
          </div>
        </div>
      </div>

      <div class="beautiful-table-body">
        <draggable
          v-model="draggedData"
          :item-key="dataKey"
          handle=".drag-handle"
          :disabled="reordering"
          :animation="200"
          ghost-class="drag-ghost"
          @start="onDragStart"
          @end="onDragEnd"
        >
          <template #item="{ element: rowData, index: rowIndex }">
            <div
              class="beautiful-table-row table-grid-layout"
              :class="{ 'is-selected': props.rowSelected?.(rowData) }"
              :style="{ gridTemplateColumns }"
            >
              <div class="flex justify-center">
                <div class="drag-handle beautiful-drag-handle">
                  <i class="pi pi-bars text-slate-400 hover:text-slate-600" />
                </div>
              </div>

              <div
                v-for="column in columns"
                :key="column.field"
                class="flex items-center overflow-hidden"
              >
                <div
                  v-if="column.template === 'user'"
                  class="flex items-center gap-3"
                >
                  <Avatar
                    :label="getInitials(rowData[column.field])"
                    class="font-bold text-white shadow-sm"
                    shape="circle"
                    :style="{
                      backgroundColor: getAvatarColor(rowData[column.field]),
                      width: '32px',
                      height: '32px',
                      fontSize: '0.85rem',
                    }"
                  />
                  <div class="flex flex-col">
                    <span class="font-semibold text-slate-800 text-[13px]">{{
                      rowData[column.field]
                    }}</span>
                    <span
                      v-if="column.subField"
                      class="text-xs text-slate-500"
                      >{{ rowData[column.subField] }}</span
                    >
                  </div>
                </div>

                <div
                  v-else-if="column.template === 'custom'"
                  v-html="column.customHTML?.(rowData)"
                />

                <div v-else-if="column.template === 'toggle'">
                  <ToggleSwitch
                    v-model="rowData[column.field]"
                    :disabled="reordering || toggling.has(rowData.id)"
                    @change="handleToggle(rowData)"
                  />
                </div>

                <div v-else-if="column.template === 'badge'" class="badge-cell">
                  <span :class="['status-pill', getBadgeClass(rowData[column.field])]">
                    {{ formatBadgeLabel(rowData[column.field]) }}
                  </span>
                </div>

                <span v-else class="text-[13px] text-[#334155] truncate">
                  {{ formatCellValue(rowData[column.field], column) }}
                </span>
              </div>

              <div class="flex justify-center items-center gap-2">
                <Button
                  v-if="getVisibleActions(rowData).length"
                  icon="pi pi-ellipsis-v"
                  rounded
                  text
                  severity="secondary"
                  class="action-btn-circle"
                  @click.stop="(event) => toggleActionMenu(event, rowData, rowIndex)"
                />
              </div>
            </div>
          </template>
        </draggable>
      </div>

      <div v-if="paginator && totalRecords > 0" class="beautiful-pagination">
        <Paginator
          :first="firstRecord"
          :rows="rowsPerPage"
          :total-records="totalRecords"
          :rows-per-page-options="rowsPerPageOptions"
          template="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
          @page="handlePage"
        />
      </div>
    </div>

    <!-- Overflow actions menu (Edit / Delete) — same design as Pages listing -->
    <Teleport to="body">
      <div
        v-if="activeMenu.visible"
        class="custom-teleport-menu"
        :style="{ top: activeMenu.y + 'px', left: activeMenu.x + 'px' }"
        @click.stop
      >
        <ul class="menu-list">
          <li
            v-for="(action, idx) in activeMenu.actions"
            :key="idx"
            class="menu-item"
            :class="{ 'menu-item-disabled': isActionDisabled(action, activeMenu.rowData) }"
          >
            <RouterLink
              v-if="getActionTo(action, activeMenu.rowData) && !isActionDisabled(action, activeMenu.rowData)"
              :to="getActionTo(action, activeMenu.rowData)"
              class="menu-button"
              @click="closeActionMenu"
            >
              <i :class="[getActionIcon(action, activeMenu.rowData), 'menu-icon']"></i>
              <span class="menu-text">{{ getMenuText(action, activeMenu.rowData) }}</span>
            </RouterLink>
            <button
              v-else
              class="menu-button"
              :disabled="isActionDisabled(action, activeMenu.rowData)"
              @click="executeAction(action)"
            >
              <i :class="[getActionIcon(action, activeMenu.rowData), 'menu-icon']"></i>
              <span class="menu-text">{{ getMenuText(action, activeMenu.rowData) }}</span>
            </button>
          </li>
        </ul>
      </div>
    </Teleport>
  </div>
</template>

<style scoped>
/* ✅ FIXED: Flexible Grid Layout (matches Programs columns) */
/* Drag | Title | Slug | Age | Duration | Lang | Enabled | Actions */
.table-grid-layout {
  display: grid;
  /* grid-template-columns is set inline (computed from the column count). */
  gap: 1rem;
  padding: 0 1.5rem;
  align-items: center;
}

/* Status badge — same look as the Pages listing (ReusableDataTable) */
.badge-cell {
  display: flex;
  align-items: center;
}
.status-pill {
  padding: 0.2rem 0.65rem;
  border-radius: 5px;
  font-size: 0.6875rem;
  font-weight: 600;
  display: inline-block;
  text-transform: capitalize;
}
.badge-active {
  background-color: var(--ye-badge-bg, #003b6f);
  color: var(--ye-badge-text, #ffffff);
  border: 1px solid var(--ye-badge-border, #003b6f);
}
.badge-gray {
  background: #f1f5f9;
  color: #64748b;
}

/* Overflow (⋮) actions menu — mirrors the Pages listing (ReusableDataTable) */
.action-btn-circle {
  width: 2rem !important;
  height: 2rem !important;
  border-radius: 50% !important;
  color: var(--dt-action-icon, #64748b) !important;
  transition: all 0.2s ease !important;
}
.action-btn-circle:hover {
  background-color: var(--dt-action-hover-bg, #f1f5f9) !important;
  color: var(--dt-action-hover-icon, var(--ye-brand, #003b6f)) !important;
}

.custom-teleport-menu {
  position: absolute;
  z-index: 99999;
  min-width: 170px;
  background-color: #ffffff !important;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  box-shadow:
    0 10px 15px -3px rgba(0, 0, 0, 0.1),
    0 4px 6px -4px rgba(0, 0, 0, 0.05);
  overflow: hidden;
}
.custom-teleport-menu .menu-list {
  padding: 0;
  margin: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
}
.custom-teleport-menu .menu-item {
  margin: 0;
  border-bottom: 1px solid #f1f5f9;
}
.custom-teleport-menu .menu-item:last-child {
  border-bottom: none;
}
.custom-teleport-menu .menu-button {
  width: 100%;
  display: flex;
  align-items: center;
  padding: 0.65rem 1rem;
  background-color: transparent;
  border: none;
  cursor: pointer;
  text-align: left;
  transition: all 0.2s ease;
  outline: none;
  text-decoration: none;
  color: inherit;
}
.custom-teleport-menu .menu-icon {
  margin-right: 0.75rem;
  color: #64748b;
  font-size: 1rem;
  transition: color 0.2s ease;
}
.custom-teleport-menu .menu-text {
  color: #334155;
  font-size: 0.875rem;
  font-weight: 500;
  transition: color 0.2s ease;
}
.custom-teleport-menu .menu-button:hover {
  background-color: #003b6f !important;
}
.custom-teleport-menu .menu-button:hover .menu-icon,
.custom-teleport-menu .menu-button:hover .menu-text {
  color: #ffffff !important;
}
.custom-teleport-menu .menu-item-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.custom-teleport-menu .menu-button:disabled {
  cursor: not-allowed;
  pointer-events: none;
}

/* Container */
.beautiful-table-container {
  background: white;
  border-radius: 12px;
  box-shadow:
    0 4px 6px -1px rgba(0, 0, 0, 0.1),
    0 2px 4px -1px rgba(0, 0, 0, 0.06);
  border: 1px solid #e2e8f0;
  overflow: hidden;
}

/* Header — matches PrimeVue .p-datatable-thead > tr > th */
.beautiful-table-header {
  background: #f8fafc;
  border-bottom: 1px solid #e2e8f0;
  min-height: 2.75rem;
  display: flex;
  align-items: center;
}

/* Rows — matches PrimeVue cell padding (0.625rem) + 32px avatar */
.beautiful-table-row {
  min-height: 52px;
  border-bottom: 1px solid #f1f5f9;
  background: white;
  color: #334155;
  font-size: 0.8125rem;
  transition: background-color 0.2s;
}

.beautiful-table-row:hover {
  background-color: #f1f5f9;
}

.beautiful-table-row.is-selected {
  background-color: #eff6ff;
}

/* Drag Handle */
.beautiful-drag-handle {
  cursor: grab;
  padding: 4px;
  border-radius: 4px;
}
.beautiful-drag-handle:hover {
  background: #e2e8f0;
}
.beautiful-drag-handle:active {
  cursor: grabbing;
}

.drag-ghost {
  opacity: 0.5;
  background: #eff6ff;
  border: 2px dashed #3b82f6;
}

/* Pagination — matches PrimeVue .p-paginator in the other tables */
.beautiful-pagination {
  border-top: 1px solid #e2e8f0;
  background: #ffffff;
  display: flex;
  justify-content: center;
}
.beautiful-pagination :deep(.p-paginator) {
  background: transparent !important;
  border: none;
  color: #475569;
  font-size: 0.8125rem;
  padding: 0.5rem 1rem;
  width: 100%;
}

/* Loading */
.reordering-overlay {
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.8);
  z-index: 50;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
