<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, computed } from "vue";
import { router } from "@inertiajs/vue3";
import DataTable from "../DataTable/DataTableNew2.vue";
import Dropdown from "@/Components/Dropdown.vue";
import DeleteDialog from "../Dialogs/DeleteDialog.vue";
import { Badge } from "@/Components/ui/badge";
import TableActions from "@/Components/DataTable/TableActions.vue";
import ActionMenuItem from "@/Components/DataTable/ActionMenuItem.vue";
import { fmtDateTime } from "@/Utilities/functions";

const props = defineProps({
  documents: { type: [Array, Object], 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 },
  pageSize: {
    type: Number,
    default: 15,
  },
  pageSizeOptions: {
    type: Array,
    default: () => [10, 15, 25, 50, 100],
  },
  // Server-side pagination support
  clientCase: { type: Object, default: null },
});

// Define columns for DataTable
const columns = [
  { key: "key", label: "#", sortable: false, align: "center" },
  { key: "name", label: "Naziv", sortable: false },
  { key: "type", label: "Vrsta", sortable: false },
  { key: "size", label: "Velikost", align: "right", sortable: false },
  { key: "created_at", label: "Dodano", sortable: false },
  { key: "source", label: "Vir", sortable: false },
  { key: "description", label: "Opis", align: "center", sortable: false },
  { key: "actions", label: "", sortable: false, hideable: false, 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"]);

// Support both array and Resource Collection (object with data property)
const documentsData = computed(() => {
  if (Array.isArray(props.documents)) {
    return props.documents;
  }
  return props.documents?.data || [];
});

// Check if using server-side pagination
const isServerSide = computed(() => {
  return !!(props.documents?.links && props.clientCase);
});

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 class="space-y-4">
    <DataTable
      :columns="columns"
      :data="documentsData"
      :meta="isServerSide ? documents : null"
      :route-name="isServerSide ? 'clientCase.show' : null"
      :route-params="isServerSide ? { client_case: clientCase.uuid } : {}"
      :only-props="isServerSide ? ['documents'] : []"
      :page-size="pageSize"
      :page-size-options="pageSizeOptions"
      page-param-name="documentsPage"
      per-page-param-name="documentsPerPage"
      :show-pagination="false"
      :show-toolbar="true"
      :hoverable="true"
      row-key="uuid"
      empty-text="Ni dokumentov."
    >
      <template #toolbar-actions>
        <slot name="add" />
      </template>
      <!-- Key column -->
      <template #cell-key="{ row }">
        <Badge
          v-if="row.is_public"
          variant="secondary"
          class="bg-green-100 text-green-700 hover:bg-green-200 shrink-0"
          >Public</Badge
        >
      </template>
      <!-- Name column -->
      <template #cell-name="{ row }">
        <div>
          <div class="flex items-center gap-2">
            <button
              type="button"
              class="text-indigo-600 hover:underline max-w-xs truncate"
              :title="row.name"
              @click.stop="$emit('view', row)"
            >
              {{ row.name.length > 15 ? row.name.substring(0, 15) + "..." : row.name }}
            </button>
          </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 }">
        <div class="text-gray-800 font-medium leading-tight">
          {{ row.created_by }}
        </div>
        <div v-if="row.created_at" class="mt-1">
          <span
            class="inline-block px-2 py-0.5 rounded text-[11px] bg-gray-100 text-gray-600 tracking-wide"
          >
            {{ fmtDateTime(row.created_at) }}
          </span>
        </div>
      </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 #cell-actions="{ row }">
        <TableActions align="right">
          <template #default>
            <ActionMenuItem
              v-if="edit"
              :icon="faCircleInfo"
              label="Uredi"
              @click="emit('edit', row)"
            />
            <ActionMenuItem
              :icon="faDownload"
              label="Prenos"
              @click="handleDownload(row)"
            />
            <ActionMenuItem
              v-if="edit"
              :icon="faTrash"
              label="Izbriši"
              danger
              @click="askDelete(row)"
            />
          </template>
        </TableActions>
      </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>
