<template>
  <PageHead with-actions>
    <template #actions>
      <RouterLink
        class="px-2 py-2"
        :to="{
          name: 'planner',
          query: { buildingId: building?.id, floorId: floor?.id },
        }"
        >Edit floor plan</RouterLink
      >
    </template>

    <template #default>
      <div class="flex flex-col">
        <h1 class="text-2xl font-bold">{{ floor?.displayName }}</h1>
        <span class="text-sm font-light text-gray-800 line-clamp-1"
          >Floor {{ floor?.number }} in {{ building?.displayName }}</span
        >
      </div>
    </template>
  </PageHead>

  <button
    @click="showMap = !showMap"
    :class="[
      showMap ? 'bg-gray-100' : 'rounded-md ring-1 ring-black ring-opacity-5',
      'ml-auto flex items-center space-x-2 rounded-tl-lg rounded-tr-lg px-2 py-2 shadow-md',
    ]"
  >
    <span class="sr-only">{ showMap ? 'Hide' : 'Show' }}</span> Floor plan
    <ChevronUpIcon v-if="showMap" class="h-4 w-4" />
    <ChevronDownIcon v-else class="h-4 w-4" />
  </button>

  <Transition
    name="menu-transition"
    enter-active-class="transition-height ease-out duration-200"
    enter-from-class="h-0"
    enter-to-class="h-[70vh]"
    leave-active-class="transition-height ease-in duration-150"
    leave-from-class="h-[70vh]"
    leave-to-class="h-0"
  >
    <div v-if="showMap" class="z-10 overflow-hidden bg-gray-100 shadow-md">
      <HousePlanner
        v-if="floorDocument"
        :key="`fdoc${floorDocument.id}`"
        ref="canvas"
        class="h-[70vh]"
        :editable="false"
        :grid="false"
        transparent
        headless
        :floor-document="floorDocument"
        @click="clickOnRoom(undefined, $event)"
      >
        <RoomPolygon
          v-for="room of rooms"
          :room="room"
          :highlighted="selectedRoom?.id"
          @clicked-in="(ev) => clickOnRoom(room, ev)"
        >
          <template v-if="selectedRoom?.id === room.id">
            <StorageBubble
              :storage="storage"
              v-for="storage of storages"
              :class="{ 'z-20': storage.id === hoveredBubble }"
              @mouseenter="() => (hoveredBubble = storage.id)"
              @mouseleave="() => (hoveredBubble = undefined)"
            >
              <span class="text-md font-bold">{{ storage.displayName }}</span>
              <span class="text-sm">Stored items: {{ storage.itemCount }}</span>
            </StorageBubble>
          </template>
        </RoomPolygon>
      </HousePlanner>
    </div>
  </Transition>

  <div class="grid grid-cols-3">
    <div class="flex flex-col">
      <button
        v-for="room of rooms"
        @click="selectRoomFromList(room)"
        :class="[
          selectedRoom?.id === room.id
            ? 'bg-blue-100 hover:bg-blue-200'
            : 'hover:bg-blue-100',
          'flex items-center justify-between border-b-2 border-gray-100 py-2 px-2',
        ]"
      >
        {{ room.displayName }} <ChevronRightIcon class="h-4 w-4" />
      </button>
    </div>

    <div class="flex flex-col" v-if="selectedRoom?.id">
      <button
        v-for="storage of storages"
        :class="[
          'hover:bg-blue-100',
          'flex items-center justify-between border-b-2 border-gray-100 py-2 px-2',
        ]"
      >
        {{ storage.displayName }} ({{ storage.itemCount }})
        <ChevronRightIcon class="h-4 w-4" />
      </button>
    </div>
  </div>
</template>
<script setup lang="ts">
import {
  ChevronDownIcon,
  ChevronRightIcon,
  ChevronUpIcon,
} from '@heroicons/vue/24/outline';
import { storeToRefs } from 'pinia';
import PageHead from '../../../components/PageHead.vue';
import { useRoute } from 'vue-router';
import { useBuildingStore } from '../../../store/building.store';
import { computed, ref } from '@vue/reactivity';
import HousePlanner from '../../../components/house-planner/HousePlanner.vue';
import { boundingBox } from '../../../modules/house-planner/utils';
import { Vec2 } from '../../../modules/house-planner/interfaces';
import { watch } from 'vue';
import { RoomLayoutObject } from '../../../interfaces/room.interfaces';
import jfetch from '../../../utils/jfetch';
import { BACKEND_URL } from '../../../constants';
import { useAccessToken } from '../../../composables/useAccessToken';
import { StorageListItem } from '../../../interfaces/storage.interfaces';
import StorageBubble from './StorageBubble.vue';
import RoomPolygon from './RoomPolygon.vue';
import { useLocalStorage } from '@vueuse/core';

const route = useRoute();
const buildingStore = useBuildingStore();
const { building } = storeToRefs(buildingStore);
const { authHeader } = useAccessToken();
const canvas = ref<InstanceType<typeof HousePlanner>>();
const storages = ref<StorageListItem[]>([]);
const selectedRoom = ref<RoomLayoutObject>();
const showMap = useLocalStorage('showRoomMap', true, { writeDefaults: false });
const hoveredBubble = ref<number>();
const selectedStorage = ref<number>();

const floor = computed(() =>
  building.value?.floors.find(
    (floor) => floor.number === Number(route.params.number)
  )
);

const floorDocument = computed(
  () => floor.value?.plan && JSON.parse(floor.value.plan)
);

const roomCoordinate = (ev: MouseEvent) => {
  const rect = (ev.target as HTMLElement).getBoundingClientRect();
  const [x, y] = [ev.clientX - rect.left, ev.clientY - rect.top];
  console.log(x, y);
};

const clickOnRoom = (room: RoomLayoutObject | undefined, ev: MouseEvent) => {
  canvas.value?.setViewRectangle(room?.boundingBox);
  selectedStorage.value = undefined;
  if (room && (!selectedRoom.value || room.id !== selectedRoom.value?.id)) {
    getRoomStorages(room);
  } else if (room?.id == selectedRoom.value?.id) {
    roomCoordinate(ev);
  } else {
    storages.value = [];
  }
  selectedRoom.value = room;
};

const selectRoomFromList = (room: RoomLayoutObject) => {
  canvas.value?.setViewRectangle(room?.boundingBox);
  selectedStorage.value = undefined;
  getRoomStorages(room);
  selectedRoom.value = room;
};

const rooms = computed<RoomLayoutObject[]>(
  () =>
    (floor.value &&
      floor.value.rooms
        .filter((room) => room.plan?.includes('polygon'))
        .map((room) => {
          const { polygon } = JSON.parse(room.plan);
          const aabb = boundingBox(polygon, [
            [Infinity, Infinity],
            [0, 0],
          ]);
          return {
            ...room,
            plan: polygon as Vec2[],
            boundingBox: aabb,
            storages: [],
          } as RoomLayoutObject;
        })) ||
    []
);

const getRoomStorages = async (room: RoomLayoutObject) => {
  storages.value = [];
  try {
    const { data: storageList } = await jfetch(
      `${BACKEND_URL}/storage/room/${room.id}?includeWithSets=false`,
      {
        headers: authHeader.value,
      }
    );
    const { data: setList } = await jfetch(
      `${BACKEND_URL}/storage/set/room/${room.id}`,
      {
        headers: authHeader.value,
      }
    );
    storages.value = [...storageList, ...setList];
  } catch (e) {
    console.error(e);
  }
};
</script>
