<template>
  <section class="h-screen-main w-full px-4 flex flex-col justify-between items-start">
    <!-- Upload Content -->
    <div class="w-full h-[calc(100%_-_64px)]">
      <!-- File name -->
      <!-- cursor-pointer -->
      <div class="h-12 pl-1 border-b border-neutral-300 flex items-center" title="Rename">
        <InputText type="text" v-model="fileName" id="fileNameInput" class="rounded !border-transparent !font-bold !text-base !py-1 min-w-[1px] w-auto" @input="onInput" @blur="onBlur" />
      </div>
      <!-- Upload notification -->
      <div class="flex justify-start items-center space-x-2 ml-2 py-2">
        <span class="material-symbols-outlined text-neutral-700 cursor-pointer" v-tooltip.right="tooltipUpload">info</span>
        <span class="w-px h-7 bg-neutral-300"></span>
        <!-- Upload text -->
        <div>
          <div v-if="!isDisabled"></div>
          <div v-else-if="isInform" class="flex justify-start items-center space-x-2 duration-700">
            <span class="material-symbols-outlined text-primary">notifications</span>
            <p class="text-primary text-sm">
              Please verify the label for each column before uploading.
            </p>
          </div>
          <div v-else class="flex justify-start items-center space-x-2 duration-700">
            <span class="material-symbols-outlined material-fill text-danger">warning</span>
            <p class="text-danger text-sm">
              Need to select
              <span v-for="(item, index) in informData" :key="index">[ {{ item }} ]<span v-if="index !== informData.length - 1">, </span></span>.
            </p>
            <div v-if="repeatedData.length !== 0" class="duration-700">
              <p v-if="repeatedData.length === 1" class="text-danger text-sm">
                [ {{repeatedData[0]}} ] has been assigned.
              </p>
              <p v-else class="text-danger text-sm">
                <span v-for="(item, index) in repeatedData" :key="index">[ {{ item }} ]<span v-if="index !== repeatedData.length - 1">, </span></span>
                have been assigned.
              </p>
            </div>
          </div>
        </div>
        </div>
      <!-- Upload table -->
      <div class="overflow-y-auto overflow-x-auto scrollbar max-h-[calc(100%_-_97px)]">
        <table class="text-sm w-full table-fixed border-separate border-spacing-0">
          <thead class="sticky top-0 bg-neutral-10">
            <tr>
              <td v-for="(item, index) in uploadDetail?.columns" :key="index" class="border border-neutral-500 p-2">{{ item }}</td>
            </tr>
            <tr>
              <td v-for="(item, index) in uploadDetail?.columns" :key="index" class="px-2 py-1 bg-neutral-300 border border-neutral-500">
                <Dropdown
                v-model="selectedColumns[index]"
                :options="columnType"
                optionLabel="name"
                placeholder="Not Assigned"
                class="w-full !border-neutral-500"
                :data-type="item"
                :inputId="index.toString()"
                :inputClass="selectedColumns[index]?.color"
                inputClass="!text-sm">
                  <template #option="slotProps">
                    <div :class="slotProps.option.color" class="text-sm">
                      <span>{{ slotProps.option.name }}</span>
                    </div>
                  </template>
                </Dropdown>
              </td>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(item, index) in uploadDetail?.data" :key="index">
              <td v-for="(itemDetail, key) in item" :key="key" class="border border-neutral-500 p-2 truncate break-keep">{{ itemDetail }}</td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
    <!-- Upload button -->
    <div class="w-full text-right space-x-4 px-8 py-4">
      <button type="button" class="btn btn-sm btn-neutral" @click="cancel">Cancel</button>
      <button type="button" class="btn btn-sm btn-neutral" @click="reset">Reset</button>
      <button type="button" class="btn btn-sm" @click="submit" :disabled="isDisabled" :class="isDisabled ? 'btn-disable' : 'btn-neutral'">Upload</button>
      </div>
  </section>
</template>
<script>
import { storeToRefs } from 'pinia';
import LoadingStore from '@/stores/loading.js';
import FilesStore from '@/stores/files.js';
import { uploadFailedFirst, uploadSuccess, uploadConfirm } from '@/module/alertModal.js'

export default {
  setup() {
    const loadingStore = LoadingStore();
    const filesStore = FilesStore();
    const { isLoading } = storeToRefs(loadingStore);
    const { uploadDetail, uploadId, uploadFileName } = storeToRefs(filesStore);

    return { isLoading, filesStore, uploadDetail, uploadId, uploadFileName }
  },
  data() {
    return {
      tooltipUpload: {
        value: `1. Case ID: A unique identifier for each case.
          2. Activity: A process step executed by either a system (automated) or humans (manual).
          3. Activity Instance ID: A unique identifier for a single occurrence of an activity.
          4. Timestamp: The time of occurrence of a particular event, such as the start or end of an activity.
          5. Status: Activity status, such as Start or Complete.
          6. Attribute: A property that can be associated with a case to provide additional information about that case.`,
          // 暫時沒有 Resource
          // 7. Resource: A resource refers to any entity that is required to carry out a business process. This can include people, equipment, software, or any other type of asset.
       class: '!max-w-[400px] !text-[10px] !opacity-80',
       autoHide: false,
      },
      columnType: [
        { name: 'Case ID*', code: 'case_id', color: '!text-secondary', value: '' },
        { name: 'Timestamp*', code: 'timestamp', color: '!text-secondary', value: '' },
        { name: 'Status*', code: 'status', color: '!text-secondary', value: '' },
        { name: 'Activity*', code: 'name', color: '!text-secondary', value: '' },
        { name: 'Activity Instance ID*', code: 'instance', color: '!text-secondary', value: '' },
        { name: 'Case Attribute', code: 'case_attributes', color: '!text-primary', value: '' },
        // { name: 'Resource', code: '', color: '', value: '' }, // 現階段沒有，未來可能有
        { name: 'Not Assigned', code: '', color: '!text-neutral-700', value: '' },
      ],
      selectedColumns: [],
      isInform: true, // true: 藍字提示; false: 紅字提示
      informData: [], // 紅字提示，尚未選擇的 type
      repeatedData: [], // 紅字提示，重複選擇的 type
      baseTypeData: ['Case ID*', 'Timestamp*', 'Status*', 'Activity*', 'Activity Instance ID*'],
      fileName: this.uploadFileName,
    };
  },
  computed: {
    isDisabled: function() {
      // 1. 長度一樣，強制每一個都要選
      // 2. 不為 null undefind
      let hasValue = !this.selectedColumns.includes(undefined);
      let result = !(this.selectedColumns.length === this.uploadDetail?.columns.length && this.informData.length === 0 && this.repeatedData.length === 0 && hasValue) ? true : false;
      return result
    },
  },
  watch: {
    selectedColumns: {
      deep: true, // 監聽陣列內部的變化
      handler(newVal, oldVal) {
        this.updateValidationData(newVal);
      },
    }
  },
  methods: {
    uploadFailedFirst,
    uploadSuccess,
    uploadConfirm,
    /**
     * Rename 離開 input 的行為
     * @param {Event} e
     */
    onBlur(e) {
      const baseWidth = 20;

      if(e.target.value === '') {
        e.target.value = this.uploadFileName;
        const textWidth = this.getTextWidth(e.target.value, e.target);
        e.target.style.width = baseWidth + textWidth + 'px';
      }else if(e.target.value !== e.target.value.trim()) {
        e.target.value = e.target.value.trim();
        const textWidth = this.getTextWidth(e.target.value, e.target);
        e.target.style.width = baseWidth + textWidth + 'px';
      }
    },
    /**
     * Rename 輸入 input 的行為
     * @param {Event} e
     */
    onInput(e) {
      const baseWidth = 20;
      const textWidth = this.getTextWidth(e.target.value, e.target);

      e.target.style.width = baseWidth + textWidth + 'px';
    },
    /**
     * input 寬度隨著 value 響應式改變
     * @param {String} text
     * @param {Event} e
     */
    getTextWidth(text, e) {
      // 替換空格為不斷行的空格
      const processedText = text.replace(/ /g, '\u00a0');
      const hiddenSpan = document.createElement('span');
      let width;

      hiddenSpan.innerHTML = processedText;
      hiddenSpan.style.font = window.getComputedStyle(e).font;
      hiddenSpan.style.visibility = 'hidden';
      document.body.appendChild(hiddenSpan);
      width = hiddenSpan.getBoundingClientRect().width;
      document.body.removeChild(hiddenSpan);

      return width;
    },
    /**
     * 驗證，根據新的 selectedColumns 更新 isInform、informData 和 repeatedData
     * @param {Array} data
     */
    updateValidationData(data) {
      const nameOccurrences = {};
      let selectedData = [] // 已經選擇的 data
      this.informData = []; // 尚未選擇的 data
      this.repeatedData = []; // 重複選擇的 data

      data.forEach(item => {
        const { name, code } = item;

        if(nameOccurrences[name]) {
          // 'Not Assigned'、'Case Attribute' 不列入驗證
          if(!code || code === 'case_attributes') return;
          nameOccurrences[name]++;
          this.repeatedData.push(name);
        }else {
          nameOccurrences[name] = 1;
          selectedData.push(name);
          this.informData = this.baseTypeData.filter(item => !selectedData.includes(item));
        }
      });
      this.isInform = (this.informData.length === 0 && this.repeatedData.length === 0) ? true : false;
    },
    /**
     * Reset Button
     */
    reset() {
      // 路徑不列入歷史紀錄
      this.selectedColumns = [];
    },
    /**
     * Cancel Button
     */
    cancel() {
      // 路徑不列入歷史紀錄
      this.$router.push({name: 'Files', replace: true});
    },
    /**
     * Upload Button
     */
    async submit() {
      // Post API Data
      let fetchData = {
        timestamp: '',
        case_id: '',
        name: '',
        instance: '',
        status: '',
        case_attributes: []
      };
      // 給值
      let haveValueData = this.selectedColumns.map((column, i) => {
        if (column && this.uploadDetail.columns[i]) {
          return {
            name: column.name,
            code: column.code,
            color: column.color,
            value: this.uploadDetail.columns[i]
          }
        }
      });

      // 取得欲更改的檔名，
      this.uploadFileName = this.fileName;
      // 設定第二階段上傳的 data
      haveValueData.forEach(column => {
        switch (column.code) {
          case 'timestamp':
            fetchData.timestamp = column.value;
            break;
          case 'case_id':
            fetchData.case_id = column.value;
            break;
          case 'name':
            fetchData.name = column.value;
            break;
          case 'instance':
            fetchData.instance = column.value;
            break;
          case 'status':
            fetchData.status = column.value;
            break;
          case 'case_attributes':
            fetchData.case_attributes.push(column.value);
            break;
          default:
            break;
        }
      });
      this.uploadConfirm(fetchData);
    },
  },
  mounted() {
    // 只監聽第一次
    let unwatch = this.$watch('fileName', (newValue) => {
        if (newValue) {
          const inputElement = document.getElementById('fileNameInput');
          const baseWidth = 20;
          const textWidth = this.getTextWidth(this.fileName, inputElement);
          inputElement.style.width = baseWidth + textWidth + 'px';
        }
      },
      { immediate: true }
    );
    this.isInform = true; // 初始為藍字提示
    this.showEdit = true;
    if(this.uploadId) this.filesStore.getUploadDetail();
    unwatch();
    this.isLoading = false;
  },
  beforeUnmount() {
    // 離開頁面要刪 uploadID
    this.uploadId = null;
    this.uploadFileName = null;
  },
  beforeRouteEnter(to, from, next){
    // 要有 uploadID 才能進來
    next(vm => {
      if(vm.uploadId == null) {
        vm.$router.push({name: 'Files', replace: true});
        vm.$toast.default('Please upload your file.', {position: 'bottom'});
        return
      }
    })
  },
}
</script>
