<script setup lang="ts">
import { computed, reactive, ref } from "vue";
import { useQuasar } from "quasar";
import axios from "axios";
import { storeToRefs } from "pinia";

import { useCounterMixin } from "@/stores/mixin";
import { usePositionKeycloakStore } from "@/stores/positionKeycloak";
import { useMenuDataStore } from "@/stores/menuList";
import http from "@/plugins/http";
import config from "@/app.config";

import DialogHeader from "@/components/DialogHeader.vue";

const $q = useQuasar();
const store = usePositionKeycloakStore();
const { dataPositionKeycloak } = storeToRefs(store);
const { findOrgName } = store;

const { menuList } = storeToRefs(useMenuDataStore());
const { dialogConfirm, showLoader, hideLoader, messageError, success } =
  useCounterMixin();

const modal = defineModel<boolean>("modal", {
  default: false,
});

const title = computed(() => "แจ้งปัญหาการใช้งานระบบ");
const orgName = computed(() => findOrgName(dataPositionKeycloak.value) || "");
const optionData = computed(() => {
  return menuList.value.map((menu) => ({
    label: menu.sysName,
    value: menu.sysName,
    disable: menu?.children?.length === 0 ? false : true,
    children: menu?.children?.map((subMenu) => ({
      label: subMenu.sysName,
      value: `${menu.sysName}/${subMenu.sysName}`,
    })),
  }));
});

const menuSelect = ref();
const optionsMenu = ref(optionData.value);
const formData = reactive({
  title: "",
  description: "",
  system: "mgt",
  fileAttachments: [] as File[],
  menu: "",
  org: orgName.value,
});

/** ฟังก์ชันบันทึกข้อมูล */
function onSubmit() {
  dialogConfirm($q, async () => {
    try {
      showLoader();
      const payload = {
        title: formData.title,
        description: formData.description,
        system: formData.system,
        menu: formData.menu,
        org: formData.org,
      };

      const res = await http.post(config.API.orgIssues, payload);

      const issueCode = res.data.result.codeIssue;
      await uploadProfile(issueCode);
      success($q, "บันทึกข้อมูลเรียบร้อย");

      onClose();
    } catch (error) {
      messageError($q, error);
    } finally {
      hideLoader();
    }
  });
}

/**
 * ฟังก์ชันเพิ่มไฟล์
 * @param files ไฟล์ที่ต้องการเพิ่ม
 */
async function onAddfile(files: any) {
  files.forEach((file: any) => {
    formData.fileAttachments.push(file);
  });
}

/**
 * ฟังก์ชันลบไฟล์
 * @param files ไฟล์ที่ต้องการลบ
 */
async function onRemoveFile(files: any) {
  files.forEach((file: any) => {
    const index = formData.fileAttachments.findIndex(
      (x: any) => x.__key == file.__key
    );
    if (index > -1) {
      formData.fileAttachments.splice(index, 1);
    }
  });
}

/**
 * ฟังก์ชันสร้าง url อัปโหลดไฟล์
 * @param code รหัส issue
 */
async function uploadProfile(code: string) {
  if (formData.fileAttachments.length === 0) {
    return;
  }
  try {
    const fileName = formData.fileAttachments.map((file) => ({
      fileName: file.name,
    }));
    const res = await http.post(
      config.API.file("issueAttachments", "documents", code),
      {
        replace: false,
        fileList: fileName,
      }
    );

    for (const file of formData.fileAttachments) {
      const fileInfo = res.data[file.name];
      if (fileInfo && fileInfo.uploadUrl) {
        await uploadFileDoc(fileInfo.uploadUrl, file);
      }
    }
  } catch (e) {
    messageError($q, e);
  }
}

/**
 * ฟังก์ชันอัปโหลดไฟล์เอกสาร
 * @param uploadUrl ลิงก์อัปโหลดไฟล์
 * @param file ไฟล์ที่ต้องการอัปโหลด
 */
async function uploadFileDoc(uploadUrl: string, file: any) {
  try {
    await axios.put(uploadUrl, file, {
      headers: {
        "Content-Type": file.type,
      },
    });
  } catch (e) {
    messageError($q, e);
  }
}

/**
 * ฟังก์ชันกรองข้อมูลใน select
 * @param val ค่าที่กรอง
 * @param update ฟังก์ชันอัปเดตค่าหลังกรอง
 */
function filterSelector(val: string, update: Function) {
  update(() => {
    if (!val) {
      optionsMenu.value = optionData.value;
      return;
    }
    optionsMenu.value = optionData.value
      .map((parent: any) => {
        const matchParent = parent.label.indexOf(val) > -1;

        const filteredChildren = (parent.children || []).filter(
          (child: any) => child.label.indexOf(val) > -1
        );
        if (matchParent) {
          return { ...parent };
        } else if (filteredChildren.length > 0) {
          return { ...parent, children: filteredChildren };
        }

        return null;
      })
      .filter((item: any) => item !== null);
  });
}

/** ฟังก์ชันปิด dialog และรีเซ็ตข้อมูล */
function onClose() {
  modal.value = false;
  formData.menu = "";
  formData.title = "";
  formData.description = "";
  formData.fileAttachments = [];
  formData.org = orgName.value;
}
</script>

<template>
  <q-dialog v-model="modal" persistent>
    <q-card style="width: 700px; max-width: 80vw">
      <q-form greedy @submit.prevent @validation-success="onSubmit">
        <DialogHeader :tittle="title" :close="onClose" />
        <q-separator />

        <q-card-section>
          <div class="row col q-col-gutter-md">
            <div class="col-12">
              <q-select
                ref="menuSelect"
                dense
                outlined
                label="ระบบ"
                v-model="formData.menu"
                :options="optionsMenu"
                class="inputgreen"
                :rules="[ (val: string) => !!val || 'กรุณาเลือกระบบ' ]"
                hide-bottom-space
                emit-value
                map-options
                use-input
                @filter="(inputValue: string,
              doneFn: Function) => filterSelector(inputValue, doneFn, 
              )"
              >
                <template v-slot:option="scope">
                  <q-item v-bind="scope.itemProps">
                    <q-item-section>
                      <q-item-label>{{ scope.opt.label }}</q-item-label>
                    </q-item-section>
                  </q-item>
                  <q-list v-if="scope.opt.children">
                    <q-item
                      v-for="child in scope.opt.children"
                      :key="child.value"
                      clickable
                      @click.stop="
                        formData.menu = child.value;
                        menuSelect.hidePopup();
                      "
                    >
                      <q-item-section class="q-ml-md">
                        {{ child.label }}
                      </q-item-section>
                    </q-item>
                  </q-list>
                </template>
              </q-select>
            </div>
            <div class="col-12">
              <q-input
                dense
                outlined
                label="หัวข้อปัญหา"
                v-model="formData.title"
                class="inputgreen"
                :rules="[ (val: string) => !!val || 'กรุณากรอกหัวข้อปัญหา' ]"
                hide-bottom-space
              />
            </div>
            <div class="col-12">
              <q-input
                dense
                outlined
                type="textarea"
                label="รายละเอียดปัญหา"
                v-model="formData.description"
                class="inputgreen"
                :rules="[ (val: string) => !!val || 'กรุณากรอกรายละเอียดปัญหา' ]"
                hide-bottom-space
              />
            </div>
            <div class="col-12">
              <q-uploader
                color="gray"
                type="file"
                flat
                ref="uploader"
                class="full-width"
                text-color="dark"
                accept=".jpg,.png,.pdf,.csv,.doc"
                bordered
                label="[ไฟล์ jpg,png,pdf,csv,doc ขนาดไม่เกิน 5MB]"
                multiple
                max-file-size="5000000"
                @added="onAddfile"
                @removed="onRemoveFile"
              >
                <template v-slot:header="scope">
                  <div
                    class="row no-wrap items-center q-pa-sm q-gutter-xs text-white"
                  >
                    <q-btn
                      v-if="scope.queuedFiles.length > 0"
                      icon="clear_all"
                      @click="scope.removeQueuedFiles"
                      round
                      dense
                      flat
                    >
                      <q-tooltip>ลบทั้งหมด</q-tooltip>
                    </q-btn>
                    <q-btn
                      v-if="scope.uploadedFiles.length > 0"
                      icon="done_all"
                      @click="scope.removeUploadedFiles"
                      round
                      dense
                      flat
                    >
                      <q-tooltip>ลบไฟล์ที่อัปโหลด</q-tooltip>
                    </q-btn>
                    <q-spinner
                      v-if="scope.isUploading"
                      class="q-uploader__spinner"
                    />
                    <div class="col">
                      <div class="q-uploader__title">
                        {{ "[ไฟล์ jpg,png,pdf,csv,doc ขนาดไม่เกิน 5MB]" }}
                      </div>
                      <div class="q-uploader__subtitle">
                        {{ scope.uploadSizeLabel }}
                        /
                        {{ scope.uploadProgressLabel }}
                      </div>
                    </div>
                    <q-btn
                      v-if="scope.canAddFiles"
                      type="a"
                      icon="add_box"
                      @click="scope.pickFiles"
                      round
                      dense
                      flat
                    >
                      <q-uploader-add-trigger />
                      <q-tooltip>เลือกไฟล์</q-tooltip>
                    </q-btn>
                    <q-btn
                      v-if="scope.isUploading"
                      icon="clear"
                      @click="scope.abort"
                      round
                      dense
                      flat
                    >
                      <q-tooltip>ยกเลิกการอัปโหลด</q-tooltip>
                    </q-btn>
                  </div>
                </template>
              </q-uploader>
            </div>
          </div>
        </q-card-section>

        <q-separator />
        <q-card-actions align="right">
          <q-btn
            type="submit"
            for="#submitForm"
            class="q-px-md items-center"
            color="public"
            label="บันทึก"
          >
            <q-tooltip>บันทึกข้อมูล</q-tooltip>
          </q-btn>
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>

<style scoped></style>
