<script setup lang="ts">
import { type Component } from "vue";
import { router } from "@inertiajs/vue3";
import { registry } from "../registry";
import { useTranslations } from "../composables/useTranslations";
import DropdownMenu from "./ui/DropdownMenu.vue";
import DropdownMenuTrigger from "./ui/DropdownMenuTrigger.vue";
import DropdownMenuContent from "./ui/DropdownMenuContent.vue";
import DropdownMenuItem from "./ui/DropdownMenuItem.vue";
import DropdownMenuSeparator from "./ui/DropdownMenuSeparator.vue";

import type { Column, BulkAction, RowAction } from "../types";

const { t } = useTranslations();

const props = defineProps<{
  columns: Column[];
  rows: Record<string, unknown>[];
  bulkActions: BulkAction[];
  selectedIds: Set<unknown>;
  allSelected: boolean;
  sortColumn: string | null;
  sortDirection: "asc" | "desc";
  canEdit: boolean;
  hasCustomRowActions: boolean;
  isHierarchical?: boolean;
  isPublic?: boolean;
  publicUrlBase?: string;
}>();

const emit = defineEmits<{
  toggleSort: [key: string];
  toggleAll: [];
  toggleRow: [id: unknown];
  editRecord: [id: unknown];
  deleteRecord: [id: unknown];
  rowAction: [key: string, record: Record<string, unknown>];
}>();

function resolveCell(componentName: string | null): Component | null {
  if (!componentName) return null;
  return registry.resolveComponent(componentName) ?? null;
}

function formatCellValue(
  col: Column,
  record: Record<string, unknown>,
): unknown {
  return record[col.key] ?? "—";
}

function handleRowAction(
  action: RowAction,
  record: Record<string, unknown>,
): void {
  if (action.key === "delete") {
    emit("deleteRecord", record.id);
    return;
  }
  if (action.url) {
    if (action.method === "post") {
      router.post(action.url);
    } else {
      window.location.href = action.url;
    }
    return;
  }
  emit("rowAction", action.key, record);
}

function nonDestructiveActions(record: Record<string, unknown>): RowAction[] {
  const actions = (record._rowActions as RowAction[] | undefined) ?? [];
  return actions.filter((a) => !a.destructive);
}

function destructiveActions(record: Record<string, unknown>): RowAction[] {
  const actions = (record._rowActions as RowAction[] | undefined) ?? [];
  return actions.filter((a) => a.destructive);
}

function hasDestructiveActions(record: Record<string, unknown>): boolean {
  return destructiveActions(record).length > 0;
}

function rowDepth(record: Record<string, unknown>): number {
  let depth = 0;
  let parentId = record.parent_id;
  while (parentId != null) {
    const parent = props.rows.find((r) => r.id === parentId);
    if (!parent || parent === record) break;
    depth++;
    parentId = parent.parent_id;
  }
  return depth;
}

function publicViewUrl(record: Record<string, unknown>): string | null {
  if (!props.isPublic || !record.slug) return null;
  const base = props.publicUrlBase ?? "";
  return `${base}/${record.slug}`;
}
</script>

<template>
  <div class="overflow-x-auto">
    <table class="w-full text-sm">
      <thead>
        <tr class="border-b bg-muted/40">
          <th v-if="bulkActions.length > 0" class="w-10 px-4 py-3">
            <input
              type="checkbox"
              :checked="allSelected"
              class="rounded border-input"
              @change="emit('toggleAll')"
            />
          </th>
          <th
            v-for="col in columns"
            :key="col.key"
            class="px-4 py-3 text-left text-xs font-medium text-muted-foreground"
            :class="
              col.sortable
                ? 'cursor-pointer select-none hover:text-foreground'
                : ''
            "
            @click="col.sortable ? emit('toggleSort', col.key) : undefined"
          >
            <span class="inline-flex items-center gap-1.5">
              {{ col.label }}
              <template v-if="col.sortable">
                <svg
                  class="h-3 w-3 transition-transform"
                  :class="{
                    'text-foreground': sortColumn === col.key,
                    'rotate-180':
                      sortColumn === col.key && sortDirection === 'desc',
                    'opacity-40': sortColumn !== col.key,
                  }"
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                >
                  <path
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    stroke-width="2"
                    d="M5 15l7-7 7 7"
                  />
                </svg>
              </template>
            </span>
          </th>
          <th class="w-10 px-2 py-3"></th>
        </tr>
      </thead>
      <tbody class="divide-y">
        <tr v-if="rows.length === 0">
          <td
            :colspan="columns.length + (bulkActions.length > 0 ? 2 : 1)"
            class="px-4 py-20 text-center text-muted-foreground"
          >
            {{ t("builder.resources.no_records") }}
          </td>
        </tr>

        <tr
          v-for="record in rows"
          :key="record.id as string"
          class="transition-colors duration-100 hover:bg-muted/40"
        >
          <td v-if="bulkActions.length > 0" class="w-10 px-4 py-3">
            <input
              type="checkbox"
              :checked="selectedIds.has(record.id)"
              class="rounded border-input"
              @change="emit('toggleRow', record.id)"
            />
          </td>

          <td
            v-for="(col, colIndex) in columns"
            :key="col.key"
            class="px-4 py-3.5"
            :style="
              colIndex === 0 && isHierarchical && rowDepth(record) > 0
                ? {
                    paddingLeft: `${1 + rowDepth(record) * 1.25}rem`,
                  }
                : undefined
            "
          >
            <component
              v-if="col.component && resolveCell(col.component)"
              :is="resolveCell(col.component)"
              :value="record[col.key]"
              :record="record"
              :column="col"
            />
            <button
              v-else-if="colIndex === 0 && canEdit"
              class="cursor-pointer text-left font-medium text-foreground transition-colors hover:text-primary"
              @click="emit('editRecord', record.id)"
            >
              {{ formatCellValue(col, record) }}
            </button>
            <span
              v-else
              :class="
                colIndex === 0
                  ? 'font-medium text-foreground'
                  : 'text-muted-foreground'
              "
            >
              {{ formatCellValue(col, record) }}
            </span>
          </td>

          <!-- Row actions — always-visible ⋯ dropdown (shadcn data table style) -->
          <td class="w-10 px-2 py-3">
            <DropdownMenu>
              <DropdownMenuTrigger as-child>
                <button
                  class="inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground"
                  :aria-label="t('builder.resources.actions')"
                >
                  <svg class="h-4 w-4" fill="currentColor" viewBox="0 0 24 24">
                    <circle cx="5" cy="12" r="1.5" />
                    <circle cx="12" cy="12" r="1.5" />
                    <circle cx="19" cy="12" r="1.5" />
                  </svg>
                </button>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end" class="w-40">
                <!-- Custom row actions -->
                <template v-if="hasCustomRowActions">
                  <DropdownMenuItem
                    v-for="action in nonDestructiveActions(record)"
                    :key="action.key"
                    @click="handleRowAction(action, record)"
                  >
                    {{ action.label }}
                  </DropdownMenuItem>
                  <template v-if="hasDestructiveActions(record)">
                    <DropdownMenuSeparator />
                    <DropdownMenuItem
                      v-for="action in destructiveActions(record)"
                      :key="action.key"
                      class="text-destructive focus:text-destructive"
                      @click="handleRowAction(action, record)"
                    >
                      {{ action.label }}
                    </DropdownMenuItem>
                  </template>
                </template>

                <!-- Default edit / delete (with optional extra actions like duplicate) -->
                <template v-else>
                  <DropdownMenuItem
                    v-if="canEdit"
                    @click="emit('editRecord', record.id)"
                  >
                    {{ t("builder.resources.edit") }}
                  </DropdownMenuItem>
                  <DropdownMenuItem v-if="publicViewUrl(record)" as-child>
                    <a
                      :href="publicViewUrl(record)!"
                      target="_blank"
                      rel="noopener noreferrer"
                    >
                      {{ t("builder.resources.view") }}
                    </a>
                  </DropdownMenuItem>
                  <DropdownMenuItem
                    v-for="action in nonDestructiveActions(record)"
                    :key="action.key"
                    @click="handleRowAction(action, record)"
                  >
                    {{ action.label }}
                  </DropdownMenuItem>
                  <DropdownMenuSeparator
                    v-if="
                      record._canDelete !== false &&
                      (canEdit || nonDestructiveActions(record).length > 0)
                    "
                  />
                  <DropdownMenuItem
                    v-if="record._canDelete !== false"
                    class="text-destructive focus:text-destructive"
                    @click="emit('deleteRecord', record.id)"
                  >
                    {{ t("builder.resources.delete") }}
                  </DropdownMenuItem>
                </template>
              </DropdownMenuContent>
            </DropdownMenu>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
