<script setup>
import * as XLSX from "xlsx";
import { ref } from "vue";
import { useAlert } from "../composables/alert";
import { VBtn } from "vuetify/components/VBtn";
const props = defineProps({
  stringFields: { type: Array, required: false, default: () => [] },
  tooltip: { type: null, required: false, default: () => ({ text: "Import", location: "bottom" }) }
});
const alert = useAlert();
const emit = defineEmits(["import"]);
const loading = ref(false);
const fileBtnRef = ref();
function uploadedFile(files) {
  if (!files) return;
  if (Array.isArray(files) && files.length != 1) {
    alert?.addAlert({ message: "Please select a single file for import", alertType: "error" });
    return;
  }
  if (Array.isArray(files)) files = files[0];
  const fileExtension = files.name.slice(files.name.lastIndexOf(".")).toLowerCase();
  if (![".xlsx", ".csv"].includes(fileExtension)) {
    alert?.addAlert({ message: `Please upload a file with .csv or .xlsx extension only (${files.name})`, alertType: "error" });
    return;
  }
  const reader = new FileReader();
  reader.onload = (e) => {
    const workbook = XLSX.read(e.target?.result);
    const parsedData = parseAndAggregateColumns(
      XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]])
    );
    emit("import", parsedData);
    loading.value = false;
    fileBtnRef.value.reset();
  };
  loading.value = true;
  reader.readAsArrayBuffer(files);
}
const parseAndAggregateColumns = (items) => {
  return items.map((item) => {
    const aggregatedItem = {};
    for (const key in item) {
      if (key.includes(".")) {
        const [rootKey, ...subKeys] = key.split(".");
        aggregatedItem[rootKey] = aggregatedItem[rootKey] || {};
        assignNestedValue(aggregatedItem[rootKey], subKeys, parseIfJson(item[key]));
      } else {
        if (props.stringFields.includes(key)) aggregatedItem[key] = item[key];
        else aggregatedItem[key] = parseIfJson(item[key]);
      }
    }
    return aggregatedItem;
  });
};
const assignNestedValue = (obj, keys, value) => {
  const [currentKey, ...remainingKeys] = keys;
  if (remainingKeys.length === 0) {
    obj[currentKey] = value;
  } else {
    obj[currentKey] = obj[currentKey] || {};
    assignNestedValue(obj[currentKey], remainingKeys, value);
  }
};
const parseIfJson = (value) => {
  if (typeof value === "string") {
    try {
      let parsedValue = JSON.parse(value);
      return parsedValue == value ? value : parsedValue;
    } catch {
      return value;
    }
  }
  return value;
};
</script>

<template>
  <FileBtn
      ref="fileBtnRef"
      v-bind="$attrs"
      color="primary"
      :loading="loading"
      text="Import CSV"
      accept=".csv, .xlsx"
      :multiple="false"
      @update:model-value="uploadedFile"
      :tooltip="props.tooltip"
  >
    <template
        v-for="(_, name, index) in $slots"
        :key="index"
        #[name]="slotData"
    >
      <slot
          :name="name"
          v-bind="slotData || {}"
      />
    </template>
  </FileBtn>
</template>
