<template>
  <v-row no-gutters align="center" justify="center">
    <v-col cols="12" lg="12">
      <TableMain
        :title="`${siteName} Units`"
        :items="items"
        :headers="headers"
        :loading="loading"
        :show-header="true"
        v-model:page="page"
        :pages="pages"
        :pageRange="pageRange"
        :no-data-text="`No units found for ${siteName}.`"
        @refresh="getUnitsRefresh"
        :canCreate="canCreateUnit"
        createLabel="Add Unit"
        @create="onCreateUnit"
        @row-click="handleRowClick"
      >
        <template #actions>
          <v-row no-gutters align="center" class="w-100">
            <v-col cols="auto">
              <div class="d-flex align-center">
                <!-- Primary action -->
                <v-btn
                  v-if="canCreateUnit"
                  class="text-none mr-3"
                  rounded="pill"
                  variant="tonal"
                  size="large"
                  @click="onCreateUnit()"
                >
                  Add Unit
                </v-btn>

                <v-tooltip v-if="canCreateUnit" location="top">
                  <template #activator="{ props: t }">
                    <v-btn
                      v-bind="t"
                      class="ma-1"
                      variant="tonal"
                      size="large"
                      rounded="pill"
                      href="/files/unit-sample-data.xlsx"
                      target="_blank"
                      download
                    >
                      <v-icon>mdi-download</v-icon>
                    </v-btn>
                  </template>
                  <span>Download Template</span>
                </v-tooltip>

                <v-tooltip v-if="canImportUnit" location="top">
                  <template #activator="{ props: t }">
                    <v-btn
                      v-bind="t"
                      class="ma-1"
                      variant="tonal"
                      size="large"
                      rounded="pill"
                      @click="onImportData"
                    >
                      <v-icon>mdi-upload</v-icon>
                    </v-btn>
                  </template>
                  <span>Import Data</span>
                </v-tooltip>

                <v-tooltip v-if="canViewUnits" location="top">
                  <template #activator="{ props: t }">
                    <v-btn
                      v-bind="t"
                      class="ma-1"
                      variant="tonal"
                      size="large"
                      rounded="pill"
                      @click="handleDownloadExcel"
                      :loading="isDownloading"
                    >
                      <v-icon>mdi-file-excel</v-icon>
                    </v-btn>
                  </template>
                  <span>Download Excel</span>
                </v-tooltip>
              </div>
            </v-col>

            <v-spacer />

            <v-col cols="auto">
              <v-text-field
                v-model="searchInput"
                density="compact"
                placeholder="Search"
                clearable
                width="300"
                append-inner-icon="mdi-magnify"
                hide-details
              />
            </v-col>
          </v-row>
        </template>

        <template #item.block="{ value }">
          {{ value ? `blk ${value}` : "" }}
        </template>
      </TableMain>
    </v-col>
  </v-row>

  <AreaFormDialog
    v-model="dialogShowForm"
    v-model:name="areaName"
    :mode="dialogMode"
    :areaData="editingUnit"
    label="Unit Name"
    entityType="Unit"
    :showOptional="false"
    :showType="false"
    @saved="_createUnit"
  />

  <v-dialog v-model="dialogShowMoreActions" width="400" persistent>
    <HygieneUpdateMoreAction
      :title="selectedUnit?.name || 'Unit Actions'"
      :canUpdate="canUpdateUnit"
      :canDelete="canDeleteUnit"
      :manageButtonLabel="''"
      :editButtonLabel="'Edit Unit'"
      :deleteButtonLabel="'Delete Unit'"
      @close="dialogShowMoreActions = false"
      @edit="onEditFromMoreAction"
      @delete="onDeleteFromMoreAction"
    >
      <template #content>
        <v-row no-gutters>
          <v-col cols="12" class="my-2">
            <span class="text-subtitle-2"
              >Select an action to perform on this unit.</span
            >
          </v-col>

          <v-col cols="12" class="my-2">
            <span class="text-subtitle-2 text-error">{{ message }}</span>
          </v-col>
        </v-row>
      </template>
    </HygieneUpdateMoreAction>
  </v-dialog>

  <v-dialog v-model="dialogDeleteUnit" max-width="450">
    <v-card>
      <v-toolbar>
        <v-row no-gutters class="fill-height px-6" align="center">
          <span class="font-weight-bold text-h6 text-capitalize">
            Delete {{ selectedUnit?.name || "Unit" }}
          </span>
        </v-row>
      </v-toolbar>
      <v-card-text>
        <span class="text-subtitle-2"
          >Are you sure you want to delete this unit?</span
        >
      </v-card-text>

      <v-toolbar class="pa-0" density="compact">
        <v-row no-gutters>
          <v-col cols="6" class="pa-0">
            <v-btn
              block
              variant="text"
              class="text-none"
              size="large"
              @click="dialogDeleteUnit = false"
              height="48"
            >
              Cancel
            </v-btn>
          </v-col>

          <v-col cols="6" class="pa-0">
            <v-btn
              block
              variant="flat"
              color="black"
              class="text-none font-weight-bold"
              height="48"
              :loading="submitting"
              @click="_deleteUnit"
            >
              Delete
            </v-btn>
          </v-col>
        </v-row>
      </v-toolbar>
    </v-card>
  </v-dialog>

  <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />

  <input
    ref="fileInput"
    type="file"
    accept=".csv,.xlsx,.xls"
    style="display: none"
    @change="onFileSelected"
  />
</template>

<script setup lang="ts">
import useUnits from "../composables/useUnits";
import useUtils from "../composables/useUtils";

const props = defineProps({
  orgId: { type: String, default: "" },
  site: { type: String, default: "" },
  serviceType: { type: String, default: "", required: true },
  canViewUnits: { type: Boolean, default: true },
  canCreateUnit: { type: Boolean, default: false },
  canUpdateUnit: { type: Boolean, default: false },
  canDeleteUnit: { type: Boolean, default: false },
  canImportUnit: { type: Boolean, default: false },
});

const items = ref<Array<Record<string, any>>>([]);
const siteName = ref<string>("");
const submitting = ref(false);
const isDownloading = ref(false);

const headers = [{ title: "UNIT", value: "name" }];

const { debounce } = useUtils();
const {
  getUnits,
  createUnit,
  updateUnit,
  deleteUnit,
  uploadUnits,
  downloadUnits,
} = useUnits();

const searchInput = ref("");
const startDate = ref("");
const endDate = ref("");
const page = ref(1);
const pages = ref(0);
const pageRange = ref("-- - -- of --");

const {
  data: getUnitsReq,
  refresh: getUnitsRefresh,
  pending: loading,
} = await useLazyAsyncData(
  "get-all-units",
  () =>
    getUnits({
      page: page.value,
      search: searchInput.value,
      site: props.site,
      serviceType: props.serviceType,
    }),
  {
    watch: [page, () => props.site],
  }
);

watchEffect(() => {
  if (getUnitsReq.value) {
    items.value = getUnitsReq.value.items;
    pages.value = getUnitsReq.value.pages;
    pageRange.value = getUnitsReq.value.pageRange;
  }
});

const debounceSearch = debounce(getUnitsRefresh, 500);

watch(
  [searchInput, endDate, startDate],
  ([]) => {
    debounceSearch();
  },
  { immediate: false, deep: true }
);

const selectedUnit = ref<Record<string, any> | null>(null);
const message = ref("");
const messageSnackbar = ref(false);
const messageColor = ref("");
const fileInput = ref<HTMLInputElement | null>(null);

const dialogShowMoreActions = ref(false);
const dialogShowForm = ref(false);
const dialogDeleteUnit = ref(false);
const dialogMode = ref<"add" | "edit">("add");

const editingUnit = ref<Record<string, any>>({});
const areaName = ref("");

function showMessage(msg: string, color: string = "error") {
  message.value = msg;
  messageColor.value = color;
  messageSnackbar.value = true;
}

const canViewUnits = computed(() => props.canViewUnits);
const canCreateUnit = computed(() => props.canCreateUnit);
const canUpdateUnit = computed(() => props.canUpdateUnit);
const canDeleteUnit = computed(() => props.canDeleteUnit);
const canImportUnit = computed(() => props.canImportUnit);

async function handleDownloadExcel() {
  try {
    isDownloading.value = true;

    if (!props.site || !/^[0-9a-fA-F]{24}$/.test(props.site)) {
      showMessage("Invalid site id for export.", "error");
      isDownloading.value = false;
      return;
    }

    const excelBuffer = await downloadUnits(props.site, props.serviceType);

    if (!excelBuffer) {
      showMessage("Failed to download units.", "error");
      return;
    }

    const blob = new Blob([excelBuffer], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");

    const date = new Date();
    const formattedDate = `${String(date.getMonth() + 1).padStart(
      2,
      "0"
    )}-${String(date.getDate()).padStart(2, "0")}-${date.getFullYear()}`;

    a.href = url;
    a.download = `units-${siteName.value || "export"}-${formattedDate}.xlsx`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);

    showMessage("Units exported successfully.", "success");
  } catch (error: any) {
    showMessage(error?.message || "Failed to download units.", "error");
  } finally {
    isDownloading.value = false;
  }
}

function onImportData() {
  fileInput.value?.click();
}

async function onFileSelected(event: Event) {
  const target = event.target as HTMLInputElement;
  const file = target.files?.[0];

  if (!file) return;

  try {
    submitting.value = true;

    const response = await uploadUnits(file, props.site, props.serviceType);
    showMessage(response?.message, "success");

    await getUnitsRefresh();
  } catch (err: any) {
    showMessage(err?.data?.message, "error");
  } finally {
    submitting.value = false;
    target.value = "";
  }
}

function onCreateUnit() {
  dialogMode.value = "add";
  editingUnit.value = {};
  dialogShowForm.value = true;
}

async function _createUnit(name: string) {
  try {
    submitting.value = true;
    let response;
    if (dialogMode.value === "edit" && editingUnit.value) {
      const id =
        (editingUnit.value as any)._id || (editingUnit.value as any).id;
      if (!id) throw new Error("Invalid unit id for update");
      response = await updateUnit(id, name);
    } else {
      response = await createUnit(name, props.site, props.serviceType);
    }
    showMessage(response?.message, "success");
    dialogShowForm.value = false;
    editingUnit.value = {};

    await getUnitsRefresh();
  } catch (err: any) {
    showMessage(err?.message, "error");
  } finally {
    submitting.value = false;
  }
}

function editUnit(unit: Record<string, any> | null) {
  if (!unit) return;
  dialogMode.value = "edit";
  editingUnit.value = unit;
  dialogShowForm.value = true;
}

function handleRowClick(data: any) {
  selectedUnit.value = data?.item;
  dialogShowMoreActions.value = true;
  message.value = "";
}

const onEditFromMoreAction = () => {
  dialogShowMoreActions.value = false;
  editUnit(selectedUnit.value);
};

const onDeleteFromMoreAction = () => {
  dialogShowMoreActions.value = false;
  dialogDeleteUnit.value = true;
};

async function _deleteUnit() {
  if (!selectedUnit.value) return;

  try {
    loading.value = true;
    const id =
      (selectedUnit.value as any)._id || (selectedUnit.value as any).id;
    if (!id) throw new Error("Invalid unit id");

    const response = await deleteUnit(id);
    dialogDeleteUnit.value = false;
    showMessage(response?.message, "success");

    await getUnitsRefresh();
  } catch (err: any) {
    const errorMessage = err?.data?.message || err?.message;
    dialogDeleteUnit.value = false;
    showMessage(errorMessage, "error");
  } finally {
    loading.value = false;
  }
}
</script>
