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

import { useCounterMixin } from "@/stores/mixin";
import { useDataStoreManage } from "@/modules/06_webservices/stores/manage";

import type { DataOption } from "@/modules/06_webservices/interface/index/Main";
import type {
  DataSystems,
  Propertys,
  DataAttributes,
} from "@/modules/06_webservices/interface/response/Main";

/** importComponents*/
import DialogHeader from "@/components/DialogHeader.vue";
import http from "@/plugins/http";
import config from "@/app.config";

const $q = useQuasar();
const { systemList, methodOptions } = toRefs(useDataStoreManage());
const {
  showLoader,
  hideLoader,
  dialogConfirm,
  success,
  dialogMessageNotify,
  messageError,
} = useCounterMixin();

const modal = defineModel<boolean>("modal", { required: true });
const isEdit = defineModel<boolean>("isEdit", { default: false });
const apiId = defineModel<string>("apiId", { default: "" });

const props = defineProps({
  fetchData: {
    type: Function,
    required: true,
  },
});

//ชื่อ title ของ dialog
const titleName = computed(() => {
  return isEdit.value ? "แก้ไข API" : "เพิ่ม API";
});

// รายการระบบที่ไม่ใช่ "all"
const options = computed<DataOption[]>(() => {
  return systemList.value.filter((e) => e.id !== "all") ?? [];
});

// กรองรายการระบบที่เป็น Main
const mainFields = computed(() => {
  return availableFields.value.filter((field) => field.isMain === true);
});

// ฟังก์ชันสำหรับนับจำนวนแอตทริบิวต์ที่ถูกเลือกในแต่ละหัวข้อ
const getSelectedCount = computed(() => {
  return (tbName: string) => {
    if (!selectedAttributes.value[tbName]) return 0;

    return Object.values(selectedAttributes.value[tbName]).filter(
      (selected) => selected === true
    ).length;
  };
});

const systemMain = ref<string>(""); // Default system
const systemOptions = ref<DataOption[]>(options.value); // Default to first option
const apiPath = ref<string>(""); // Path API
const splitterModel = ref<number>(15); // Initial splitter position
const tabs = ref<string>(""); // Tabs

// Form data
const formData = reactive({
  name: "",
  methodApi: "GET",
  system: "",
  isActive: false,
});

const availableFields = ref<DataSystems[]>([]); // เก็บข้อมูล fields ที่ดึงมา
const selectedAttributes = ref<Record<string, Record<string, boolean>>>({}); // เก็บข้อมูล attributes ที่เลือก
const dataAttributes = ref<DataAttributes[]>([]); // เก็บข้อมูล attributes ที่ดึงมา
const loading = ref<boolean>(false); // ใช้สำหรับแสดงสถานะการโหลดข้อมูล
const validationErrors = ref<string[]>([]); // เก็บข้อความ error สำหรับ validation

/**
 * ดึงข้อมูล fields ของ API ตามชื่อระบบ
 * @param system ชื่อระบบที่ต้องการดึงข้อมูล fields
 */
async function fetchData(system: string) {
  availableFields.value = [];
  loading.value = true;
  try {
    const res = await http.get(`${config.API.apiManage}${system}/fields`);
    availableFields.value = res.data.result || [];

    // Reset selected attributes เมื่อเปลี่ยน system
    selectedAttributes.value = {};

    // แยกแต่ละหัวข้อและ properties
    availableFields.value.forEach((field) => {
      // สร้าง group สำหรับแต่ละ field (หัวข้อ)
      selectedAttributes.value[field.tb] = {};

      if (field.propertys && field.propertys.length > 0) {
        field.propertys.forEach((prop: Propertys) => {
          // เก็บ properties ในแต่ละ group
          selectedAttributes.value[field.tb][prop.propertyName] = false;
        });
      }
    });

    tabs.value =
      availableFields.value.length > 0 ? availableFields.value[0].tb : "";
  } catch (error) {
    messageError($q, error);
    availableFields.value = [];
  } finally {
    loading.value = false;
  }
}

/**
 * ดึงข้อมูล API ตาม ID
 * @param id ID ของ API ที่ต้องการดึงข้อมูล
 */
async function fetchDataId(id: string) {
  showLoader();
  try {
    const res = await http.get(`${config.API.apiManage}${id}`);
    const data = res.data.result;
    systemMain.value = data.system;
    formData.name = data.name;
    formData.methodApi = data.methodApi;
    formData.system = data.system;
    formData.isActive = data.isActive;
    apiPath.value = data.pathApi;
    dataAttributes.value = data.apiAttributes || [];

    // ดึง fields และ attributes ที่เกี่ยวข้อง
    await fetchData(data.system);

    // กำหนดค่า selectedAttributes ตามข้อมูลที่ดึงมา
    updateSelectedAttributes(data.apiAttributes);
  } catch (error) {
    messageError($q, error);
  } finally {
    hideLoader();
  }
}

/**
 * ฟังก์ชันเมื่อเลือกระบบจาก select
 * @param value ชื่อระบบที่ถูกเลือก
 */
async function onSelectSystem(value: string) {
  await fetchData(value);
  if (systemMain.value === value && dataAttributes.value?.length > 0) {
    updateSelectedAttributes(dataAttributes.value);
  }
}

/** ฟังก์ชันตรวจสอบ validation */
function validateSelection(): boolean {
  validationErrors.value = [];

  // ตรวจสอบหัวข้อที่เป็น isMain: true
  mainFields.value.forEach((field) => {
    const selectedPropsCount = Object.keys(
      selectedAttributes.value[field.tb] || {}
    ).filter(
      (propKey) => selectedAttributes.value[field.tb][propKey] === true
    ).length;

    if (selectedPropsCount === 0) {
      validationErrors.value.push(
        `กรุณาเลือกแอตทริบิวต์ในส่วนของ"${field.description}" อย่างน้อย 1 รายการ`
      );
    }
  });

  return validationErrors.value.length === 0;
}

/** ฟังก์ชันบันทึกข้อมูล */
function onSubmit() {
  if (!validateSelection()) {
    validationErrors.value.forEach((error) => {
      dialogMessageNotify($q, error);
    });
    return;
  }

  dialogConfirm($q, async () => {
    showLoader();
    // สร้าง apiAttributes array
    const apiAttributes: Array<{
      tbName: string;
      propertyKey: string[];
    }> = [];

    // วนลูปผ่าน selectedAttributes เพื่อสร้าง apiAttributes
    Object.keys(selectedAttributes.value).forEach((fieldKey) => {
      const selectedProps: string[] = [];

      // เก็บเฉพาะ property ที่เลือก (true)
      Object.keys(selectedAttributes.value[fieldKey]).forEach((propKey) => {
        if (selectedAttributes.value[fieldKey][propKey]) {
          selectedProps.push(propKey);
        }
      });

      // ถ้ามี property ที่เลือก ให้เพิ่มเข้า apiAttributes
      if (selectedProps.length > 0) {
        apiAttributes.push({
          tbName: fieldKey,
          propertyKey: selectedProps,
        });
      }
    });

    // สร้างข้อมูลสำหรับส่งไป API
    const payload = {
      ...formData,
      apiAttributes: apiAttributes,
    };

    const method = isEdit.value ? http.put : http.post;
    const pathAPI = isEdit.value
      ? `${config.API.apiManage}${apiId.value}`
      : config.API.apiManage;
    try {
      await method(pathAPI, payload);
      await props.fetchData(); // เรียกใช้ฟังก์ชัน fetchData ที่ส่งมาจาก parent component
      success($q, "บันทึกข้อมูลสำเร็จ");
      onCloseDialog();
    } catch (error) {
      messageError($q, error);
      return;
    } finally {
      hideLoader();
    }
  });
}

/**
 * ฟังก์ชันอัพเดต selectedAttributes ตามข้อมูลที่ดึงมา
 * @param data ข้อมูลที่ต้องการอัพเดต selectedAttributes
 */
function updateSelectedAttributes(
  data: Array<{ tbName: string; propertyKey: string }>
) {
  if (!data?.length) return;
  data.forEach(({ tbName, propertyKey }) => {
    if (selectedAttributes.value[tbName]?.[propertyKey] !== undefined) {
      selectedAttributes.value[tbName][propertyKey] = true;
    }
  });
}

/**
 * function ค้นหาคำใน select
 * @param val คำค้นหา
 * @param update function
 */
function filterSelector(val: string, update: Function) {
  update(() => {
    const newVal = val.toLowerCase();
    systemOptions.value = options.value.filter(
      (v: DataOption) => v.name.toLowerCase().indexOf(newVal) > -1
    );
  });
}

/** ฟังก์ชันปิด dialog และรีเซ็ตข้อมูล */
function onCloseDialog() {
  modal.value = false;
  formData.name = "";
  formData.methodApi = "GET";
  formData.system = "";
  formData.isActive = false;
  apiPath.value = "";
  availableFields.value = [];
  selectedAttributes.value = {};
  validationErrors.value = [];
  dataAttributes.value = [];
  systemMain.value = "";
}

watch(modal, (newVal) => {
  if (newVal && isEdit.value) {
    systemOptions.value = options.value; // รีเซ็ตตัวเลือกเมื่อเปิด dialog
    fetchDataId(apiId.value);
  }
});
</script>

<template>
  <q-dialog v-model="modal" full-height>
    <q-card style="min-width: 90%">
      <q-form
        class="column full-height"
        greedy
        @submit.prevent
        @validation-success="onSubmit"
      >
        <DialogHeader :tittle="titleName" :close="onCloseDialog" />

        <q-separator />
        <q-card-section class="col q-pt-none scroll">
          <div class="q-pa-md">
            <div class="row q-col-gutter-md q-mb-lg">
              <div class="col-12 col-md-6">
                <q-input
                  v-model="formData.name"
                  label="API Name"
                  outlined
                  dense
                  hide-bottom-space
                  lazy-rules
                  :rules="[(val:string) => !!val || 'กรุณากรอก API Name']"
                />
              </div>
              <div class="col-12 col-md-6">
                <q-checkbox
                  v-model="formData.isActive"
                  color="primary"
                  :label="formData.isActive ? 'Active' : 'Inactive'"
                />
              </div>
              <div class="col-12 col-md-1">
                <q-select
                  v-model="formData.methodApi"
                  label="Method"
                  :options="methodOptions"
                  outlined
                  dense
                  hide-bottom-space
                  disable
                />
              </div>
              <div class="col-12 col-md-5">
                <q-input
                  v-model="apiPath"
                  outlined
                  dense
                  hide-bottom-space
                  placeholder="Auto generate"
                  disable
                />
              </div>
            </div>

            <q-card bordered class="row col-12 text-dark">
              <div class="bg-grey-1 q-pa-sm col-12 row items-center">
                <div class="q-pl-sm text-weight-bold text-subtitle2">
                  เลือกระบบ
                </div>
              </div>
              <div class="col-12"><q-separator /></div>
              <div class="row col-12 q-pa-md">
                <div class="col-12 row q-col-gutter-md">
                  <div class="col-12 col-md-4">
                    <q-select
                      dense
                      hide-bottom-space
                      outlined
                      option-label="name"
                      option-value="id"
                      emit-value
                      map-options
                      v-model="formData.system"
                      :options="systemOptions"
                      use-input
                      hide-selected
                      fill-input
                      lazy-rules
                      :rules="[(val:string) => !!val || 'กรุณาเลือกระบบข้อมูล']"
                      @update:model-value="onSelectSystem"
                      @filter="(inputValue: string,doneFn: Function) => filterSelector(inputValue, doneFn )"
                    >
                      <template v-slot:no-option>
                        <q-item>
                          <q-item-section class="text-grey">
                            ไม่มีข้อมูล
                          </q-item-section>
                        </q-item>
                      </template>
                    </q-select>
                  </div>

                  <div v-if="loading" class="col-12 text-center">
                    <q-spinner-dots
                      color="primary"
                      size="30px"
                      class="q-mt-md"
                    />
                  </div>

                  <q-splitter
                    v-model="splitterModel"
                    style="height: 55vh"
                    v-else-if="
                      !loading &&
                      formData.system !== '' &&
                      availableFields.length > 0
                    "
                  >
                    <template v-slot:before>
                      <div>
                        <q-tabs
                          v-model="tabs"
                          vertical
                          active-color="primary"
                          indicator-color="transparent"
                          dense
                        >
                          <q-tab
                            v-for="items in availableFields"
                            :key="items.tb"
                            :name="items.tb"
                            :label="
                              items.description +
                              ' (' +
                              getSelectedCount(items.tb) +
                              ')'
                            "
                            style="
                              justify-content: flex-start;
                              text-align: left;
                            "
                          />
                        </q-tabs>
                      </div>
                    </template>

                    <template v-slot:after>
                      <div class="q-pa-none">
                        <q-tab-panels
                          v-model="tabs"
                          animated
                          swipeable
                          vertical
                          transition-prev="jump-up"
                          transition-next="jump-up"
                        >
                          <q-tab-panel
                            v-for="value in availableFields"
                            :key="value.tb"
                            :name="value.tb"
                            class="q-pt-none"
                          >
                            <div
                              v-if="
                                formData.system !== '' &&
                                value.propertys &&
                                value.propertys.length > 0
                              "
                            >
                              <div class="row q-col-gutter-sm">
                                <!-- Loop through properties of this field -->
                                <div
                                  v-for="property in value.propertys"
                                  :key="property.propertyName"
                                  class="col-xs-12 col-sm-6 col-md-4 col-lg-3"
                                >
                                  <!-- Property Card -->
                                  <q-card flat bordered>
                                    <q-card-section>
                                      <!-- Property Name Header -->
                                      <div class="text-subtitle2 text-primary">
                                        {{ property.propertyName }}
                                      </div>

                                      <!-- Checkbox with details -->
                                      <q-item
                                        tag="label"
                                        v-ripple
                                        class="q-pa-none"
                                      >
                                        <q-item-section avatar>
                                          <q-checkbox
                                            v-model="
                                              selectedAttributes[value.tb][
                                                property.propertyName
                                              ]
                                            "
                                            color="primary"
                                          />
                                        </q-item-section>
                                        <q-item-section>
                                          <q-item-label class="text-body2">
                                            {{
                                              property.comment ||
                                              property.propertyName
                                            }}
                                          </q-item-label>
                                          <q-item-label
                                            caption
                                            class="text-grey-6"
                                          >
                                            Type: {{ property.type }}
                                          </q-item-label>
                                        </q-item-section>
                                      </q-item>
                                    </q-card-section>
                                  </q-card>
                                </div>
                              </div>
                            </div>

                            <!-- Empty state for this tab -->
                            <div
                              v-else-if="
                                !value.propertys || value.propertys.length === 0
                              "
                              class="text-center q-pa-lg text-grey-6"
                            >
                              <q-icon name="info_outline" size="48px" />
                              <div class="q-mt-md">
                                ไม่มี properties สำหรับหมวดนี้
                              </div>
                            </div>
                          </q-tab-panel>
                        </q-tab-panels>
                      </div>
                    </template>
                  </q-splitter>
                </div>
              </div>
            </q-card>

            <!-- System Selection -->
            <!-- <div class="row q-mb-lg">
              <div class="col-12 col-md-4">
                <div class="text-subtitle2 q-mb-sm">เลือกระบบ</div>
                <q-select
                  dense
                  hide-bottom-space
                  outlined
                  option-label="name"
                  option-value="id"
                  emit-value
                  map-options
                  v-model="formData.system"
                  :options="systemOptions"
                  use-input
                  hide-selected
                  fill-input
                  lazy-rules
                  :rules="[(val:string) => !!val || 'กรุณาเลือกระบบข้อมูล']"
                  @update:model-value="onSelectSystem"
                  @filter="(inputValue: string,doneFn: Function) => filterSelector(inputValue, doneFn )"
                >
                  <template v-slot:no-option>
                    <q-item>
                      <q-item-section class="text-grey">
                        ไม่มีข้อมูล
                      </q-item-section>
                    </q-item>
                  </template>
                </q-select>
              </div>
            </div> -->
          </div>
        </q-card-section>

        <q-separator />
        <q-card-actions align="right">
          <q-btn unelevated label="บันทึก" color="public" type="submit" />
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>

<style scoped>
.scroll {
  overflow-y: auto;
}
</style>
