<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 equipment found for ${siteName}.`"
        @refresh="getEquipmentsRefresh"
        :canCreate="canAddEquipment"
        createLabel="Add Equipment"
        @row-click="handleRowClick"
      >
        <template #actions>
          <v-row no-gutters align="center" class="w-100">
            <v-col cols="auto" v-if="canAddEquipment">
              <v-btn
                class="text-none"
                rounded="pill"
                variant="tonal"
                size="large"
                @click="onCreateUnit()"
              >
                Add Equipment
              </v-btn>
            </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.status="{ value }">
          <v-chip class="text-capitalize">{{ value || "N/A" }}</v-chip>
        </template>

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

  <AddEqupmentForm
    v-model="dialogShowForm"
    v-model:name="equipmentName"
    v-model:unitOfMeasurement="equipmentUnit"
    :mode="dialogMode"
    :equipmentData="editingEquipment"
    :site="props.site"
    @saved="_createEquipment"
  />

  <v-dialog v-model="dialogShowMoreActions" width="400" persistent>
    <HygieneUpdateMoreAction
      :title="selectedEquipment?.name || 'Unit Actions'"
      :canUpdate="canUpdateEquipment"
      :canDelete="canDeleteEquipment"
      :showAddStock="canAddStock"
      :showViewStock="canViewStock"
      :showRequestItem="canRequestItem"
      :manageButtonLabel="''"
      :editButtonLabel="'Edit Equipment'"
      :deleteButtonLabel="'Delete Equipment'"
      :addStockButtonLabel="'Add Stock'"
      :viewButtonLabel="'View Stock'"
      :requestItemButtonLabel="'Checkout Item'"
      @close="dialogShowMoreActions = false"
      @edit="onEditFromMoreAction"
      @delete="onDeleteFromMoreAction"
      @addstock="onAddStockFromMoreAction"
      @view-stock="onViewStockFromMoreAction"
      @requestItem="onRequestItemFromMoreAction"
    >
      <template #content>
        <v-row no-gutters>
          <v-col v-if="selectedEquipment" cols="12" class="mb-2">
            <v-row no-gutters class="mb-2">
              <v-col cols="5" class="text-subtitle-2 font-weight-bold">
                Name:
              </v-col>
              <v-col cols="7" class="text-subtitle-2">
                {{ selectedEquipment.name || "N/A" }}
              </v-col>
            </v-row>

            <v-row no-gutters class="mb-2">
              <v-col cols="5" class="text-subtitle-2 font-weight-bold">
                Quantity:
              </v-col>
              <v-col cols="7" class="text-subtitle-2">
                {{ selectedEquipment.qty || "N/A" }}
              </v-col>
            </v-row>

            <v-row no-gutters class="mb-2">
              <v-col cols="5" class="text-subtitle-2 font-weight-bold">
                Unit of Measurement:
              </v-col>
              <v-col cols="7" class="text-subtitle-2">
                {{ selectedEquipment.unitOfMeasurement || "N/A" }}
              </v-col>
            </v-row>

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

  <v-dialog v-model="dialogDeleteEquipment" 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 {{ selectedEquipment?.name || "Unit" }}
          </span>
        </v-row>
      </v-toolbar>
      <v-card-text>
        <span class="text-subtitle-2"
          >Are you sure you want to delete this equipment?</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="dialogDeleteEquipment = 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="_deleteEquipment"
            >
              Delete
            </v-btn>
          </v-col>
        </v-row>
      </v-toolbar>
    </v-card>
  </v-dialog>

  <v-dialog v-model="dialogStockAction" 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">
            {{ stockActionMode === "add" ? "Add Stock" : "Checkout Item" }}
          </span>
        </v-row>
      </v-toolbar>
      <v-card-text class="pa-4">
        <v-form ref="stockActionFormRef" v-model="stockActionValid">
          <v-row no-gutters>
            <v-col cols="12" class="mb-4">
              <InputLabel
                for="stockActionQty"
                title="Quantity"
                required
                class="mb-1"
              />
              <v-text-field
                v-model.number="stockActionQuantity"
                :rules="[requiredRule]"
                density="comfortable"
                variant="outlined"
                type="number"
                min="1"
                placeholder="Enter quantity"
                hide-details="auto"
              />
            </v-col>
          </v-row>
        </v-form>
      </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="dialogStockAction = 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 rounded-0"
              height="48"
              :loading="submitting"
              @click="stockActionMode === 'add' ? _addStock() : _requestItem()"
            >
              {{ stockActionMode === "add" ? "Add Stock" : "Checkout Item" }}
            </v-btn>
          </v-col>
        </v-row>
      </v-toolbar>
    </v-card>
  </v-dialog>

  <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
</template>
<script setup lang="ts">
import useEquipment from "../composables/useEquipment";
import useStock from "../composables/useStock";
import useUtils from "../composables/useUtils";
import useEquipmentManagement from "../composables/useEquipmentManagement";

const props = defineProps({
  orgId: { type: String, default: "" },
  site: { type: String, default: "" },
  serviceType: { type: String, default: "" },
  canViewEquipments: { type: Boolean, default: true },
  canAddEquipment: { type: Boolean, default: false },
  canUpdateEquipment: { type: Boolean, default: false },
  canDeleteEquipment: { type: Boolean, default: false },
  canAddStock: { type: Boolean, default: false },
  canViewStock: { type: Boolean, default: true },
  canRequestItem: { type: Boolean, default: false },
});

const canViewEquipments = computed(() => props.canViewEquipments);
const canAddEquipment = computed(() => props.canAddEquipment);
const canUpdateEquipment = computed(() => props.canUpdateEquipment);
const canDeleteEquipment = computed(() => props.canDeleteEquipment);
const canAddStock = computed(() => props.canAddStock);
const canViewStock = computed(() => props.canViewStock);
const canRequestItem = computed(() => props.canRequestItem);

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

const headers = [
  { title: "Name", value: "name" },
  { title: "Available Stock Qty", value: "qty" },
  { title: "Status", value: "status" },
];

const {
  getEquipments,
  getEquipmentById,
  createEquipment,
  updateEquipment,
  deleteEquipment,
} = useEquipment();
const { debounce, requiredRule } = useUtils();

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

const {
  data: getEquipmentsReq,
  refresh: getEquipmentsRefresh,
  pending: loading,
} = await useLazyAsyncData<any>(
  "get-all-equipments",
  () =>
    getEquipments({
      page: page.value,
      search: searchInput.value,
      site: props.site,
      serviceType: props.serviceType,
    }),
  {
    watch: [page, () => props.site],
  }
);

watchEffect(() => {
  if (getEquipmentsReq.value) {
    items.value = getEquipmentsReq.value.items;

    pages.value = getEquipmentsReq.value.pages;
    pageRange.value = getEquipmentsReq.value.pageRange;
  }
});

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

const selectedEquipment = ref<Record<string, any>>({});
const message = ref("");
const messageSnackbar = ref(false);
const messageColor = ref("");

const dialogShowMoreActions = ref(false);
const dialogShowForm = ref(false);
const dialogDeleteEquipment = ref(false);
const dialogStockAction = ref(false);
const stockActionMode = ref<"add" | "request">("add");
const dialogMode = ref<"add" | "edit">("add");

const editingEquipment = ref<Record<string, any>>({});
const equipmentName = ref("");
const equipmentUnit = ref("");

const stockActionFormRef = ref<any>(null);
const stockActionValid = ref(false);

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

function onCreateUnit() {
  dialogMode.value = "add";
  editingEquipment.value = {};
  equipmentName.value = "";
  equipmentUnit.value = "";
  dialogShowForm.value = true;
}

async function _createEquipment() {
  submitting.value = true;
  try {
    const payload: TEquipmentCreate = {
      name: equipmentName.value,
      unitOfMeasurement: equipmentUnit.value,
    };

    let response;

    if (dialogMode.value === "edit" && editingEquipment.value) {
      const id =
        (editingEquipment.value as any)._id ||
        (editingEquipment.value as any).id;
      if (!id) throw new Error("Invalid equipment id for update");
      response = await updateEquipment(id, payload);
    } else {
      response = await createEquipment(payload, props.site, props.serviceType);
    }

    showMessage(response?.message, "success");
    dialogShowForm.value = false;
    editingEquipment.value = {};
    equipmentName.value = "";
    equipmentUnit.value = "";

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

const selectedEquipmentId = ref("");

const {
  data: getEquipmentByIdReq,
  refresh: getEquipmentByIdRefresh,
  status: getEquipmentByIdStatus,
} = await useLazyAsyncData<any>(
  "get-equipment-by-id",
  () => getEquipmentById(selectedEquipmentId.value),
  {
    watch: [selectedEquipmentId],
    immediate: false,
  }
);

watchEffect(() => {
  if (getEquipmentByIdReq.value && getEquipmentByIdStatus.value === "success") {
    selectedEquipment.value = getEquipmentByIdReq.value;
  }
});

async function handleRowClick(data: any) {
  selectedEquipment.value = data?.item;
  message.value = "";

  selectedEquipmentId.value = selectedEquipment.value._id;
  await getEquipmentByIdRefresh();

  dialogShowMoreActions.value = true;
}

const onEditFromMoreAction = async () => {
  dialogShowMoreActions.value = false;
  if (!selectedEquipment.value) return;

  submitting.value = true;
  selectedEquipmentId.value = selectedEquipment.value._id;
  await getEquipmentByIdRefresh();
  submitting.value = false;

  const response = getEquipmentByIdReq.value;
  if (!response) return;

  dialogMode.value = "edit";
  editingEquipment.value = response;
  equipmentName.value = response.name || "";
  equipmentUnit.value = response.unitOfMeasurement || "";
  dialogShowForm.value = true;
};

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

const onAddStockFromMoreAction = () => {
  dialogShowMoreActions.value = false;
  stockActionMode.value = "add";
  stockActionQuantity.value = 0;
  stockActionRemarks.value = "";
  dialogStockAction.value = true;
};

const onViewStockFromMoreAction = () => {
  dialogShowMoreActions.value = false;
  const org = props.orgId;
  const site = props.site;
  const id = selectedEquipment.value._id;
  useRouter().push(`/${org}/${site}/equipment-management/stock/${id}`);
};

const onRequestItemFromMoreAction = () => {
  dialogShowMoreActions.value = false;
  stockActionMode.value = "request";
  stockActionQuantity.value = 0;
  stockActionRemarks.value = "";
  dialogStockAction.value = true;
};

async function _deleteEquipment() {
  if (!selectedEquipment.value) return;

  try {
    submitting.value = true;
    const id =
      (selectedEquipment.value as any)._id ||
      (selectedEquipment.value as any).id;
    if (!id) throw new Error("Invalid equipment id");

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

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

const { createStock } = useStock();
const { checkOutItemSingle } = useEquipmentManagement();

const stockActionQuantity = ref<number>(0);
const stockActionRemarks = ref("");

async function _addStock() {
  submitting.value = true;
  try {
    const id = selectedEquipment.value._id || selectedEquipment.value.id;

    const payload: TStockCreate = {
      qty: stockActionQuantity.value,
      remarks: stockActionRemarks.value,
      serviceType: props.serviceType,
    };

    const response = await createStock(props.site, id, payload);
    showMessage(response?.message, "success");
    dialogStockAction.value = false;
    stockActionQuantity.value = 0;
    stockActionRemarks.value = "";

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

async function _requestItem() {
  submitting.value = true;
  try {
    const id = selectedEquipment.value._id || selectedEquipment.value.id;

    const payload: TStockCreate = {
      qty: stockActionQuantity.value,
      serviceType: props.serviceType,
    };

    const response = await checkOutItemSingle(props.site, id, payload);
    showMessage(response?.message, "success");
    dialogStockAction.value = false;
    stockActionQuantity.value = 0;

    await getEquipmentsRefresh();
  } catch (error: any) {
    console.error(error);
    showMessage(error?.data?.message, "error");
  } finally {
    submitting.value = false;
  }
}
</script>
