<script setup lang="ts">
import { ref, useAttrs, watch } from "vue";
import { checkPermission } from "@/utils/permissions";
import { useRoute, useRouter } from "vue-router";

import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
import { useQuasar } from "quasar";

const route = useRoute();
const router = useRouter();

const $q = useQuasar();
const mixin = useCounterMixin();
const { dateToISO, success, modalError, dialogMessage } = mixin;

const attrs = ref<any>(useAttrs());
const table = ref<any>(null);
const files = ref<File[]>([]);
const filterRef = ref<any>(null);
const examId = ref<string>(route.params.examId.toString());
const selected = ref<string[]>([]);
const { messageError, showLoader, hideLoader } = mixin;

const dateFilter = ref<[Date, Date]>([new Date(), new Date()]); //วันที่เลือกค้นหา
const props = defineProps({
  inputfilter: String,
  inputvisible: Array,
  inputvisibleFilter: String,
  editvisible: Boolean,
  titleText: String,
  optionsFilter: {
    type: Array,
    defualt: [],
  },
  selected: {
    type: Array,
    defualt: [],
  },
  boss: {
    type: Boolean,
    defualt: false,
  },
  saveNoDraft: {
    type: Boolean,
    defualt: false,
  },
  history: {
    type: Boolean,
    defualt: false,
  },
  paging: {
    type: Boolean,
    defualt: false,
  },
  pageSize: {
    type: Number,
    defualt: 25,
  },
  page: {
    type: Number,
    defualt: 1,
  },
  maxPage: {
    type: Number,
    defualt: 1,
  },
  total: {
    type: Number,
    defualt: 0,
  },
  nornmalData: {
    type: Boolean,
    defualt: false,
  },
  nextPageVisible: {
    type: Boolean,
    defualt: false,
  },
  publicData: {
    type: Boolean,
    defualt: true,
    required: false,
  },
  updateData: {
    type: Boolean,
    defualt: true,
    required: false,
  },
  statusPayment: {
    type: Boolean,
    required: false,
  },
  setSeat: {
    type: Boolean,
    required: false,
  },
  publicNoBtn: {
    type: Boolean,
    defualt: false,
  },
  save: {
    type: Function,
    default: () => console.log("not function"),
  },
  cancel: {
    type: Function,
    default: () => console.log("not function"),
  },
  publish: {
    type: Function,
    default: () => console.log("not function"),
  },
  validate: {
    type: Function,
    default: () => console.log("not function"),
  },
  fetchData: {
    type: Function,
    default: () => console.log("not function"),
  },
});

// Pagination - initial pagination
const initialPagination = ref<any>({
  sortBy: null,
  descending: false,
  page: 1,
  rowsPerPage: props.pageSize,
});

// Pagination - update rowsPerPage
async function updatePagination(newPagination: any) {
  initialPagination.value = newPagination;
  currentPage.value = 1;
}

const emit = defineEmits([
  "update:inputfilter",
  "update:inputvisible",
  "update:editvisible",
  "update:titleText",
  "update:inputvisibleFilter",
  "update:change-page",
]);

const updateInput = async (value: any) => {
  emit("update:inputfilter", value);
};

// search & get new data by keyword
const submitInput = () => {
  setTimeout(() => {
    emit("update:change-page", 1, initialPagination.value.rowsPerPage);
    currentPage.value = 1;
  }, 500);
};

const updateVisible = (value: any) => {
  emit("update:inputvisible", value);
};
const updateVisibleFilter = (value: any) => {
  emit("update:inputvisibleFilter", value);
};

async function uploadFile() {
  if (files.value.length > 0) {
    if (props.setSeat == false) {
      uploadDataSeat();
    } else {
      uploadDataPoint();
    }
  } else {
    modalError(
      $q,
      "ไม่สามารถอัปโหลดไฟล์ได้",
      "กรุณาเลือกไฟล์ที่ต้องการอัปโหลด"
    );
  }
}

async function candidateToPlacement() {
  $q.dialog({
    title: "ยืนยันการนำผู้ผ่านคัดเลือกเข้าสู่ระบบบรรจุ",
    message: "ต้องการนำผู้ผ่านคัดเลือกเข้าสู่ระบบบรรจุใช่หรือไม่?",
    cancel: {
      flat: true,
      color: "negative",
    },
    persistent: true,
  })
    .onOk(async () => {
      await http
        .get(config.API.periodExamToPlacement(examId.value))
        .then(() => {
          success($q, "นำผู้ผ่านคัดเลือกเข้าสู่ระบบบรรจุ");
        })
        .catch((e) => {
          messageError($q, e);
        })
        .finally(async () => {
          hideLoader();
          router.go(-1);
        });
    })
    .onCancel(() => {})
    .onDismiss(() => {});
}

async function uploadDataSeat() {
  showLoader();
  const formData = new FormData();
  formData.append("", files.value[0]);
  await http
    .put(config.API.periodExamUploadSeat(examId.value), formData)
    .then(() => {
      success($q, "อัพเดทที่นั่งสอบสำเร็จ");
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(async () => {
      hideLoader();
      files.value = [];
      props.fetchData();
    });
}

async function uploadDataPoint() {
  showLoader();
  const formData = new FormData();
  formData.append("", files.value[0]);
  await http
    .put(config.API.periodExamUploadPoint(examId.value), formData)
    .then(() => {
      success($q, "อัพเดทคะแนนสอบสำเร็จ");
      files.value = [];
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(async () => {
      hideLoader();
      files.value = [];
      props.fetchData();
    });
}

async function downloadFile() {
  showLoader();
  await http
    .get(config.API.periodExamDownload(examId.value), {
      responseType: "blob",
    })
    .then((res) => {
      const data = res.data;
      downloadFilePDF(data, `Candidate__${dateToISO(new Date())}.xlsx`);
    })
    .catch(async (e) => {
      messageError($q, JSON.parse(await e.response.data.text()));
    })
    .finally(() => {
      hideLoader();
    });
}

async function downloadFileDetail() {
  showLoader();
  await http
    .get(config.API.periodExamDownloadDetail(examId.value), {
      responseType: "blob",
    })
    .then((res) => {
      const data = res.data;
      downloadFilePDF(data, `Candidate_Detail_${dateToISO(new Date())}.xlsx`);
    })
    .catch(async (e) => {
      messageError($q, JSON.parse(await e.response.data.text()));
    })
    .finally(() => {
      hideLoader();
    });
}

async function checkCandidates() {
  var _selected: any[] = [];
  selected.value.map((r: any) => {
    _selected.push(r.id.toString());
  });
  showLoader();
  await http
    .post(config.API.candidateCheckRegisters, {
      candidateId: _selected,
    })
    .then(() => {
      success($q, "ตรวจสอบข้อมูลสำเร็จ");
      selected.value = [];
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(() => {
      hideLoader();
      props.fetchData();
    });
}

async function downloadFilePDF(res: string, fileName: string) {
  const link = document.createElement("a");
  link.href = window.URL.createObjectURL(
    new Blob([res], {
      type: "application/vnd.ms-excel",
    })
  );
  link.setAttribute("download", fileName);
  document.body.appendChild(link);
  link.click();
}

async function candidateCheckProfileDialog() {
  dialogMessage(
    $q,
    "ยืนยันการตรวจสอบข้อมูลนี้หรือไม่?",
    "ยืนยันการตรวจสอบข้อมูล",
    "mdi-email-check-outline",
    "ยืนยัน",
    "public",
    checkCandidates,
    undefined
  );
}

function resetFilter() {
  // reset ค่าที่ค้นหาเมื่อกดปุ่ม X ในกล่องค้นหา
  emit("update:inputfilter", "");
  filterRef.value.focus();

  // clear keyword & get new data
  emit("update:change-page", 1, initialPagination.value.rowsPerPage);
  currentPage.value = 1;
}

async function downloadFileDashboard() {
  showLoader();
  await http
    .put(
      config.API.periodExamDownloadDashboard(examId.value),
      {
        dateStart: dateToISO(dateFilter.value[0]),
        dateEnd: dateToISO(dateFilter.value[1]),
        responseType: "blob",
      },
      {
        responseType: "blob",
      }
    )
    .then((res) => {
      const data = res.data;
      downloadFilePDF(
        data,
        `Candidate_Dashboard_${dateToISO(new Date())}.xlsx`
      );
    })
    .catch(async (e) => {
      messageError($q, JSON.parse(await e.response.data.text()));
    })
    .finally(() => {
      hideLoader();
    });
}

async function clickPassExam() {
  showLoader();
  await http
    .get(config.API.exportExamPassExamList(examId.value))
    .then(() => {
      window.open(config.API.exportExamPassExamList(examId.value));
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(() => {
      hideLoader();
    });
}

async function clickCandidateList() {
  showLoader();
  await http
    .get(config.API.exportExamCandidateList(examId.value))
    .then(() => {
      window.open(config.API.exportExamCandidateList(examId.value));
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(() => {
      hideLoader();
    });
}

// Pagination - page & change page & get new data
const currentPage = ref<number>(1);
watch(
  [() => currentPage.value, () => initialPagination.value.rowsPerPage],
  () => {
    emit(
      "update:change-page",
      currentPage.value,
      initialPagination.value.rowsPerPage,
      true
    );
  }
);
</script>
<template>
  <div class="q-px-md q-pb-md">
    <q-card
      bordered
      flat
      class="col-12 row q-py-sm items-center bg-grey-1"
      v-show="statusPayment"
    >
      <div class="col-12 row q-col-gutter-sm">
        <span class="text-subtitle1">{{ titleText }}</span>
        <q-select
          dense
          outlined
          :model-value="inputvisibleFilter"
          :options="optionsFilter"
          option-value="id"
          option-label="name"
          map-options
          class="col-xs-12 col-sm-3"
          label="สถานะ"
          emit-value
          @update:model-value="updateVisibleFilter"
          v-if="optionsFilter != undefined && optionsFilter.length > 0"
        />
        <q-file
          v-model="files"
          dense
          :label="setSeat == false ? 'อัปโหลดที่นั่งสอบ' : 'อัปโหลดคะแนนสอบ'"
          outlined
          use-chips
          multiple
          class="col-xs-12 col-sm-4"
          v-if="statusPayment && checkPermission($route)?.attrIsUpdate"
        >
          <template v-slot:prepend>
            <q-icon name="attach_file" color="blue" />
          </template>
        </q-file>
        <div>
          <q-btn
            size="md"
            icon="mdi-upload"
            round
            flat
            color="blue"
            v-if="statusPayment && checkPermission($route)?.attrIsUpdate"
            @click="uploadFile"
          >
            <q-tooltip v-if="setSeat == false">อัปโหลดที่นั่งสอบ</q-tooltip>
            <q-tooltip v-if="setSeat == true">อัปโหลดคะแนนสอบ</q-tooltip>
          </q-btn>
        </div>
      </div>
    </q-card>
    <div class="col-12 row q-py-sm items-center q-col-gutter-sm">
      <div class="col-xs-12 col-sm-3" v-show="!statusPayment">
        <q-select
          dense
          outlined
          :model-value="inputvisibleFilter"
          :options="optionsFilter"
          option-value="id"
          option-label="name"
          map-options
          class=""
          label="สถานะ"
          emit-value
          @update:model-value="updateVisibleFilter"
          v-if="optionsFilter != undefined && optionsFilter.length > 0"
        />
      </div>
      <div>
        <q-btn
          v-if="checkPermission($route)?.attrIsUpdate"
          size="md"
          icon="mdi-playlist-check"
          round
          flat
          color="primary"
          @click="candidateCheckProfileDialog"
          :disabled="attrs.rows.filter((r: any) => r.status == 'checkRegister').length == 0 ||
            selected.length == 0
            "
        >
          <q-tooltip>ตรวจสอบข้อมูล/ได้รับใบสมัครแล้ว</q-tooltip>
        </q-btn>
      </div>
      <div>
        <q-btn icon="mdi-download" round color="green-6" flat>
          <q-tooltip>ดาวน์โหลดไฟล์</q-tooltip>
          <q-menu>
            <q-list style="min-width: 100px">
              <q-item clickable v-close-popup @click="downloadFileDashboard">
                <q-item-section>ดาวน์โหลดสรุปข้อมูลสมัครสอบ</q-item-section>
              </q-item>
              <q-item
                clickable
                v-close-popup
                @click.stop.prevent="clickCandidateList()"
              >
                <q-item-section>ดาวน์โหลดรายชื่อผู้มีสิทธิ์สอบ</q-item-section>
              </q-item>
              <q-item
                clickable
                v-close-popup
                @click.stop.prevent="clickPassExam()"
              >
                <q-item-section
                  >ดาวน์โหลดรายชื่อผู้สอบคัดเลือกได้</q-item-section
                >
              </q-item>
              <q-item clickable v-close-popup @click="downloadFile()">
                <q-item-section>ดาวน์โหลดจัดการรายชื่อผู้สมัคร</q-item-section>
              </q-item>
              <q-item clickable v-close-popup @click="downloadFileDetail()">
                <q-item-section>ดาวน์โหลดข้อมูลผู้สมัคร</q-item-section>
              </q-item>
            </q-list>
          </q-menu>
        </q-btn>
      </div>
      <div>
        <q-btn
          size="md"
          icon="mdi-content-save-move-outline"
          round
          flat
          color="indigo"
          v-if="
            statusPayment &&
            setSeat == true &&
            checkPermission($route)?.attrIsUpdate
          "
          @click="candidateToPlacement"
        >
          <q-tooltip>บรรจุผู้ผ่านการคัดเลือก</q-tooltip>
        </q-btn>
      </div>
      <q-space />
      <div class="items-center gt-xs" style="display: flex">
        <!-- ค้นหาข้อความใน table -->
        <!-- @keydown.enter.prevent:model-value="updateInput" -->
        <q-input
          :model-value="inputfilter"
          @keydown.enter.prevent="submitInput"
          @update:model-value="updateInput"
          ref="filterRef"
          standout
          dense
          outlined
          debounce="300"
          placeholder="ค้นหา"
          style="max-width: 200px"
          class="q-ml-sm"
        >
          <template v-slot:append>
            <q-icon v-if="inputfilter == ''" name="search" />
            <q-icon
              v-if="inputfilter !== ''"
              name="clear"
              class="cursor-pointer"
              @click="resetFilter"
            />
          </template>
        </q-input>
        <!-- แสดงคอลัมน์ใน table -->
        <q-select
          :model-value="inputvisible"
          @update:model-value="updateVisible"
          :display-value="$q.lang.table.columns"
          multiple
          outlined
          dense
          :options="attrs.columns"
          options-dense
          option-value="name"
          map-options
          emit-value
          style="min-width: 140px"
          class="q-ml-sm"
        />
      </div>
    </div>

    <q-table
      ref="table"
      flat
      bordered
      class="custom-header-table"
      v-bind="attrs"
      virtual-scroll
      :virtual-scroll-sticky-size-start="48"
      dense
      :pagination="initialPagination"
      :rows-per-page-options="paging == true ? [25, 50, 100, 500] : []"
      row-key="id"
      selection="multiple"
      v-model:selected="selected"
      @update:pagination="updatePagination"
      :filter="false"
    >
      <template v-slot:pagination="scope">
        ทั้งหมด {{ props.total }} รายการ
        <q-pagination
          v-model="currentPage"
          active-color="primary"
          color="dark"
          :max-pages="5"
          size="sm"
          boundary-links
          direction-links
          :max="Number(props.maxPage)"
        ></q-pagination>
      </template>
      <template v-slot:header="props">
        <q-tr :props="props">
          <q-th auto-width v-if="checkPermission($route)?.attrIsUpdate">
            <q-checkbox v-model="props.selected" />
          </q-th>
          <q-th auto-width v-if="boss == true" />
          <q-th v-for="col in props.cols" :key="col.name" :props="props">
            <span class="text-weight-medium">{{ col.label }}</span>
          </q-th>
          <q-th
            auto-width
            v-if="
              editvisible == true || nextPageVisible == true || history == true
            "
          />
        </q-tr>
      </template>
      <template #body="props">
        <slot v-bind="props" name="columns"></slot>
      </template>
    </q-table>
  </div>
</template>

<style lang="scss">
.icon-color {
  color: #4154b3;
}

.custom-header-table {
  max-height: 64vh;

  .q-table tr:nth-child(odd) td {
    background: white;
  }

  .q-table tr:nth-child(even) td {
    background: #f8f8f8;
  }

  .q-table thead tr {
    background: #ecebeb;
  }

  .q-table thead tr th {
    position: sticky;
    z-index: 1;
  }

  /* this will be the loading indicator */
  .q-table thead tr:last-child th {
    /* height of all previous header rows */
    top: 48px;
  }

  .q-table thead tr:first-child th {
    top: 0;
  }
}
</style>
