<script setup lang="ts">
import { ref, onMounted, watch, onBeforeMount, nextTick } from "vue";
import { useQuasar } from "quasar";
import { OrgChart } from "bma-org-chart";
import "bma-org-chart/org-chart.css";

import http from "@/plugins/http";
import config from "@/app.config";

import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useStructStore } from "@/modules/02_organization/store/chart";
import avatar from "@/assets/avatar_user.jpg";
import chartData from "@/assets/orgChartData";
import {
  showLoadingSpinner,
  exportChartToPDF,
  exportChartToPNG,
} from "@/plugins/exportChart";

import type { DataOption } from "@/modules/02_organization/interface/index/Main";

const mixin = useCounterMixin();
const store = useOrganizational();
const storeOrg = useStructStore();
const { showLoader, hideLoader, messageError } = mixin;
const $q = useQuasar(); // show dialog

const dataSource = ref(chartData); // ข้อมูล Chart

const rootOrgID = ref(); // org id ของ root ตัวปัจจุบันที่เลือกอยู่
const dataSourceLock = ref(); // ข้อมูลตั้งต้นของ Chart ใช้ให้กดกลับไปที่ home
const chartRef = ref(); // อ้างอิงไปที่ตัว chart
const scrollContainer = ref<HTMLElement | null>(null);

const agencyId = ref<string>(""); // id ของหน่วยงานที่เลือก
const agencyData = ref<DataOption[]>([]); // ข้อมูลรายการหน่วยงาน
const agencyOp = ref<DataOption[]>([]); // ตัวเลือกหน่วยงาน

/** fetch ข้อมูล Chart โครงสร้าง*/
async function fetchOrgChart(agencyId: string = "root") {
  if (rootOrgID.value) {
    showLoader();
    let urlRequest = config.API.orgChart(rootOrgID.value) + `/${agencyId}`;
    await http
      .get(urlRequest)
      .then(async (response) => {
        if (response.data.result.length > 0) {
          const data = await response.data.result;
          const updatedData = await Promise.all(data.map(addAvatarToData));

          dataSource.value = await updatedData[0];
          storeOrg.dataSource = updatedData[0];

          if (dataSourceLock.value === undefined)
            dataSourceLock.value = dataSource.value;
        }
      })
      .catch((e) => {
        messageError($q, e);
      })
      .finally(() => {
        hideLoader();
      });
  }
}

/**
 * map ข้อมูล Chart
 * @param item  ข้อมูล Chart
 */
async function addAvatarToData(item: any) {
  // เพิ่ม avatar ให้กับ item
  const updatedItem = {
    ...item,
    // avatar: item.avatar ? await fetchProfile(item.avatar) : avatar,
    avatar: avatar,
    // ตรวจสอบว่า item มี children หรือไม่
    children: item.children
      ? await Promise.all(item.children.map(addAvatarToData))
      : [],
  };
  return updatedItem;
}

/**
 * fetch รูปโปรไฟล์ return ลิงก์ download ไฟล์
 * @param path ไฟล์รูป
 */
async function fetchProfile(path: string) {
  try {
    const res = await http.get(config.API.filefullPath(path));
    return res.data.downloadUrl; // คืนค่า URL ของ avatar
  } catch (err) {
    return avatar; // คืนค่า default avatar ถ้าเกิดข้อผิดพลาด
  }
}

/**
 * เมื่อมีการคลิกที่ Chart ให้อ่าน ID ของหน่วยงานที่ถูกคลิก แล้วดึงข้อมูล Chart ของหน่วยงานนั้นๆ จาก API
 * @param data
 */
async function refreshChart(data: any) {
  if (data.value !== undefined) rootOrgID.value = data.value;
  else rootOrgID.value = data;
  if (rootOrgID.value !== 0) await fetchOrgChart();
  if (data.value !== undefined) data.value = 0;
}

/** โหลด Chart รูป*/
async function savePNG() {
  // try {
  //   showLoader();
  //   await scrollToCenter();
  //   await chartRef.value.savePNG();
  // } catch {
  //   messageError($q);
  // } finally {
  //   hideLoader();
  // }
  showLoadingSpinner();
  setTimeout(async () => {
    scrollContainer.value && (await exportChartToPNG(scrollContainer.value));
  }, 500);
}

/** โหลด Chart PDF*/
async function savePDF() {
  // try {
  //   showLoader();
  //   await scrollToCenter();
  //   await chartRef.value.savePDF();
  // } catch {
  //   messageError($q);
  // } finally {
  //   hideLoader();
  // }
  showLoadingSpinner();
  setTimeout(async () => {
    scrollContainer.value && (await exportChartToPDF(scrollContainer.value));
  }, 500);
}

/** ฟังก์ชันเลื่อน scroll ไปที่กึ่งกลาง*/
async function scrollToCenter() {
  const container = scrollContainer.value;
  if (container) {
    container.scrollLeft = (container.scrollWidth - container.clientWidth) / 2;
  }
}

async function fetchAgencyData(id: string) {
  if (!id) return; // ถ้าไม่มี id ให้ return ออกไป

  agencyId.value = "";
  try {
    const data = await store.fetchDataTree(id);

    agencyData.value = data.data.map((item: any) => ({
      id: item.orgTreeId,
      name: item.orgName,
    }));
    agencyOp.value = agencyData.value;
  } catch (err) {
    messageError($q, err);
  }
}

function onSelectAgency(val: string) {
  const id = val || "root"; // ถ้าไม่มีการเลือกหน่วยงาน ให้ใช้ root
  fetchOrgChart(id);
}

/**
 * ฟังก์ชันต้นหาข้อมูลของ Option ขอสถานะ
 * @param val ค่าที่ต้องการฟิลเตอร์
 * @param update  อัพเดทค่า
 * @param refData ดาต้าที่ต้องการฟิลเตอร์
 */
function filterOption(val: string, update: Function) {
  update(() => {
    agencyOp.value = agencyData.value.filter(
      (v: DataOption) => v.name.indexOf(val) > -1
    );
  });
}

watch(
  [() => store.typeOrganizational, () => store.historyId],
  ([new1], [old1]) => {
    if (new1 === "old" && old1 !== "old") {
      store.historyId = "";
    }

    rootOrgID.value =
      store.typeOrganizational === "current"
        ? store.activeId
        : store.typeOrganizational === "draft"
        ? store.draftId
        : store.historyId;

    if (rootOrgID.value) {
      fetchAgencyData(rootOrgID.value);
      fetchOrgChart();
    }
  }
);

onMounted(async () => {
  rootOrgID.value =
    store.typeOrganizational === "current"
      ? store.activeId
      : store.typeOrganizational === "draft"
      ? store.draftId
      : store.historyId;

  await fetchOrgChart();
  await scrollToCenter();
  await fetchAgencyData(rootOrgID.value);
});

onBeforeMount(() => {
  storeOrg.dataSource = undefined;
});
</script>

<template>
  <!-- <div class="toptitle text-dark col-12 row items-center">แผนภูมิองค์กร</div> -->
  <div class="text-dark">
    <q-card class="col-12 q-mt-sm">
      <div class="q-pa-sm row">
        <q-btn flat round color="primary" @click="savePNG()" icon="mdi-image">
          <q-tooltip> ดาวน์โหลด PNG </q-tooltip>
        </q-btn>
        <q-btn
          flat
          round
          color="red-7"
          @click="savePDF()"
          icon="mdi-file-pdf-box"
        >
          <q-tooltip> ดาวน์โหลด PDF </q-tooltip>
        </q-btn>

        <q-space />
        <q-select
          v-model="agencyId"
          :label="`${'หน่วยงาน'}`"
          option-label="name"
          :options="agencyOp"
          option-value="id"
          dense
          emit-value
          map-options
          use-input
          hide-selected
          fill-input
          outlined
          clearable
          @clear="() => (agencyId = '')"
          @update:model-value="onSelectAgency"
          @filter="(inputValue:any,doneFn:Function) => filterOption(inputValue, doneFn) "
          style="width: 400px"
        >
          <template v-slot:no-option>
            <q-item>
              <q-item-section class="text-grey"> ไม่มีข้อมูล </q-item-section>
            </q-item>
          </template>
        </q-select>
      </div>
      <q-separator />
      <div
        ref="scrollContainer"
        style="
          overflow-x: auto;
          overflow-y: auto;
          height: 70vh;
          position: relative;
        "
        class="q-pt-md"
      >
        <OrgChart
          v-if="storeOrg.dataSource"
          style="height: 70vh"
          ref="chartRef"
          class="org"
          :dataSource="dataSource"
          @onElementClick="refreshChart"
        />
      </div>
    </q-card>
  </div>
</template>

<style>
.org .section-list {
  padding: 15px !important;
}

.org .section-list .column-content .header {
  font-size: 1rem;
  line-height: 1.2rem;
  font-weight: 500 !important;
}
.org .section-list .column-content .subheader {
  font-weight: 500 !important;
}

.org .section-list .column-content .caption {
  font-size: 0.9rem;
  line-height: 1.2rem;
  font-weight: 400 !important;
}

.org .element-container .column-content p {
  padding-top: 3px !important;
}

.org .element-container .column-side .side-button {
  background-size: 14px;
}
</style>
