<script setup>
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/Components/ui/table';
import DialogModal from './DialogModal.vue';
import { useForm } from '@inertiajs/vue3';
import { ref } from 'vue';
import TextInput from './TextInput.vue';
import InputLabel from './InputLabel.vue';
import ActionMessage from './ActionMessage.vue';
import PrimaryButton from './PrimaryButton.vue';
import Modal from './Modal.vue';
import SecondaryButton from './SecondaryButton.vue';
import { Button } from '@/Components/ui/button';


const props = defineProps({
  title: String,
  description: String,
  header: Array,
  body: Array,
  // Make table header sticky while body scrolls
  stickyHeader: {
    type: Boolean,
    default: true
  },
  editor: {
    type: Boolean,
    default: false
  },
  options: {
    type: Object,
    default: {}
  },
  // Deprecated: fixed height. Prefer bodyMaxHeight (e.g., 'max-h-96').
  bodyHeight: {
    type: String,
    default: 'h-96'
  },
  // Preferred: control scrollable body max-height (Tailwind class), e.g., 'max-h-96', 'max-h-[600px]'
  bodyMaxHeight: {
    type: String,
    default: 'max-h-96'
  }
});

const drawerUpdateForm = ref(false);
const modalRemove = ref(false);
const formUpdate = (props.editor) ? useForm(props.options.editor_data.form.values) : false;
const formRemove = (props.editor) ? useForm({type: 'soft', key: null}) : false;

const openEditor = (ref, data) => {
  formUpdate[ref.key] = ref.val;
  for(const [key, value] of Object.entries(data)) {
    formUpdate[key] = value;
  }
  drawerUpdateForm.value = true;
}

const closeEditor = () => {
  drawerUpdateForm.value = false;
}

const setUpdateRoute = (name, params = false, index) => {
  if(!params){
    return route(name, index)
  }

  return route(name, [params, index]);
}

const update = () => {
 
  const putRoute = setUpdateRoute(
    props.options.editor_data.form.route.name,
    props.options.editor_data.form.route.params,
    formUpdate[props.options.editor_data.form.key]
  )
  
  formUpdate.put(putRoute, {
    onSuccess: () => {
      closeEditor();
      formUpdate.reset();
    },
    preserveScroll: true
  });
}

const modalRemoveTitle = ref('');

const closeModal = () => {
  modalRemove.value = false;
}

const showModal = (key, title) => {
  modalRemoveTitle.value = title;
  formRemove.key = key;
  modalRemove.value = true;
}

const remove = () => {
  const removeRoute = setUpdateRoute(
    props.options.editor_data.form.route_remove.name,
    props.options.editor_data.form.route_remove.params,
    formRemove.key
  )

  formRemove.delete(removeRoute, {
    onSuccess: () => {
      closeModal();
      formRemove.reset();
    },
    preserveScroll: true
  });
}

</script>
<template>
  <div>
    <!-- Header -->
    <div v-if="title || description" class="mb-4">
      <h2 v-if="title" class="text-lg font-semibold text-gray-900">{{ title }}</h2>
      <p v-if="description" class="mt-1 text-sm text-gray-600">{{ description }}</p>
    </div>

    <div :class="['relative rounded-lg border border-gray-200 bg-white shadow-sm overflow-x-auto overflow-y-auto', bodyMaxHeight, stickyHeader ? 'table-sticky' : '']">
      <Table class="text-sm">
        <TableHeader class="sticky top-0 z-10 bg-gray-50/90 backdrop-blur supports-[backdrop-filter]:bg-gray-50/80 border-b border-gray-200 shadow-sm">
          <TableRow class="border-b">
            <TableHead
              v-for="(h, hIndex) in header"
              :key="hIndex"
              class="sticky top-0 z-10 uppercase text-xs font-semibold tracking-wide text-gray-700 py-3 first:pl-6 last:pr-6 bg-gray-50/90"
            >{{ h.data }}</TableHead>
            <TableHead v-if="editor" class="sticky top-0 z-10 w-px text-gray-700 py-3 bg-gray-50/90"></TableHead>
            <TableHead v-else class="sticky top-0 z-10 w-px text-gray-700 py-3 bg-gray-50/90" />
          </TableRow>
        </TableHeader>
        <TableBody>
          <TableRow v-for="(row, key, parent_index) in body" :key="key" :class="[row.options.class, 'hover:bg-gray-50/50']">
            <TableCell v-for="(col, colIndex) in row.cols" :key="colIndex" class="align-middle">  
              <a v-if="col.link !== undefined" :class="col.link.css" :href="route(col.link.route, col.link.options)">{{ col.data }}</a>
              <span v-else>{{ col.data }}</span>
            </TableCell>
            <TableCell v-if="editor" class="text-right whitespace-nowrap">
              <Button class="mr-2" size="sm" variant="outline" @click="openEditor(row.options.ref, row.options.editable)">Edit</Button>
              <Button size="sm" variant="destructive" @click="showModal(row.options.ref.val, row.options.title)">Remove</Button>
            </TableCell>
            <TableCell v-else />
          </TableRow>
        </TableBody>
      </Table>
      <div v-if="!body || body.length === 0" class="p-6 text-center text-sm text-gray-500">No records found.</div>
    </div>
  </div>
  <DialogModal
    v-if="editor"
    :show="drawerUpdateForm"
    @close="drawerUpdateForm = false"
    maxWidth="xl"
  >
    
    <template #title>Update {{ options.editor_data.title }}</template>
    <template #content>
      <form @submit.prevent="update" class="pt-2">
        <div v-for="(e, eIndex) in options.editor_data.form.el" :key="eIndex" class="col-span-6 sm:col-span-4 mb-4">
          <InputLabel :for="e.id" :value="e.label"/>
          <TextInput 
            v-if="e.type === 'text'" 
            :id="e.id"
            :ref="e.ref"
            type="text"
            :autocomplete="e.autocomplete"
            class="mt-1 block w-full text-sm"
            v-model="formUpdate[e.bind]"
          />
          <select
            v-else-if="e.type === 'select'"
            class="block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm text-sm"
            :id="e.id"
            :ref="e.ref"
            v-model="formUpdate[e.bind]"
          >
            <option v-for="(op, opIndex) in e.selectOptions" :key="opIndex" :value="op.val">{{ op.desc }}</option>
          </select>
        </div>
        <div class="flex justify-end mt-6 gap-3">
            <ActionMessage :on="formUpdate.recentlySuccessful" class="me-3"> 
                Saved.
            </ActionMessage>
            <PrimaryButton :class="{ 'opacity-25': formUpdate.processing }" :disabled="formUpdate.processing">
                Save
            </PrimaryButton>
        </div>
      </form>
    </template>
  </DialogModal>

  <Modal
    v-if="editor"
    :show="modalRemove"
    @close="closeModal"
    maxWidth="sm"
  >
    <form @submit.prevent="remove">
      <div class="p-6">
        <div class="text-base font-medium text-center py-2 mb-4 text-gray-900">
          Remove {{ options.editor_data.title }} <b>{{ modalRemoveTitle }}</b>?
        </div>
    
        <div class="flex justify-between items-center">
          <SecondaryButton type="button" @click="closeModal">
            Cancel
          </SecondaryButton>
          <ActionMessage :on="formRemove.recentlySuccessful" class="me-3"> 
            Deleted.
          </ActionMessage>
          <PrimaryButton class="bg-red-700" :class="{ 'opacity-25': formRemove.processing }" :disabled="formRemove.processing">
                Delete
          </PrimaryButton>
        </div>
      </div>
    </form>
  </Modal>
</template>

<style scoped>
/* Ensure sticky header remains above scrollable body inside wrapper */
:deep(.table-sticky thead) {
  position: sticky;
  top: 0;
  z-index: 10;
}

:deep(.table-sticky thead th) {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: rgba(249, 250, 251, 0.9); /* gray-50/90 */
  backdrop-filter: saturate(180%) blur(5px);
}

/* Maintain column widths alignment when scrollbar appears */
.table-sticky {
  /* Make sure the header and body share the same scroll container */
  overflow-y: auto;
}
</style>