<template>
  <v-container fluid>
    <v-row align="center">
      <v-col cols="12" md="6">
        <h1 class="text-h4">Imágenes de Catálogo</h1>
      </v-col>
      <v-col cols="12" md="6" class="text-md-right">
        <v-btn
          color="primary"
          variant="elevated"
          prepend-icon="mdi-plus"
          @click="openCreateDialog"
        >
          Agregar Imagen
        </v-btn>
      </v-col>
    </v-row>

    <v-row>
      <v-col cols="12">
        <v-card>
          <v-data-table
            :headers="headers"
            :items="images"
            :loading="loading"
            density="compact"
            item-value="id"
            items-per-page="25"
            :items-per-page-options="[10, 25, 50, 100]"
          >
            <template #item.image="{ item }">
              <v-img
                :src="item.image"
                max-width="60"
                aspect-ratio="1"
                cover
                class="rounded"
              />
            </template>

            <template #item.product="{ item }">
              {{ productMap[item.product] || `ID: ${item.product}` }}
            </template>

            <template #item.uploaded_at="{ item }">
              {{ formatDate(item.uploaded_at) }}
            </template>

            <template #item.actions="{ item }">
              <v-btn
                icon
                size="small"
                variant="text"
                @click="openEditDialog(item)"
              >
                <v-icon>mdi-pencil</v-icon>
              </v-btn>
              <v-btn
                icon
                size="small"
                variant="text"
                color="error"
                @click="openDeleteDialog(item)"
              >
                <v-icon>mdi-delete</v-icon>
              </v-btn>
            </template>

            <template #loading>
              <v-skeleton-loader type="table-row@10" />
            </template>

            <template #no-data>
              <v-alert type="info" variant="tonal" class="my-4">
                No hay imágenes de catálogo
              </v-alert>
            </template>
          </v-data-table>
        </v-card>
      </v-col>
    </v-row>

    <v-dialog v-model="dialog.show" max-width="520" persistent>
      <v-card elevation="2" rounded="lg">
        <v-card-title class="text-h6 font-weight-bold pa-6 pb-0">
          <v-icon :icon="dialog.isEdit ? 'mdi-pencil' : 'mdi-plus-circle-outline'" class="mr-2" color="primary" />
          {{ dialog.isEdit ? 'Editar' : 'Agregar' }} Imagen de Catálogo
        </v-card-title>
        <v-divider class="mt-3" />
        <v-card-text class="pa-6">
          <v-form ref="formRef">
            <v-label class="font-weight-medium mb-1 d-block">Producto</v-label>
            <v-autocomplete
              v-model="form.product"
              :items="productOptions"
              placeholder="Buscar producto…"
              :rules="[(v) => !!v || 'Seleccione un producto']"
              item-title="name"
              item-value="id"
              variant="outlined"
              :disabled="dialog.isEdit"
              class="mb-5"
              clearable
              prepend-inner-icon="mdi-package-variant-closed"
              density="comfortable"
            />

            <v-label class="font-weight-medium mb-1 d-block">Imagen</v-label>
            <v-file-input
              ref="fileInputRef"
              accept="image/*"
              :rules="[(v) => !!v || 'Seleccione una imagen']"
              variant="outlined"
              prepend-icon="mdi-camera"
              prepend-inner-icon="mdi-image-outline"
              class="mb-5"
              @update:model-value="onFileSelected"
              density="comfortable"
              hide-details="auto"
            />

            <v-img
              v-if="form.preview"
              :src="form.preview"
              max-height="220"
              contain
              class="rounded-lg border mt-2"
            />
          </v-form>
        </v-card-text>
        <v-divider />
        <v-card-actions class="pa-4">
          <v-spacer />
          <v-btn variant="tonal" @click="closeDialog">Cancelar</v-btn>
          <v-btn
            color="primary"
            variant="elevated"
            :loading="submitting"
            :disabled="submitting"
            @click="submitForm"
            class="ml-2"
          >
            <v-icon start :icon="dialog.isEdit ? 'mdi-content-save' : 'mdi-upload'" />
            {{ dialog.isEdit ? 'Actualizar' : 'Agregar' }}
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <v-dialog v-model="deleteDialog.show" max-width="400">
      <v-card>
        <v-card-title>Confirmar Eliminación</v-card-title>
        <v-card-text>
          ¿Está seguro de eliminar esta imagen de catálogo?
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn variant="text" @click="deleteDialog.show = false">
            Cancelar
          </v-btn>
          <v-btn
            color="error"
            variant="elevated"
            :loading="deleting"
            :disabled="deleting"
            @click="confirmDelete"
          >
            Eliminar
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <v-snackbar
      v-model="snackbar.show"
      :color="snackbar.color"
      :timeout="3000"
      location="top"
    >
      {{ snackbar.message }}
      <template #actions>
        <v-btn variant="text" @click="snackbar.show = false">Cerrar</v-btn>
      </template>
    </v-snackbar>
  </v-container>
</template>

<script setup>
import { ref, inject, onMounted, computed, watch } from "vue";

const api = inject("api");

const images = ref([]);
const products = ref([]);
const loading = ref(false);
const submitting = ref(false);
const deleting = ref(false);
const formRef = ref(null);

const snackbar = ref({ show: false, message: "", color: "success" });

const headers = [
  { title: "ID", key: "id", sortable: true },
  { title: "Producto", key: "product", sortable: true },
  { title: "Imagen", key: "image", sortable: false },
  { title: "Subida el", key: "uploaded_at", sortable: true },
  { title: "Acciones", key: "actions", sortable: false },
];

const dialog = ref({
  show: false,
  isEdit: false,
  editingItem: null,
});

const fileInputRef = ref(null);
const selectedFile = ref(null);

const form = ref({
  product: null,
  preview: null,
});

const deleteDialog = ref({
  show: false,
  item: null,
});

let previewObjectUrl = null;

const productMap = computed(() => {
  const map = {};
  for (const p of products.value) {
    map[p.id] = p.name;
  }
  return map;
});

const productOptions = computed(() => {
  return products.value.map((p) => ({
    name: p.name,
    id: p.id,
  }));
});

watch(
  selectedFile,
  (file) => {
    if (previewObjectUrl) {
      URL.revokeObjectURL(previewObjectUrl);
      previewObjectUrl = null;
    }
    if (file) {
      previewObjectUrl = URL.createObjectURL(file);
      form.value.preview = previewObjectUrl;
    } else if (dialog.value.isEdit && dialog.value.editingItem) {
      form.value.preview = dialog.value.editingItem.image;
    } else {
      form.value.preview = null;
    }
  },
);

function onFileSelected(file) {
  selectedFile.value = file;
}

function formatDate(dateStr) {
  if (!dateStr) return "-";
  const d = new Date(dateStr);
  return d.toLocaleString("es-CO");
}

async function loadImages() {
  loading.value = true;
  try {
    const data = await api.getCatalogueImages();
    images.value = data;
  } catch (error) {
    console.error("Error al cargar imágenes:", error);
    showSnackbar("Error al cargar imágenes", "error");
  } finally {
    loading.value = false;
  }
}

async function loadProducts() {
  try {
    const data = await api.getProducts("all");
    products.value = data;
  } catch (error) {
    console.error("Error al cargar productos:", error);
  }
}

function openCreateDialog() {
  dialog.value = { show: true, isEdit: false, editingItem: null };
  selectedFile.value = null;
  form.value = { product: null, preview: null };
}

function openEditDialog(item) {
  dialog.value = { show: true, isEdit: true, editingItem: item };
  selectedFile.value = null;
  form.value = {
    product: item.product,
    preview: item.image,
  };
}

function closeDialog() {
  if (previewObjectUrl) {
    URL.revokeObjectURL(previewObjectUrl);
    previewObjectUrl = null;
  }
  selectedFile.value = null;
  dialog.value.show = false;
  dialog.value.isEdit = false;
  dialog.value.editingItem = null;
  form.value = { product: null, preview: null };
}

async function submitForm() {
  const formComponent = formRef.value;
  if (formComponent) {
    const { valid } = await formComponent.validate();
    if (!valid) return;
  }

  submitting.value = true;
  try {
    const fd = new FormData();
    fd.append("product", form.value.product);
    if (selectedFile.value) {
      fd.append("image", selectedFile.value);
    }

    if (dialog.value.isEdit) {
      await api.updateCatalogueImage(dialog.value.editingItem.id, fd);
      showSnackbar("Imagen actualizada exitosamente", "success");
    } else {
      await api.createCatalogueImage(fd);
      showSnackbar("Imagen agregada exitosamente", "success");
    }

    closeDialog();
    await loadImages();
  } catch (error) {
    console.error("Error al guardar imagen:", error);
    showSnackbar("Error al guardar imagen", "error");
  } finally {
    submitting.value = false;
  }
}

function openDeleteDialog(item) {
  deleteDialog.value = { show: true, item };
}

async function confirmDelete() {
  deleting.value = true;
  try {
    await api.deleteCatalogueImage(deleteDialog.value.item.id);
    showSnackbar("Imagen eliminada exitosamente", "success");
    deleteDialog.value.show = false;
    await loadImages();
  } catch (error) {
    console.error("Error al eliminar imagen:", error);
    showSnackbar("Error al eliminar imagen", "error");
  } finally {
    deleting.value = false;
  }
}

function showSnackbar(message, color) {
  snackbar.value = { show: true, message, color };
}

onMounted(() => {
  loadImages();
  loadProducts();
});
</script>

<style scoped>
.text-md-right {
  text-align: right;
}

@media (max-width: 960px) {
  .text-md-right {
    text-align: left;
  }
}
</style>
