<!-- tab ตำแหน่งประเภท หน้าจัดการข้อมูลหลัก/ข้อมูลตำแหน่งของข้าราชการกรุงเทพมหานคร -->
<template>
  <div>
    <q-form ref="myForm">
      <data-table
        :rows="rows"
        :columns="columns"
        :filter="filter"
        :visible-columns="visibleColumns"
        v-model:inputfilter="filter"
        v-model:inputvisible="visibleColumns"
        v-model:editvisible="edit"
        :add="clickAdd"
        :edit="clickEdit"
        :save="clickSave"
        :deleted="clickDelete"
        :cancel="clickCancel"
        :publish="clickPublish"
        :validate="validateData"
        :publicData="version === 'published'"
        :updateData="updateData"
        :history="true"
      >
        <template #columns="props">
          <q-tr :props="props" v-if="edit == false">
            <q-td v-for="col in props.cols" :key="col.name" :props="props">
              <div v-if="col.name == 'isActive'" class="">
                <q-icon
                  v-if="col.value == false"
                  name="mdi-close"
                  color="red"
                  class="text-h5"
                />
                <q-icon
                  v-else
                  name="mdi-check"
                  color="positive"
                  class="text-h5"
                />
              </div>
              <div v-else-if="col.name == 'createdAt'" class="">
                {{ textDate(col.value) }}
              </div>
              <div v-else-if="col.name == 'lastUpdatedAt'" class="">
                {{ textDate(col.value) }}
              </div>
              <div v-else class="">
                {{ col.value }}
              </div>
            </q-td>
            <q-td auto-width>
              <q-btn
                color="info"
                flat
                dense
                round
                size="14px"
                icon="mdi-history"
                @click="clickHistory(props.row)"
              />
            </q-td>
          </q-tr>
          <q-tr :props="props" v-if="edit == true">
            <q-td key="name" :props="props" v-if="props.row.name !== undefined">
              <q-input
                class=""
                outlined
                @update:model-value="clickEditRow"
                v-model="props.row.name"
                dense
                lazy-rules
                autofocus
                hide-bottom-space
                :rules="[
                  (val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
                  (val) =>
                    checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
                ]"
              ></q-input>
            </q-td>
            <q-td
              key="createdAt"
              :props="props"
              v-if="props.row.createdAt !== undefined"
            >
              <div class="">
                {{ textDate(props.row.createdAt) }}
              </div>
            </q-td>
            <q-td key="lastUpdatedAt" :props="props">
              <div class="">
                {{ textDate(props.row.lastUpdatedAt) }}
              </div>
            </q-td>
            <q-td
              key="lastUpdateFullName"
              :props="props"
              v-if="props.row.lastUpdateFullName !== undefined"
              class=""
            >
              {{ props.row.lastUpdateFullName }}
            </q-td>
            <q-td
              key="isActive"
              :props="props"
              v-if="props.row.isActive !== undefined"
            >
              <q-toggle
                v-model="props.row.isActive"
                dense
                size="34px"
                color="positive"
                @update:model-value="clickEditRow"
              />
            </q-td>

            <q-td auto-width>
              <q-btn
                v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
                color="red"
                flat
                dense
                round
                size="14px"
                icon="mdi-trash-can-outline"
                @click="clickDeleteRow(props.row)"
              />
              <q-btn
                v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
                color="info"
                flat
                dense
                round
                size="14px"
                icon="mdi-history"
                @click="clickHistory(props.row)"
              />
            </q-td>
          </q-tr>
        </template>
      </data-table>
    </q-form>
  </div>
  <HistoryTable
    :rows="rowsHistory"
    :columns="columnsHistory"
    :filter="filterHistory"
    :visible-columns="visibleColumnsHistory"
    v-model:modal="modalHistory"
    v-model:inputfilter="filterHistory"
    v-model:inputvisible="visibleColumnsHistory"
    v-model:tittle="tittleHistory"
  >
    <template #columns="props">
      <q-tr :props="props">
        <q-td v-for="col in props.cols" :key="col.name" :props="props">
          <div v-if="col.name == 'isActive'" class="">
            <q-icon
              v-if="col.value == false"
              name="mdi-close"
              color="red"
              class="text-h5"
            />
            <q-icon v-else name="mdi-check" color="positive" class="text-h5" />
          </div>
          <div v-else-if="col.name == 'lastUpdatedAt'" class="">
            {{ textDate(col.value) }}
          </div>
          <div v-else class="">
            {{ col.value }}
          </div>
        </q-td>
      </q-tr>
    </template>
  </HistoryTable>
</template>

<script setup lang="ts">
import type { QTableProps } from "quasar";
import { useQuasar } from "quasar";
import { onMounted, ref, watch } from "vue";
import http from "@/plugins/http";
import config from "@/app.config";
import keycloak from "@/plugins/keycloak";
import { useCounterMixin } from "@/stores/mixin";
import { useManageDataStore } from "@/modules/01_metadata/store";
import type {
  RequestItemsHistoryObject,
  RequestItemsPublishHistoryObject,
  Columns,
} from "@/modules/01_metadata/interface/request/position/Type";
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/position/Type";
import HistoryTable from "@/components/TableHistory.vue";

const props = defineProps({
  fetchDataComponent: {
    type: Function,
    default: () => console.log("not function"),
  },
});

const mixin = useCounterMixin();
const { success, dateText, messageError, showLoader, hideLoader } = mixin;
const store = useManageDataStore();
const { manageData, changeManageColumns, getPositionType, dataPositionType } =
  store;
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
const tittleHistory = ref<string>("ประวัติแก้ไขตำแหน่งประเภท"); //
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
const filter = ref<string>(""); //search data table
const filterHistory = ref<string>(""); //search data table history
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
const idVersion = ref<string>(""); //id data ใน mongodb
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่

const checkValidate = ref<boolean>(false);

const columns = ref<QTableProps["columns"]>([
  {
    name: "name",
    align: "left",
    label: "ตำแหน่งประเภท",
    sortable: true,
    field: "name",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "createdAt",
    align: "center",
    label: "วันที่สร้าง",
    sortable: true,
    field: "createdAt",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "lastUpdatedAt",
    align: "center",
    label: "วันที่แก้ไข",
    sortable: true,
    field: "lastUpdatedAt",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "lastUpdateFullName",
    align: "left",
    label: "ผู้ดำเนินการ",
    sortable: true,
    field: "lastUpdateFullName",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "isActive",
    align: "left",
    label: "สถานะ",
    sortable: true,
    field: "isActive",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
]);

const visibleColumns = ref<String[]>([]);
manageData.position.type.columns.length == 0
  ? (visibleColumns.value = [
      "name",
      "createdAt",
      "lastUpdatedAt",
      "lastUpdateFullName",
      "isActive",
    ])
  : (visibleColumns.value = manageData.position.type.columns);

const columnsHistory = ref<QTableProps["columns"]>([
  {
    name: "name",
    align: "left",
    label: "ตำแหน่งประเภท",
    sortable: true,
    field: "name",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "lastUpdatedAt",
    align: "center",
    label: "วันที่แก้ไข",
    sortable: true,
    field: "lastUpdatedAt",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "lastUpdateFullName",
    align: "left",
    label: "ผู้ดำเนินการ",
    sortable: true,
    field: "lastUpdateFullName",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
  {
    name: "isActive",
    align: "left",
    label: "สถานะ",
    sortable: true,
    field: "isActive",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
    sort: (a: string, b: string) =>
      a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
  },
]);

const visibleColumnsHistory = ref<String[]>([
  "name",
  "lastUpdatedAt",
  "lastUpdateFullName",
  "isActive",
]);

/**
 * เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
 */
onMounted(async () => {
  await fetchData();
  await fetchHistory();
});

watch(visibleColumns, async (count: String[], prevCount: String[]) => {
  await changeManageColumns(3, "type", count);
});

/**
 * แจ้งเตือนข้อมูลในกรณี success
 */
const $q = useQuasar();

/**
 * ฟังก์ชัน get data ล่าสุด
 */
const fetchData = async (load: boolean = false) => {
  await props.fetchDataComponent();
  const result = await getPositionType(false, load);
  version.value = result.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
  idVersion.value = result.idversion; //เลข id ใน mongodb
  rows.value = result.data;
  updateData.value = false;
  //   rows.value.splice(0);
  //   showLoader();
  //   await http
  //     .get(config.API.listPositionTypeHistory)
  //     .then((res) => {
  //       let data = res.data.result;
  //       version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
  //       idVersion.value = data.id; //เลข id ใน mongodb
  //       data.items.map((e: RequestItemsHistoryObject) => {
  //         rows.value.push({
  //           id: e.id,
  //           name: e.name,
  //           createdAt: e.createdAt,
  //           lastUpdatedAt: e.lastUpdatedAt,
  //           lastUpdateFullName: e.lastUpdateFullName,
  //           isActive: e.isActive,
  //           createdFullName: e.createdFullName,
  //           createdUserId: e.createdUserId,
  //           lastUpdateUserId: e.lastUpdateUserId,
  //         });
  //       });
  //     })
  //     .catch((e) => {
  //       messageError($q, e);
  //     })
  //     .finally(() => {
  //       updateData.value = false;
  //       hideLoader();
  //     });
};

/**
 * ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
 */
const fetchHistory = async () => {
  showLoader();
  await http
    .get(config.API.listPositionTypePublishedHistory)
    .then((res) => {
      const data = res.data.result;
      rawHistory.value = [];
      if (data.length > 0) {
        data.map((e: RequestItemsPublishHistoryObject) => {
          e.items.map((i: RequestItemsHistoryObject) => {
            rawHistory.value.push({
              createdAt: i.createdAt,
              createdFullName: i.createdFullName,
              createdUserId: i.createdUserId,
              id: i.id,
              isActive: i.isActive,
              lastUpdateFullName: i.lastUpdateFullName,
              lastUpdateUserId: i.lastUpdateUserId,
              lastUpdatedAt: i.lastUpdatedAt,
              name: i.name,
            });
          });
        });
      }
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(async () => {
      hideLoader();
    });
};

/**
 * ฟังก์ชัน clear data แบบร่าง
 * เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
 */
const clearPublishedData = async () => {
  showLoader();
  await http
    .delete(config.API.listPositionTypeHistory)
    .then((res) => {
      success($q, "ลบข้อมูลร่างสำเร็จ");
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(async () => {
      await fetchHistory();
      await fetchData(true);
    });
};

/**
 * ฟังก์ชันเผยแพร่แบบร่าง
 * เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
 */
const publishedData = async () => {
  showLoader();
  await http
    .get(config.API.listPositionTypePublished)
    .then((res) => {
      success($q, "เผยแพร่ข้อมูลสำเร็จ");
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(async () => {
      await fetchData(true);
    });
};

/**
 * ฟังก์ชันเพิ่มข้อมูล
 */
const clickAdd = async () => {
  const filterRowNull = rows.value.filter(
    (f: RequestItemsHistoryObject) =>
      f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
  );
  if (filterRowNull.length == 0) {
    //ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
    rows.value.push({
      createdAt: new Date(),
      createdFullName: "",
      createdUserId: "",
      id: "00000000-0000-0000-0000-000000000000",
      isActive: true,
      lastUpdateFullName:
        keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
      lastUpdateUserId: "",
      lastUpdatedAt: new Date(),
      name: "",
    });
    updateData.value = true;
  }
};

/**
 * ฟังก์ชันบันทึกแบบร่าง
 * เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
 * publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
 */
const save = async (publish: boolean) => {
  await validateData();
  if (checkValidate.value == false) return;
  rows.value.map((e: ResponseHistoryObject) => ({
    //จัด data ก่อนส่งไป backend
    id: e.id,
    createdAt: e.createdAt,
    lastUpdatedAt: e.lastUpdatedAt,
    name: e.name,
    isActive: e.isActive,
    createdFullName: e.createdFullName,
    createdUserId: e.createdUserId,
    lastUpdateFullName: e.lastUpdateFullName,
    lastUpdateUserId: e.lastUpdateUserId,
  }));
  showLoader();
  await http
    .post(config.API.listPositionTypeHistoryId(idVersion.value), {
      id: idVersion.value,
      version: "draft",
      items: rows.value,
    })
    .then(async (res) => {
      if (publish === false) {
        success($q, "บันทึกข้อมูลร่างสำเร็จ");
        await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
      } else {
        await publishedData(); //เผยแพร่ข้อมูลต
      }
      edit.value = false;
    })
    .catch((e) => {
      messageError($q, e);
    })
    .finally(async () => {
      hideLoader();
      await fetchData(true);
    });
};

/**
 * เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
 * @param val input ชื่อ
 */
const checkDupDataName = (val: string) => {
  const filterNameNull = rows.value.filter(
    (f: RequestItemsHistoryObject) => f.name == val
  ); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
  if (filterNameNull.length > 1) {
    return false;
  }
  return true;
};

/**
 * ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
 */
const clickEdit = async () => {
  await fetchData();
};

/**
 * ฟังก์ชันปุ่มบันทึกแบบร่าง
 */
const clickSave = async () => {
  await save(false);
  await fetchData(true);
};

/**
 * ฟังก์ชันปุ่มลบแบบร่าง
 */
const clickDelete = async () => {
  await clearPublishedData();
  await fetchData(true);
};

/**
 * ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
 */
const clickCancel = async () => {
  edit.value = false;
  await fetchData(true);
};

/**
 * ฟังก์ชันปุ่มเผยแพร่ข้อมูล
 * เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
 * ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
 */
const clickPublish = async () => {
  if (myForm.value !== null) {
    myForm.value.validate().then(async (result: boolean) => {
      if (result) {
        await save(true);
      }
    });
  } else {
    await save(true);
  }
};

/**
 * ฟังก์ชันปุ่มลบ row data
 * @param val data ใน row ที่จะลบ
 */
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
  rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
  updateData.value = true;
};

/**
 * ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
 */
const clickEditRow = () => {
  myForm.value.validate(false);
  updateData.value = true;
};

/**
 * ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
 * @param row ข้อมูล row ที่ดูประวัติการแก้ไข
 */
const clickHistory = async (row: RequestItemsHistoryObject) => {
  modalHistory.value = true;
  rowsHistory.value = rawHistory.value.filter(
    (f: RequestItemsHistoryObject) => f.id == row.id
  );
};

/**
 * ฟังก์ชันแปลง date เป็นภาษาไทย
 * @param value วันที่ type datetime ที่จะแปลงเป็นไทย
 */
const textDate = (value: Date) => {
  return dateText(value);
};

/**
 * validate component
 */
const validateData = async () => {
  checkValidate.value = true;
  await myForm.value.validate().then((result: boolean) => {
    if (result == false) {
      checkValidate.value = false;
    }
  });
};
</script>

<style>
/* สีของnoti */
.my-notif-class {
  background: rgba(33, 186, 69, 0.5) !important;
  color: #008f17 !important;
}
</style>
