<script setup>
import SvgIcon from '@/components/SvgIcon.vue';
import { findLandByTradeCode, findTemInside, objIsTem } from '@/components/viewer/utils/aps-viewer';
import { getBounds } from '@/components/viewer/utils/geometry';

const props = defineProps({
  products: Array,
})

const productInput = ref('');
const isSubmitting = ref(false);

const productMatches = computed(() => {
  const val = productInput.value.trim().toUpperCase();
  if (!val) return;
  return props.products.filter(p => p.trade_code.includes(val));
});

function panToLand(trade_code) {
  const { viewer } = window;

  viewer.getObjectTree(async (instanceTree) => {
    const dbIdMap = instanceTree.nodeAccess.dbIdToIndex;
    const allDbIds = Object.keys(dbIdMap).map((id) => parseInt(id));

    viewer.model.getBulkProperties(allDbIds, {}, (results) => {
      const frags = viewer.model.getFragmentList();
      const tems = results.filter(objIsTem);
      const lands = results.filter(land => {
        const layerProp = land.properties.find(prop => prop.displayName === 'Layer');
        if (!layerProp) return false;
        const globalWidthProp = land.properties.find(prop => prop.displayName === 'Global width');
        return layerProp.displayValue === '1-bodim' && globalWidthProp.displayValue === 0;
      });

      const temsWithBounds = tems.map(tem => ({ ...tem, bounds: getBounds(tem.dbId, frags) }));
      const landsWithBounds = lands.map(land => ({ ...land, bounds: getBounds(land.dbId, frags) }));
      const temsInside = landsWithBounds.map(landWithBounds => findTemInside(landWithBounds, temsWithBounds));

      const [foundLand] = findLandByTradeCode(trade_code, landsWithBounds, temsInside);
      if (!foundLand) return;
      
      viewer.fitToView([foundLand.dbId]);
      isSubmitting.value = false;
    });
  });
}

function clickMatchBtn(product) {
  isSubmitting.value = true;
  panToLand(product.trade_code);
}

function submit() {
  isSubmitting.value = true;
  const trade_code = productInput.value.toUpperCase();  

  const foundProduct = props.products.find(p => {
    return p.trade_code === trade_code;
  });
  
  if (!foundProduct) { 
    isSubmitting.value = false; 
    return;
  }

  panToLand(trade_code);
}

const showMatches = ref(true);
const input = useTemplateRef('input');
const matches = useTemplateRef('matches');

function clickAwayListener(e) {
  if (input.value?.contains(e.target)
  || matches.value?.contains(e.target)
  ) {
    showMatches.value = true;
  } else {
    showMatches.value = false;
  }
}

onMounted(() => {
  document.addEventListener('click', clickAwayListener)
});

onUnmounted(() => {
  document.removeEventListener('click', clickAwayListener)
});
</script>
<template>
  <div class="has-background-white" style="position: sticky; top: 0">
    <form class="is-flex is-gap-1">
      <div class="field has-addons is-flex-grow-1">
        <p ref="input" class="control mb-0 is-flex-grow-1">
          <input
            v-model="productInput"
            class="input is-radiusless has-icons-right fs-13"
            type="text"
            placeholder="Tìm sản phẩm"
            style="
              box-sizing: border-box;
              border-inline-width: 0;
              box-shadow: none;
            "
          />
          <button 
            type="button"
            class="clearInputBtn"
            v-if="productInput"
            @click="productInput = ''"
            tabindex="-1"
          >
            <SvgIcon v-bind="{ name: 'close.svg', type: 'primary', size: 14 }" />
          </button>
        </p>
        <p class="control">
          <button
            :class="[
              'button is-small is-primary is-radiusless',
              isSubmitting && 'is-loading'
            ]"
            :disabled="!productInput"
            tabindex="-1"
            style="box-sizing: border-box; width: 38px; height: 100%"
            @click.prevent="submit"
            type="submit"
          >
            <span v-if="!isSubmitting" class="icon">
              <SvgIcon v-bind="{ name: 'search.svg', type: 'white', size: 18 }" />
            </span>
          </button>
        </p>
      </div>
    </form>
    <div
      v-if="showMatches"
      ref="matches"
      tabindex="-1"
      style="
        max-height: 100px;
        overflow-y: scroll;
        border-bottom-left-radius: 8px;
        border-bottom-right-radius: 8px;
        position: absolute;
        width: 100%;
        z-index: 10;
        box-shadow: 0 4px 4px 0 hsla(0, 0%, 0%, 0.1);
      "
    >
      <button
        v-for="product in productMatches"
        @click="clickMatchBtn(product)"
        class="button is-small is-fullwidth is-radiusless is-justify-content-start"
        style="
          box-sizing: border-box;
          border-inline-width: 0;
          border-bottom-width: 0;
        "
      >
        <p>{{ product.trade_code }}</p>
      </button>
    </div>
  </div>
</template>
<style scoped>
.control.is-loading::after, .select.is-loading::after, .button.is-loading::after {
  /* overrides spinner color */
  border: 3px solid white;
  border-right-color: transparent;
  border-top-color: transparent;
}

.button:focus-visible, .button.is-focused {
  border-color: transparent;
  box-shadow: none;
  /* copy styles from is-hovered */
  --bulma-button-background-l-delta: var(--bulma-button-hover-background-l-delta);
  --bulma-button-border-l-delta: var(--bulma-button-hover-border-l-delta);
}

.clearInputBtn {
  box-sizing: border-box;
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  border-radius: 9999px;
  padding: 4px;
  cursor: pointer;
  display: flex;
  background-color: hsla(0, 0%, 0%, 0.05);

  &:hover {
    background-color: hsla(0, 0%, 0%, 0.1)
  }
}
</style>