<script setup>
import Checkbox from "@/components/customUI/Checkbox.vue";
import { computed, ref, watch } from "vue";
import useBuildingStore from "@/stores/useBuildingStore";
import useSearchParam from "@/hooks/useSearchParam";
import { getHistorySideBar } from "@/apis/history";
import { useI18n } from "vue-i18n";

const { t } = useI18n();
const { searchParams, changeParams } = useSearchParam();
const storeBuild = useBuildingStore();
const selectedBuilding = ref([]);
const deviceData = ref([]);
const searchTerm = ref(""); //搜尋文字
const activeSearchTerm = ref("");

const getDeviceData = async (sub_system_tag, department_id) => {
  const deptArray = department_id ? department_id.map(Number) : [];
  const res = await getHistorySideBar({
    sub_system_tag: sub_system_tag,
    department_id: deptArray,
    elec_type_id: [],
    building_guid: storeBuild.selectedBuilding?.building_guid || null,
  });
  deviceData.value = res.data.map((building) => ({
    building_tag: building.building_tag,
    building_name: building.building_name,
    floors: building.floor_list.map((floor) => ({
      floor_tag: floor.device_floor_tag,
      floor_name: floor.floor_name,
      devices: floor.device_list.map((device) => ({
        ...device,
        key: device.device_number,
      })),
    })),
  }));

  selectedBuilding.value = res.data.map((d) => d.building_tag);
  changeSelected([res.data[0]?.floor_list[0]?.device_list[0]?.device_number]);
};

const sysIsExisted = (building_tag) => {
  return selectedBuilding.value.includes(building_tag);
};

const toggleSelectedBuilding = (building_tag) => {
  const isExisted = sysIsExisted(building_tag);
  if (isExisted) {
    selectedBuilding.value = deviceData.value.filter(
      (selected) => building_tag !== selected
    );
  } else {
    selectedBuilding.value = [...selectedBuilding.value, building_tag];
  }
};

watch(
  searchParams,
  (newVal, oldVal) => {
    if (
      newVal.sub_system_tag &&
      newVal.sub_system_tag != oldVal?.sub_system_tag
    ) {
      getDeviceData(newVal.sub_system_tag, searchParams.value.Dept);
    }
  },
  {
    immediate: true,
    deep: true,
  }
);

watch(
  searchParams,
  (newVal, oldVal) => {
    if (newVal.Dept && newVal.Dept?.length != oldVal?.Dept?.length) {
      getDeviceData(searchParams.value.sub_system_tag, newVal.Dept);
    }
  },
  {
    immediate: true,
  }
);

const selectedDeviceNumber = computed(() => {
  return typeof searchParams.value.Device_list === "string"
    ? [searchParams.value.Device_list]
    : searchParams.value.Device_list || [];
});

const isChecked = (device, checked) => {
  if (checked) {
    changeSelected([...selectedDeviceNumber.value, device]);
  } else {
    changeSelected(
      selectedDeviceNumber.value.filter(
        (device_number) => device_number !== device
      )
    );
  }
};

const checkedBuilding = computed(() => {
  let selected = [];
  deviceData.value.forEach(({ building_tag, floors }) => {
    let allDevices = [];
    floors.forEach((floor) => {
      allDevices = [...allDevices, ...floor.devices];
    });

    if (
      selectedDeviceNumber.value?.filter(
        (d) => d?.split("_")[1] === building_tag
      ).length === allDevices.length
    ) {
      selected.push(building_tag);
    }
  });
  return selected;
});

const buildingCheck = (building_tag) => {
  const building = deviceData.value.find(
    (d) => d.building_tag === building_tag
  );
  const allDevicesInBuilding = building.floors.flatMap((floor) =>
    floor.devices.map((device) => device.device_number)
  );

  if (checkedBuilding.value?.includes(building_tag)) {
    // 取消勾選該建築下的所有設備
    changeSelected(
      selectedDeviceNumber.value.filter(
        (device_number) => !allDevicesInBuilding.includes(device_number)
      )
    );
  } else {
    // 勾選該建築下的所有設備
    changeSelected([
      ...new Set([...selectedDeviceNumber.value, ...allDevicesInBuilding]),
    ]);
  }
};

const areAllDevicesCheckedInFloor = (devices) => {
  return devices.every((device) =>
    selectedDeviceNumber.value.includes(device.device_number)
  );
};

const toggleFloorDevices = (devices) => {
  const allChecked = areAllDevicesCheckedInFloor(devices);

  if (allChecked) {
    changeSelected(
      selectedDeviceNumber.value.filter(
        (device_number) =>
          !devices.some((device) => device.device_number === device_number)
      )
    );
  } else {
    const deviceNumbers = devices.map((device) => device.device_number);
    changeSelected([
      ...new Set([...selectedDeviceNumber.value, ...deviceNumbers]),
    ]);
  }
};

const changeSelected = (Device_list, renew = false) => {
  if (renew) {
    changeParams({
      ...searchParams.value,
      Points: [],
      Device_list,
    });
  } else {
    changeParams({
      ...searchParams.value,
      Device_list,
    });
  }
};

const filteredDeviceData = computed(() => {
  if (!activeSearchTerm.value) return deviceData.value;
  return deviceData.value
    .map((building) => ({
      ...building,
      floors: building.floors
        .map((floor) => ({
          ...floor,
          devices: floor.devices.filter((device) =>
            device.device_name.includes(activeSearchTerm.value)
          ),
        }))
        .filter((floor) => floor.devices.length > 0),
    }))
    .filter((building) => building.floors.length > 0);
});

const handleSearch = (e) => {
  e.preventDefault();
  activeSearchTerm.value = searchTerm.value;
};

const handleInput = (e) => {
  searchTerm.value = e.target.value;
};
</script>

<template>
  <div class="custom-border p-4">
    <label
      class="input input-bordered bg-transparent rounded-sm flex items-center px-2 border-info focus-within:border-info"
    >
      <font-awesome-icon
        :icon="['fas', 'search']"
        class="w-6 h-6 mr-2 text-info"
      />
      <input
        type="text"
        :value="searchTerm"
        @input="handleInput"
        :placeholder="t('button.enter_text')"
        class="text-white bg-transparent w-full"
        @keyup.enter="handleSearch"
      />
    </label>
    <ul class="menu text-lg">
      <template
        v-for="building in filteredDeviceData"
        :key="building.building_tag"
      >
        <li>
          <details :open="selectedBuilding.includes(building.building_tag)">
            <summary>
              <Checkbox
                :title="building.building_name"
                :checked="checkedBuilding.includes(building.building_tag)"
                @click="() => buildingCheck(building.building_tag)"
              />
            </summary>
            <ul>
              <template v-for="floor in building.floors" :key="floor.floor_tag">
                <li>
                  <details open>
                    <summary>
                      <Checkbox
                        :title="floor.floor_name"
                        :checked="areAllDevicesCheckedInFloor(floor.devices)"
                        @click="toggleFloorDevices(floor.devices)"
                      />
                    </summary>
                    <ul>
                      <template
                        v-for="device in floor.devices"
                        :key="device.device_number"
                      >
                        <li class="flex items-start">
                          <Checkbox
                            :title="device.device_name"
                            :checked="
                              selectedDeviceNumber.includes(
                                device.device_number
                              )
                            "
                            @click="
                              () =>
                                isChecked(
                                  device.device_number,
                                  !selectedDeviceNumber.includes(
                                    device.device_number
                                  )
                                )
                            "
                          />
                        </li>
                      </template>
                    </ul>
                  </details>
                </li>
              </template>
            </ul>
          </details>
        </li>
      </template>
    </ul>
  </div>
</template>

<style lang="scss" scoped></style>
