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

import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { setAuthen, authenticated, tokenParsed } from "@/plugins/auth";

import type { QTableProps } from "quasar";
import type {
  DataOption,
  Pagination,
} from "@/modules/02_users/interface/index/Main";
import type {
  FormUser,
  Roles,
} from "@/modules/02_users/interface/request/Main";
import type { Profile } from "@/modules/02_users/interface/response/Main";

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

/** use*/
const $q = useQuasar();
const { showLoader, hideLoader, dialogConfirm, messageError, success } =
  useCounterMixin();

/**  props*/
const modal = defineModel<boolean>("modal", { required: true });
const isStatusEdit = defineModel<boolean>("isStatusEdit", { required: true });
const userId = defineModel<string>("userId", { required: true });
const props = defineProps({
  fetchlist: {
    type: Function,
    required: true,
  },
  employeeClass: {
    type: String,
    required: true,
  },
});

// Table
const columns = ref<QTableProps["columns"]>([
  {
    name: "citizenId",
    align: "left",
    label: "เลขประจำตัวประชาชน",
    sortable: true,
    field: "citizenId",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
  },
  {
    name: "prefix",
    align: "left",
    label: "คำนำหน้าชื่อ",
    sortable: true,
    field: "prefix",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
  },
  {
    name: "firstName",
    align: "left",
    label: "ชื่อ",
    sortable: true,
    field: "firstName",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
  },
  {
    name: "lastName",
    align: "left",
    label: "นามสกุล",
    sortable: true,
    field: "lastName",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
  },
  {
    name: "position",
    align: "left",
    label: "ตำแหน่ง",
    sortable: true,
    field: "position",
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
  },
  {
    name: "positionTpye",
    align: "left",
    label: "ประเภทตำแหน่ง",
    sortable: true,
    field: "positionTpye",
    format: (val, row) => {
      return (
        `${row.positionTypeName ? row.positionTypeName : ""}` +
        (row.positionLevelName ? `(${row.positionLevelName})` : "")
      );
    },
    headerStyle: "font-size: 14px",
    style: "font-size: 14px",
  },
]);
const rows = ref<Profile[]>([]); //ข้อมูลรายชื่อ
const selected = ref<Profile[]>([]); // รายชื่อที่เลือก
const searchType = ref<string>("citizenId"); // ประเภทค้นหา
const keyword = ref<string>(""); //คำค้นหา
// ตัวเลือกประเภทค้นหา
const searchTypeOption = ref<DataOption[]>([
  { id: "citizenId", name: "เลขประจำตัวประชาชน" },
  { id: "firstname", name: "ชื่อ" },
  { id: "lastname", name: "นามสกุล" },
]);
const query = reactive({
  page: 1, // หน้า
  pageSize: 10, // จำนวนข้อมูลต่อหน้า
});
const total = ref<number>(0); // จำนวนรายการ
const maxPage = ref<number>(1); // จำนวนหน้า

const isPwd = ref<boolean>(true); // แสเดงรหัสผู้ใช้งาน
const isEmail = ref<boolean>(false);
const roles = ref<Roles[]>([]); // รายการบทบาท
// ฟอร์มเพิ่มผู้ใช้งาน
const formData = reactive<FormUser>({
  profileId: "", // id รายชื่อ
  username: "", // ชื่อผู้มใช้งาน
  password: "", // รหัสผู้ใช้งาน
  firstName: "", // ชื่อผู้มช้งาน
  lastName: "", // นามสกุล
  email: "", // เมล
  roles: [], // บทบาท
});
const roleOptions = ref([]); // รายการบทบาท;

/**
 * ฟังก์ชันดึงข้อมูลรายชื่อ
 */
function fetchListUser() {
  showLoader();
  const body = {
    fieldName: searchType.value ? searchType.value : "",
    keyword: keyword.value ? keyword.value : "",
  };
  http
    .post(
      config.API.orgProfileListKeycloak(
        props.employeeClass === "employee" ? "-employee" : ""
      ) + `?page=${query.page}&pageSize=${query.pageSize}`,
      body
    )
    .then(async (res) => {
      const data = await res.data.result;
      maxPage.value = Math.ceil(data.total / query.pageSize);
      total.value = data.total;
      rows.value = data.data;
    })
    .catch((err) => {
      messageError($q, err);
    })
    .finally(() => {
      hideLoader();
    });
}

/**
 * ฟังก์ชันดึงข้อมูลผู้ใช้งานตาม ID  ผู้ใช้งาน
 * @param id ผู้ใช้งาน
 *
 * และกำหนดฟอร์มเพิ่มผู้ใช้งานจาก respone
 */
function fetchUserDetail(id: string) {
  showLoader();
  http
    .get(config.API.managementUser + `/${id}`)
    .then((res) => {
      const data = res.data;
      formData.username = data.username;
      formData.firstName = data.firstName;
      formData.lastName = data.lastName;
      formData.email = data.email;
      roles.value = data.roles;
    })
    .catch((err) => {
      messageError($q, err);
    })
    .finally(() => {
      hideLoader();
    });
}

/**
 * ดึงข้อมูลรายการบทบาท
 *
 * บันทึกใน roleOptions
 */
function fetchlistRole() {
  http
    .get(config.API.managementRole)
    .then(async (res) => {
      const checkToken: any = await tokenParsed();
      const roleSuper = await checkToken.role.includes("SUPER_ADMIN");
      roleOptions.value = res.data.filter((e: Roles) =>
        roleSuper
          ? ["STAFF", "SUPER_ADMIN", "ADMIN", "USER"].includes(e.name)
          : ["STAFF", "USER"].includes(e.name)
      );
    })
    .catch((err) => {
      messageError($q, err);
    });
}

/**
 *  ฟังก์ชันยืนยันการบันทึกข้อมูลผู้ใช้งาน
 */
function onSubmit() {
  formData.roles = !isStatusEdit.value
    ? roles.value.map((e: { id: string }) => e.id)
    : undefined;
  formData.password = !isStatusEdit.value ? formData.password : undefined;

  dialogConfirm($q, () => {
    showLoader();
    const url = isStatusEdit.value
      ? config.API.managementUser + `/${userId.value}`
      : props.employeeClass === "employee"
      ? config.API.managementUser + `/emp`
      : config.API.managementUser;

    http[isStatusEdit.value ? "put" : "post"](url, {
      ...formData,
      email: isEmail.value ? formData.email : `${formData.email}@bangkok.go.th`,
    })
      .then(() => {
        success($q, "บันทึกข้อมูลสำเร็จ");
        props.fetchlist?.();
        closeDialog();
      })
      .catch((e) => {
        messageError($q, e);
      })
      .finally(() => {
        hideLoader();
      });
  });
}

/**
 * ฟังก์ชัน ปิด Dialog และกำหนด ตัวแปรไปเป็นค่า defult
 */
function closeDialog() {
  rows.value = [];
  modal.value = false;
  formData.profileId = "";
  formData.username = "";
  formData.password = "";
  formData.firstName = "";
  formData.lastName = "";
  formData.email = "";
  roles.value = [];
  searchType.value = "citizenId";
  keyword.value = "";
  selected.value = [];
  query.page = 1;
  query.pageSize = 10;
}

/**
 * function อัปเดท paging
 * @param initialPagination ข้อมูล pagination
 */
async function updatePagination(initialPagination: Pagination) {
  query.page = 1;
  query.pageSize = initialPagination.rowsPerPage;
}

/**
 * ดูการเปลี่ยนแปลงของจำนวนข้อมูลต่อหน้า
 *
 * ดึงข้อมูลรายชื่อตามจำนวนข้อมูลต่อหน้า
 */
watch(
  () => query.pageSize,
  () => {
    fetchListUser();
  }
);

/**
 * ดูการเปลี่ยนแปลงของ modal
 *
 * ุ isStatusEdit เป็น true  ดึงข้อมูลของผู้ใช้งาน
 */
watch(
  () => modal.value,
  () => {
    if (modal.value && isStatusEdit.value) {
      fetchUserDetail(userId.value);
    }
    modal.value && fetchlistRole();
    modal.value && fetchListUser();
  }
);

/**
 * ดูการเปลี่ยนแปลงของการเลือกรายชื่อ
 *
 * ุ กำหนด ฟอร์มเพิ่มข้อผู้ใช้งานตามราชชื่อที่เลือก
 */
watch(
  () => selected.value,
  () => {
    if (selected.value?.length !== 0) {
      const data = selected.value[0];
      formData.profileId = data.id;
      formData.firstName = data.firstName;
      formData.lastName = data.lastName;
      formData.email = data.email;
      formData.username = data.citizenId;
      isEmail.value = data.email ? true : false;
    }
  }
);
</script>

<template>
  <q-dialog v-model="modal" persistent>
    <q-card style="min-width: 80vw">
      <q-form greedy @submit.prevent @validation-success="onSubmit">
        <DialogHeader
          :tittle="isStatusEdit ? 'แก้ไขผู้ใช้งาน' : 'เพิ่มผู้ใช้งาน'"
          :close="closeDialog"
        />
        <q-separator />

        <q-card-section :horizontal="$q.screen.gt.md" style="padding: 0px">
          <div class="row col-12 q-gutter-sm">
            <!-- รายชื่อ -->
            <div class="q-pa-md col-md-8 col-xs-12">
              <div class="row q-col-gutter-sm">
                <div class="col-12 col-sm-6 col-md-3">
                  <q-select
                    label="ค้นหาจาก"
                    v-model="searchType"
                    :options="searchTypeOption"
                    outlined
                    emit-value
                    dense
                    emit-option
                    option-label="name"
                    option-value="id"
                    map-options
                  />
                </div>
                <div class="col-12 col-sm-6 col-md-9">
                  <q-input
                    ref="searchRef"
                    v-model="keyword"
                    outlined
                    clearable
                    hide-bottom-space
                    dense
                    label="คำค้น"
                    @keydown.enter.prevent="(query.page = 1), fetchListUser()"
                  >
                    <template v-slot:after>
                      <q-btn
                        color="primary"
                        icon="search"
                        label="ค้นหา"
                        class="full-width q-py-sm q-px-md"
                        @click="(query.page = 1), fetchListUser()"
                      >
                      </q-btn>
                    </template>
                  </q-input>
                </div>
              </div>

              <div class="col-12 q-pt-sm">
                <d-table
                  ref="table"
                  :columns="columns"
                  :rows="rows"
                  row-key="id"
                  flat
                  bordered
                  :paging="true"
                  dense
                  :rows-per-page-options="[10, 25, 50, 100]"
                  selection="single"
                  v-model:selected="selected"
                  @update:pagination="updatePagination"
                >
                  <template v-slot:header="props">
                    <q-tr :props="props">
                      <q-th auto-width></q-th>
                      <q-th
                        v-for="col in props.cols"
                        :key="col.name"
                        :props="props"
                      >
                        <span class="text-weight-medium">{{ col.label }}</span>
                      </q-th>
                    </q-tr>
                  </template>

                  <template v-slot:body="props">
                    <q-tr :props="props" class="cursor-pointer">
                      <q-td>
                        <q-checkbox
                          keep-color
                          color="primary"
                          dense
                          v-model="props.selected"
                        />
                      </q-td>
                      <q-td
                        v-for="col in props.cols"
                        :key="col.name"
                        :props="props"
                      >
                        <div>
                          {{ col.value ? col.value : "-" }}
                        </div>
                      </q-td>
                    </q-tr>
                  </template>

                  <template v-slot:pagination="scope">
                    ทั้งหมด {{ total }} รายการ
                    <q-pagination
                      v-model="query.page"
                      active-color="primary"
                      color="dark"
                      :max="Number(maxPage)"
                      size="sm"
                      boundary-links
                      direction-links
                      :max-pages="5"
                      @update:model-value="fetchListUser"
                    ></q-pagination>
                  </template>
                </d-table>
              </div>
            </div>

            <q-separator vertical />

            <!-- input -->
            <div class="q-pa-md col">
              <div class="row q-col-gutter-md">
                <div class="col-12">
                  <q-input
                    v-model="formData.username"
                    outlined
                    dense
                    :rules="[(val:string) => !!val || `${'กรุณากรอกชื่อผู้ใช้งาน'}`,]"
                    lazy-rules
                    hide-bottom-space
                    class="inputgreen"
                    label="ชื่อผู้ใช้งาน"
                    readonly
                  >
                  </q-input>
                </div>
                <div class="col-12" v-if="!isStatusEdit">
                  <q-input
                    v-model="formData.password"
                    outlined
                    dense
                    :type="isPwd ? 'password' : 'text'"
                    :rules="[
    (val:string) => !!val || 'กรุณากรอกรหัสผู้ใช้งาน',
    (val:string) => val.length >= 8 || 'รหัสผู้ใช้งานต้องมีอย่างน้อย 8 ตัวอักษร',
    (val:string) => {
      const regex = /^[A-Za-z0-9!@#$%&*]+$/;
      return regex.test(val) || 'รหัสผู้ใช้งานต้องมีเฉพาะภาษาอังกฤษ ตัวเลข และอักขระพิเศษ (! @ # $ % & *) เท่านั้น';
    }
  ]"
                    lazy-rules
                    label="รหัสผู้ใช้งาน"
                    hide-bottom-space
                    class="inputgreen"
                  >
                    <template v-slot:append>
                      <q-icon
                        :name="isPwd ? 'visibility_off' : 'visibility'"
                        class="cursor-pointer"
                        @click="isPwd = !isPwd"
                      />
                    </template>
                  </q-input>
                </div>
                <div class="col-12">
                  <q-input
                    v-model="formData.firstName"
                    outlined
                    dense
                    :rules="[(val:string) => !!val || `${'กรุณากรอกชื่อ'}`,]"
                    lazy-rules
                    hide-bottom-space
                    class="inputgreen"
                    label="ชื่อ"
                    readonly
                  >
                  </q-input>
                </div>
                <div class="col-12">
                  <q-input
                    v-model="formData.lastName"
                    outlined
                    dense
                    :rules="[(val:string) => !!val || `${'กรุณากรอกนามสกุล'}`,]"
                    lazy-rules
                    hide-bottom-space
                    class="inputgreen"
                    label="นามสกุล"
                    readonly
                  >
                  </q-input>
                </div>

                <div class="col-12">
                  <q-input
                    v-model="formData.email"
                    outlined
                    dense
                    :rules="[(val:string) => !!val || `${'กรุณากรอก อีเมล'}`,]"
                    lazy-rules
                    hide-bottom-space
                    class="inputgreen"
                    :suffix="isEmail ? '' : '@bangkok.go.th'"
                  >
                  </q-input>
                </div>
                <div class="col-12" v-if="!isStatusEdit">
                  <q-select
                    v-model="roles"
                    outlined
                    label="role"
                    dense
                    option-label="name"
                    option-value="id"
                    :options="roleOptions"
                    class="inputgreen"
                    map-options
                    hide-bottom-space
                    lazy-rules
                    use-chips
                    multiple
                    use-input
                    :rules="[(val:string) => !!val && val.length > 0|| `${'กรุณาเลือก Role'}`,]"
                  />
                </div>
              </div>
            </div>
          </div>
        </q-card-section>

        <q-separator />
        <q-card-actions align="right">
          <q-btn label="บันทึก" color="secondary" type="submit"
            ><q-tooltip>บันทึกข้อมูล</q-tooltip></q-btn
          >
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>

<style scoped></style>
