<script setup>
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import {
  faFilePdf,
  faFileWord,
  faFileExcel,
  faFileLines,
  faFileImage,
  faFile,
  faCircleInfo,
  faEllipsisVertical,
  faDownload,
  faTrash,
  faFileAlt,
} from "@fortawesome/free-solid-svg-icons";
import { ref } from "vue";
import { router } from "@inertiajs/vue3";
import DataTable from "../DataTable/DataTable.vue";
import Dropdown from "@/Components/Dropdown.vue";
import DeleteDialog from "../Dialogs/DeleteDialog.vue";
import { Badge } from "@/Components/ui/badge";

const props = defineProps({
  documents: { type: Array, default: () => [] },
  viewUrlBuilder: { type: Function, default: null },
  // Optional: direct download URL builder; if absent we emit 'download'
  downloadUrlBuilder: { type: Function, default: null },
  // Optional: direct delete URL builder; if absent we emit 'delete'
  deleteUrlBuilder: { type: Function, default: null },
  edit: { type: Boolean, default: false },
});

// Define columns for DataTable
const columns = [
  { key: 'name', label: 'Naziv' },
  { key: 'type', label: 'Vrsta' },
  { key: 'size', label: 'Velikost', align: 'right' },
  { key: 'created_at', label: 'Dodano' },
  { key: 'source', label: 'Vir' },
  { key: 'description', label: 'Opis', align: 'center' },
];
// Derive a human-friendly source for a document: Case or Contract reference
const sourceLabel = (doc) => {
  // Server can include optional documentable meta; fall back to type
  if (doc.documentable_type?.toLowerCase?.().includes("contract")) {
    return doc.contract_reference ? `Pogodba ${doc.contract_reference}` : "Pogodba";
  }
  return "Primer";
};

const emit = defineEmits(["view", "download", "delete", "edit"]);

const formatSize = (bytes) => {
  if (bytes == null) return "-";
  const thresh = 1024;
  if (Math.abs(bytes) < thresh) return bytes + " B";
  const units = ["KB", "MB", "GB", "TB"];
  let u = -1;
  do {
    bytes /= thresh;
    ++u;
  } while (Math.abs(bytes) >= thresh && u < units.length - 1);
  return bytes.toFixed(1) + " " + units[u];
};

const extFrom = (doc) => {
  let ext = (doc?.extension || "").toLowerCase();
  if (!ext && doc?.original_name) {
    const parts = String(doc.original_name).toLowerCase().split(".");
    if (parts.length > 1) ext = parts.pop();
  }
  // derive from mime
  if (!ext && doc?.mime_type) {
    const mime = String(doc.mime_type).toLowerCase();
    if (mime.includes("pdf")) ext = "pdf";
    else if (mime.includes("word") || mime.includes("msword") || mime.includes("doc"))
      ext = "docx";
    else if (mime.includes("excel") || mime.includes("sheet")) ext = "xlsx";
    else if (mime.includes("csv")) ext = "csv";
    else if (mime.startsWith("image/")) ext = "img";
    else if (mime.includes("text")) ext = "txt";
  }
  return ext;
};

const fileTypeInfo = (doc) => {
  const ext = extFrom(doc);
  const mime = (doc?.mime_type || "").toLowerCase();
  switch (ext) {
    case "pdf":
      return { icon: faFilePdf, color: "text-red-600", label: "PDF" };
    case "doc":
    case "docx":
      return {
        icon: faFileWord,
        color: "text-blue-600",
        label: (ext || "DOCX").toUpperCase(),
      };
    case "xls":
    case "xlsx":
      return {
        icon: faFileExcel,
        color: "text-green-600",
        label: (ext || "XLSX").toUpperCase(),
      };
    case "csv":
      // treat CSV as spreadsheet-like
      return { icon: faFileExcel, color: "text-emerald-600", label: "CSV" };
    case "txt":
      return { icon: faFileLines, color: "text-slate-600", label: "TXT" };
    case "jpg":
    case "jpeg":
    case "png":
    case "img":
      return {
        icon: faFileImage,
        color: "text-fuchsia-600",
        label: ext === "img" ? "IMG" : (ext || "IMG").toUpperCase(),
      };
    default:
      if (mime.startsWith("image/"))
        return { icon: faFileImage, color: "text-fuchsia-600", label: "IMG" };
      return {
        icon: faFile,
        color: "text-gray-600",
        label: (ext || "FILE").toUpperCase(),
      };
  }
};

const hasDesc = (doc) => {
  const d = doc?.description;
  return typeof d === "string" && d.trim().length > 0;
};

const expandedDescKey = ref(null);
const rowKey = (doc) => doc?.uuid ?? doc?.id ?? null;
const toggleDesc = (doc) => {
  const key = rowKey(doc);
  if (!key) return;
  expandedDescKey.value = expandedDescKey.value === key ? null : key;
};

// Track which documents have expanded descriptions
const isExpanded = (doc) => {
  const key = rowKey(doc);
  return key ? expandedDescKey.value === key : false;
};

const resolveDownloadUrl = (doc) => {
  if (typeof props.downloadUrlBuilder === "function")
    return props.downloadUrlBuilder(doc);
  // If no builder provided, parent can handle via emitted event
  return null;
};

const handleDownload = (doc) => {
  const url = resolveDownloadUrl(doc);
  if (url) {
    // Trigger a navigation to a direct-download endpoint; server should set Content-Disposition: attachment
    const a = document.createElement("a");
    a.href = url;
    a.target = "_self";
    a.rel = "noopener";
    // In many browsers, simply setting href is enough
    a.click();
  } else {
    emit("download", doc);
  }
  closeActions();
};

// ---------------- Delete logic ----------------
const confirmDelete = ref(false);
const deleting = ref(false);
const docToDelete = ref(null);

const resolveDeleteUrl = (doc) => {
  // 1. Explicit builder via prop takes precedence
  if (typeof props.deleteUrlBuilder === "function") {
    return props.deleteUrlBuilder(doc);
  }
  // 2. Attempt automatic route resolution (requires Ziggy's global `route` helper)
  try {
    const type = (doc?.documentable_type || "").toLowerCase();
    // Contract document
    if (type.includes("contract") && doc?.contract_uuid && doc?.uuid) {
      if (typeof route === "function") {
        return route("contract.document.delete", {
          contract: doc.contract_uuid,
          document: doc.uuid,
        });
      }
    }
    // Case document
    if (doc?.client_case_uuid && doc?.uuid) {
      if (typeof route === "function") {
        return route("clientCase.document.delete", {
          client_case: doc.client_case_uuid,
          document: doc.uuid,
        });
      }
    }
  } catch (e) {
    // swallow – fallback to emit path
  }
  // 3. Fallback: no URL, caller must handle emitted event
  return null;
};

const requestDelete = async () => {
  if (!docToDelete.value) {
    return;
  }
  const url = resolveDeleteUrl(docToDelete.value);
  deleting.value = true;
  try {
    if (url) {
      await router.delete(url, { preserveScroll: true });
    } else {
      emit("delete", docToDelete.value);
    }
  } finally {
    deleting.value = false;
    confirmDelete.value = false;
    docToDelete.value = null;
  }
};

const askDelete = (doc) => {
  docToDelete.value = doc;
  confirmDelete.value = true;
};

const closeDeleteDialog = () => {
  confirmDelete.value = false;
  docToDelete.value = null;
};

function closeActions() {
  /* noop placeholder for symmetry; Dropdown auto-closes */
}
</script>

<template>
  <div>
    <DataTable
      :columns="columns"
      :rows="documents"
      :show-toolbar="false"
      :show-pagination="false"
      :striped="false"
      :hoverable="true"
      :show-actions="true"
      row-key="uuid"
      empty-text="Ni dokumentov."
      empty-icon="faFileAlt"
    >
      <!-- Name column -->
      <template #cell-name="{ row }">
        <div>
          <div class="flex items-center gap-2">
            <button
              type="button"
              class="text-indigo-600 hover:underline"
              @click.stop="$emit('view', row)"
            >
              {{ row.name }}
            </button>
            <Badge v-if="row.is_public" variant="secondary" class="bg-green-100 text-green-700 hover:bg-green-200">Public</Badge>
          </div>
          <!-- Expanded description -->
          <div
            v-if="isExpanded(row)"
            class="mt-2 bg-gray-50 px-4 py-3 text-sm text-gray-700 whitespace-pre-wrap border-l-2 border-indigo-400 rounded"
          >
            {{ row.description }}
          </div>
        </div>
      </template>

      <!-- Type column -->
      <template #cell-type="{ row }">
        <div class="flex items-center gap-2">
          <FontAwesomeIcon
            :icon="fileTypeInfo(row).icon"
            :class="['h-5 w-5', fileTypeInfo(row).color]"
          />
          <span class="text-gray-700">{{ fileTypeInfo(row).label }}</span>
        </div>
      </template>

      <!-- Size column -->
      <template #cell-size="{ row }">
        {{ formatSize(row.size) }}
      </template>

      <!-- Created at column -->
      <template #cell-created_at="{ row }">
        {{ new Date(row.created_at).toLocaleString() }}
      </template>

      <!-- Source column -->
      <template #cell-source="{ row }">
        <Badge variant="secondary" class="bg-purple-100 text-purple-700 hover:bg-purple-200">{{ sourceLabel(row) }}</Badge>
      </template>

      <!-- Description column -->
      <template #cell-description="{ row }">
        <div class="flex justify-center">
          <button
            class="inline-flex items-center justify-center h-8 w-8 rounded-full hover:bg-gray-100 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
            :disabled="!hasDesc(row)"
            :title="hasDesc(row) ? 'Pokaži opis' : 'Ni opisa'"
            type="button"
            @click.stop="toggleDesc(row)"
          >
            <FontAwesomeIcon :icon="faCircleInfo" class="h-4 w-4 text-gray-700" />
          </button>
        </div>
      </template>

      <!-- Actions column -->
      <template #actions="{ row }">
        <div @click.stop>
          <Dropdown align="right" width="48">
            <template #trigger>
              <button
                type="button"
                class="inline-flex items-center justify-center h-8 w-8 rounded-full hover:bg-gray-100 focus:outline-none transition-colors"
                title="Možnosti"
              >
                <FontAwesomeIcon
                  :icon="faEllipsisVertical"
                  class="h-4 w-4 text-gray-700"
                />
              </button>
            </template>
            <template #content>
              <div class="py-1">
                <button
                  type="button"
                  class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center gap-2 transition-colors"
                  @click="emit('edit', row)"
                  v-if="edit"
                >
                  <FontAwesomeIcon :icon="faCircleInfo" class="h-4 w-4 text-gray-600" />
                  <span>Uredi</span>
                </button>
                <button
                  type="button"
                  class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center gap-2 transition-colors"
                  @click="handleDownload(row)"
                >
                  <FontAwesomeIcon :icon="faDownload" class="h-4 w-4 text-gray-600" />
                  <span>Prenos</span>
                </button>
                <button
                  type="button"
                  class="w-full px-4 py-2 text-left text-sm text-red-600 hover:bg-red-50 flex items-center gap-2 transition-colors"
                  @click="askDelete(row)"
                  v-if="edit"
                >
                  <FontAwesomeIcon :icon="faTrash" class="h-4 w-4" />
                  <span>Izbriši</span>
                </button>
              </div>
            </template>
          </Dropdown>
        </div>
      </template>
    </DataTable>

    <!-- Delete confirmation dialog -->
    <DeleteDialog
      :show="confirmDelete"
      title="Potrditev brisanja"
      :message="`Ali res želite izbrisati dokument '${docToDelete?.name}'?`"
      :item-name="docToDelete?.name"
      confirm-text="Izbriši"
      :processing="deleting"
      @close="closeDeleteDialog"
      @confirm="requestDelete"
    />
  </div>
</template>
