<script setup lang="ts">
import { onMounted, ref, watch } from "vue";
import { useQuasar, type QTableProps } from "quasar";

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

import type {
  RequestItemsObject,
  DataDateRowObject,
  DataDateAddObject,
  DataDateListsObject,
  TabsObject,
} from "@/modules/01_metadata/interface/index/Calendar";

const $q = useQuasar(); //ใช้ noti quasar
const {
  success,
  dateToISO,
  dateMonth2Thai,
  weekThai,
  messageError,
  showLoader,
  dialogRemove,
} = useCounterMixin();

const props = defineProps({
  dateYear: {
    //filter ปี วันหยุด
    type: Number,
    required: true,
  },
  refreshData: {
    //หน้า main มีการอัพเดทค่าให้ refresh data
    type: Boolean,
    required: true,
  },
  fetchDataSummaryCalendar: {
    //ฟังก์ชันอัพเดทสรุปวันหยุด
    type: Function,
    default: () => console.log("not function"),
  },
});

const calendarData = ref<DataDateListsObject[]>([]); //data วันหยุด
const modalAdd = ref<boolean>(false); //modal เพิ่มวันหยุด
const name = ref<string>(""); //ชื่อวันหยุด
const isSpecial = ref<boolean>(true); //เช็ควันหยุด
const dateAdd = ref<[Date, Date]>([new Date(), new Date()]); //วันที่ ที่เพิ่มเป็นวันหยุด
const rowData = ref<DataDateListsObject>(); //data ที่ถูกเลือกใน row นั้น

const currentTab = ref<string>("normal"); //เลือก tab ประเภทวันหยุด
const tabs = ref<TabsObject[]>([
  { label: "ทำงานจันทร์-ศุกร์ (5 วัน)", value: "normal" },
  { label: "ทำงานจันทร์-เสาร์ (6 วัน)", value: "6day" },
]); //tab ประเภทวันหยุดทั้งหมด

//columns รายการวันหยุด
const columns = ref<QTableProps["columns"]>([
  {
    name: "week",
    align: "left",
    label: "-",
    sortable: true,
    field: "week",
    style: "font-size: 15px",
  },
  {
    name: "holidayDate",
    align: "left",
    label: "-",
    sortable: true,
    field: "holidayDate",
    style: "font-size: 15px",
  },
  {
    name: "detail",
    align: "left",
    label: "-",
    sortable: true,
    field: "detail",
    style: "font-size: 15px",
  },
]);

/**
 * กดปุ่มแก้ไขวันหยุด
 * @param val data วันหยุดทั้ง row
 */
async function editCalendar(val: DataDateListsObject) {
  rowData.value = val;
  dateAdd.value = [val.dateRange[0], val.dateRange[1]];
  name.value = val.detail;
  isSpecial.value = true;
  modalAdd.value = true;
}

/**
 * กดปุ่มลบวันหยุด
 * @param val data วันหยุดทั้ง row
 */
async function deleteClick(val: DataDateListsObject) {
  rowData.value = val;
  dialogRemove($q, async () => deleteConfirm());
}

/**
 * fetch วันหยุดในรายการ
 */
async function fetchData() {
  calendarData.value = [];
  showLoader();
  await http
    .get(config.API.listHolidayHistoryYear(props.dateYear))
    .then((res) => {
      let data = res.data.result.normal;
      if (currentTab.value == "6day") {
        data = res.data.result.sixDays;
      }
      const dateStart = ref<Date | null>();
      const firstEvent = ref<boolean>(true);
      const dateRow = ref<DataDateRowObject[]>([]);
      data.map((e: RequestItemsObject, index: number) => {
        dateRow.value.push({
          holidayDate: new Date(e.holidayDate),
          name: e.name,
          isSpecial: true,
          id: e.id,
        });
        if (
          index == data.length - 1 ||
          data[index + 1].name != e.name ||
          (data[index + 1].name == e.name &&
            dateToISO(new Date(data[index + 1].holidayDate)) !=
              dateToISO(
                new Date(
                  new Date(e.holidayDate).setDate(
                    new Date(e.holidayDate).getDate() + 1
                  )
                )
              ))
        ) {
          firstEvent.value = true;
          calendarData.value.push({
            id: e.id,
            dateRange: [
              dateStart.value ? dateStart.value : new Date(e.holidayDate),
              new Date(e.holidayDate),
            ],
            dataRangeRow: dateRow.value,
            detail:
              dateToISO(new Date(e.holidayDate)) ==
              dateToISO(new Date(e.originalDate))
                ? e.name
                : `ชดเชย ${e.name}`,
            isSpecial: true,
          });
          dateStart.value = null;
          dateRow.value = [];
        } else if (firstEvent.value == true) {
          firstEvent.value = false;
          dateStart.value = new Date(e.holidayDate);
        }
      });
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(async () => {
      await props.fetchDataSummaryCalendar();
    });
}

/**
 * ลบข้อมูลวันหยุด
 */
async function deleteConfirm() {
  const dataDelete = ref<DataDateAddObject[]>([]);
  if (rowData.value != null) {
    rowData.value.dataRangeRow.map((e: DataDateRowObject) => {
      dataDelete.value.push({
        year: new Date(e.holidayDate).getFullYear(),
        holidayDate: dateToISO(e.holidayDate),
        name: e.name,
        isSpecial: true,
      });
    });
  } else {
    return;
  }
  showLoader();
  await http
    .post(
      config.API.listHolidayHistoryDelete(currentTab.value),
      dataDelete.value
    )
    .then(() => {
      success($q, "ลบข้อมูลสำเร็จ");
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(async () => {
      await fetchData();
    });
}

/**
 * บันทึกแก้ไขวันหยุด
 */
async function onSubmit() {
  const dataEdit = ref<DataDateAddObject[]>([]);
  let i = 0;
  const dateStart = ref<Date>(dateAdd.value[0]);
  do {
    i = i + 1;
    dataEdit.value.push({
      year: new Date(dateStart.value).getFullYear(),
      holidayDate: dateToISO(new Date(dateStart.value)),
      name: name.value,
      isSpecial: true,
    });
    dateStart.value = new Date(
      new Date(dateStart.value).setDate(new Date(dateStart.value).getDate() + 1)
    );
  } while (new Date(dateStart.value) <= new Date(dateAdd.value[1]));
  const _dataHistory = ref<DataDateAddObject[]>([]);
  if (rowData.value != null) {
    rowData.value.dataRangeRow.map((e: DataDateRowObject, index: number) => {
      _dataHistory.value.push({
        year: new Date(e.holidayDate).getFullYear(),
        holidayDate: dateToISO(e.holidayDate),
        name: e.name,
        isSpecial: true,
      });
    });
  }
  showLoader();
  await http
    .post(config.API.listHolidayHistoryEdit(currentTab.value), {
      history: _dataHistory.value,
      updated: dataEdit.value,
    })
    .then(() => {
      modalAdd.value = false;
      success($q, "แก้ไขข้อมูลสำเร็จ");
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(async () => {
      await fetchData();
    });
}

/**
 * เปลี่ยน tab ดูวันหยุดตามประเภท
 * @param tab tab ประเภทวันหยุดที่เลือก
 */
async function changeTab(tab: string) {
  currentTab.value = tab;
  await fetchData();
}

/**
 * แปลงช่วงวันที่ถ้า2ค่าเป็นวันเดียวกันจะโชววันเดียวแต่ถ้าไม่เท่ากันจะแสดงเป็นช่วง
 * @param val ช่วงวันที่
 */
function dateThaiRange(val: [Date, Date]) {
  if (val === null) {
    return "";
  } else if (dateMonth2Thai(val[0], true) === dateMonth2Thai(val[1], true)) {
    return `${dateMonth2Thai(val[0], true)}`;
  } else {
    return `${dateMonth2Thai(val[0], true)} - ${dateMonth2Thai(val[1], true)}`;
  }
}

/**
 * แปลงช่วงวันที่ถ้า2ค่าเป็นวันเดียวกันจะโชววันเดียวแต่ถ้าไม่เท่ากันจะแสดงเป็นช่วง(เช่นวันจันทร์ -วันศุกร์)
 * @param val ช่วงวันที่
 */
function dayThaiRange(val: [Date, Date]) {
  if (val === null) {
  } else if (dateToISO(val[0]) == dateToISO(val[1])) {
    return `${weekThai(new Date(val[0]).getDay())}`;
  } else {
    return `${weekThai(new Date(val[0]).getDay())} - ${weekThai(
      new Date(val[1]).getDay()
    )}`;
  }
}

/**
 * เรียกฟังก์ชันทั้งหมดตอนเรียกใช้ไฟล์นี้
 */
onMounted(async () => {
  await fetchData();
});

/**
 * ค่า props(วันปีที่เลือก และเพิ่มหรือแก้ไข) ตอนอัพเดท ค่าฏิทินให้อัพเดทใหม่
 */
watch(props, async (count, prevCount) => {
  await fetchData();
});
</script>

<!-- tab รายการ หน้าปฏิทินวันหยุด -->
<template>
  <q-card class="q-mt-md" flat bordered>
    <!-- list รายการันหยุด -->
    <q-tabs
      dense
      v-model="currentTab"
      indicator-color="primary"
      active-color="primary bg-teal-1"
      class="text-body2 text-grey-7"
    >
      <q-tab
        v-for="tab in tabs"
        :key="tab.value"
        v-on:click="changeTab(tab.value)"
        :label="tab.label"
        :name="tab.value"
        class="q-py-xs col-6 row"
      />
    </q-tabs>
    <q-separator />

    <q-tab-panels v-model="currentTab" animated>
      <q-tab-panel name="normal">
        <q-table
          ref="table"
          flat
          bordered
          class="custom-header-table"
          virtual-scroll
          :rows="calendarData"
          :columns="columns"
          dense
          :rows-per-page-options="[0]"
          hide-header
        >
          <template v-slot:body="props">
            <q-tr :props="props">
              <q-td auto-width>
                <q-btn flat round color="grey" @click.stop icon="more_vert">
                  <q-menu>
                    <q-list>
                      <q-item
                        clickable
                        v-close-popup
                        @click="editCalendar(props.row)"
                      >
                        <q-item-section>
                          <div class="row items-center">
                            <q-icon color="edit" name="edit" size="xs" />
                            <div class="q-pl-md">แก้ไขวันหยุด</div>
                          </div>
                        </q-item-section>
                      </q-item>
                      <q-item
                        clickable
                        v-close-popup
                        @click="deleteClick(props.row)"
                      >
                        <q-item-section>
                          <div class="row items-center">
                            <q-icon color="red" name="mdi-delete" size="xs" />
                            <div class="q-pl-md">ลบวันหยุด</div>
                          </div>
                        </q-item-section>
                      </q-item>
                    </q-list>
                  </q-menu>
                </q-btn>
              </q-td>
              <q-td v-for="col in props.cols" :key="col.name" :props="props">
                <div v-if="col.name == 'week'" class="">
                  {{ dayThaiRange(props.row.dateRange) }}
                </div>
                <div v-else-if="col.name == 'holidayDate'" class="">
                  {{ dateThaiRange(props.row.dateRange) }}
                </div>
                <div v-else class="my-table-details">
                  {{ col.value }}
                </div>
              </q-td>
            </q-tr>
          </template>
        </q-table>
      </q-tab-panel>

      <q-tab-panel name="6day">
        <q-table
          ref="table"
          flat
          bordered
          class="custom-header-table"
          virtual-scroll
          :rows="calendarData"
          :columns="columns"
          dense
          :rows-per-page-options="[0]"
          hide-header
        >
          <template v-slot:body="props">
            <q-tr :props="props">
              <q-td auto-width>
                <q-btn
                  flat
                  round
                  color="grey"
                  @click.stop
                  size="10px"
                  icon="more_vert"
                >
                  <q-menu>
                    <q-list>
                      <q-item
                        clickable
                        v-close-popup
                        @click="editCalendar(props.row)"
                      >
                        <q-item-section>
                          <div class="row items-center">
                            <q-icon color="edit" name="edit" size="xs" />
                            <div class="q-pl-md">แก้ไขวันหยุด</div>
                          </div>
                        </q-item-section>
                      </q-item>
                      <q-item
                        clickable
                        v-close-popup
                        @click="deleteClick(props.row)"
                      >
                        <q-item-section>
                          <div class="row items-center">
                            <q-icon color="red" name="mdi-delete" size="xs" />
                            <div class="q-pl-md">ลบวันหยุด</div>
                          </div>
                        </q-item-section>
                      </q-item>
                    </q-list>
                  </q-menu>
                </q-btn>
              </q-td>
              <q-td v-for="col in props.cols" :key="col.name" :props="props">
                <div v-if="col.name == 'week'" class="">
                  {{ dayThaiRange(props.row.dateRange) }}
                </div>
                <div v-else-if="col.name == 'holidayDate'" class="">
                  {{ dateThaiRange(props.row.dateRange) }}
                </div>
                <div v-else class="my-table-details">
                  {{ col.value }}
                </div>
              </q-td>
            </q-tr>
          </template>
        </q-table>
      </q-tab-panel>
    </q-tab-panels>
  </q-card>

  <!-- modal เพิ่มวันหยุด -->
  <q-dialog v-model="modalAdd" persistent>
    <q-card style="min-width: 550px">
      <q-form greedy @submit.prevent @validation-success="onSubmit()">
        <q-card-section class="row items-center q-pb-xs">
          <div class="text-bold">แก้ไขวันหยุด</div>
          <q-space />
          <q-btn
            icon="close"
            unelevated
            round
            dense
            v-close-popup
            style="color: #ff8080; background-color: #ffdede"
          />
        </q-card-section>
        <q-separator />
        <q-card-section class="q-p-sm">
          <div class="row q-col-gutter-sm">
            <div class="col-2 subName">
              <label>เลือกวันที่</label>
            </div>
            <div class="col-10">
              <datepicker
                v-model="dateAdd"
                :locale="'th'"
                autoApply
                range
                :enableTimePicker="false"
                week-start="0"
              >
                <template #year="{ year }">
                  {{ year + 543 }}
                </template>
                <template #year-overlay-value="{ value }">
                  {{ parseInt(value + 543) }}
                </template>
                <template #trigger>
                  <q-input
                    outlined
                    dense
                    class="full-width datepicker"
                    :model-value="dateThaiRange(dateAdd)"
                  >
                    <template v-slot:prepend>
                      <q-icon
                        name="event"
                        class="cursor-pointer"
                        style="color: var(--q-primary)"
                      >
                      </q-icon>
                    </template>
                  </q-input>
                </template>
              </datepicker>
            </div>
            <div class="col-2 subName">
              <label>คำอธิบาย</label>
            </div>
            <div class="col-10">
              <q-input
                dense
                autogrow
                outlined
                class="full-width datepicker q-pb-none"
                v-model="name"
                type="textarea"
                :rules="[(val:string) => (val && val.length > 0) || '']"
              />
            </div>
          </div>
        </q-card-section>
        <q-separator />
        <q-card-actions align="right" class="text-primary">
          <q-btn unelevated label="บันทึก" color="public" type="submit">
          </q-btn>
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>

<style lang="scss" scope>
.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;
  }
}

.my-table-details {
  white-space: -moz-pre-wrap !important;
  /* Mozilla, since 1999 */
  white-space: -webkit-pre-wrap;
  /* Chrome & Safari */
  white-space: -pre-wrap;
  /* Opera 4-6 */
  white-space: -o-pre-wrap;
  /* Opera 7 */
  white-space: pre-wrap;
  /* CSS3 */
  word-wrap: break-word;
  /* Internet Explorer 5.5+ */
  word-break: break-all;
  white-space: normal;
}

.table_ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: wrap;
  max-width: 250px;
}
</style>
