<template>
  <UiPopoverMenu :to="to" :visible="visible">
    <BmsCard v-if="visible" class="tenantsMenu">
      <div class="tenantsMenu-search">
        <BmsInputText
          ref="searchRef"
          v-model="search"
          type="search"
          autocomplete="off"
          class="tenantsMenu-search-input"
          name="search"
          :placeholder="selectTenantPlaceholder"
          :clearable="true"
          @enterKey="onEnterKeyPress"
        >
          <template #icon-start>
            <Search />
          </template>
        </BmsInputText>
      </div>

      <div ref="tenantsListRef" class="tenantsMenu-tenants-list">
        <template v-if="splittedTenants.favorites.length">
          <UiTenantLabel
            :tenant="tenant"
            v-for="tenant in splittedTenants.favorites"
            :key="tenant.information"
            @changeTenant="changeTenant(tenant)"
            @removeFavorite="onRemoveTenantFromFavorites(tenant)"
          />

          <hr />
        </template>
        <UiTenantLabel
          v-for="tenant in splittedTenants.tenants"
          :tenant="tenant"
          :key="tenant.id"
          @click="changeTenant(tenant)"
        />
      </div>
    </BmsCard>
  </UiPopoverMenu>
</template>

<script setup lang="ts">
import { Search } from 'lucide-vue-next';
import UiPopoverMenu from '@/components/layout/UiPopoverMenu.vue';
import {
  type ComputedRef,
  ref,
  watch,
  computed,
  type Ref,
  nextTick,
} from 'vue';
import { Tenant } from '@/models';
import { BmsCard, BmsInputText, searchString } from '@/index';
import UiTenantLabel from './UiTenantLabel.vue';

const props = withDefaults(
  defineProps<{
    visible: boolean;
    to: HTMLElement | null;
    tenants: Tenant[];
    selectTenantPlaceholder?: string;
  }>(),
  {
    selectTenantPlaceholder: '',
  },
);

const emit = defineEmits<{
  changeTenant: [tenant: Tenant];
  removeFavoriteTenant: [tenant: Tenant];
}>();

const tenantsListRef = ref(null);
const searchRef: Ref<typeof BmsInputText | null> = ref(null);
const search = ref('');

const filteredTenants: ComputedRef<Tenant[]> = computed(() => {
  return props.tenants.filter(
    (tenant) =>
      searchString(tenant.label, search.value) ||
      searchString(tenant.information, search.value),
  );
});

const splittedTenants = computed(() => {
  return filteredTenants.value.reduce(
    (acc, val) => {
      val.isFavorite ? acc.favorites.push(val) : acc.tenants.push(val);

      return acc;
    },
    { favorites: [], tenants: [] } as {
      favorites: Tenant[];
      tenants: Tenant[];
    },
  );
});

const changeTenant = (tenant: Tenant) => {
  emit('changeTenant', tenant);
};

const onEnterKeyPress = () => {
  if (filteredTenants.value.length > 0) {
    changeTenant(filteredTenants.value[0]);
  }
};
const onRemoveTenantFromFavorites = (tenant: Tenant) => {
  emit('removeFavoriteTenant', tenant);
};

watch(
  () => props.visible,
  async () => {
    search.value = '';
    await nextTick();
    if (searchRef.value && props.visible) {
      searchRef.value.setFocus();
    }
  },
);
</script>
<style lang="scss" scoped>
.tenantsMenu {
  padding: 0;
  background-color: var(--bms-white);
  width: 100%;

  &-search {
    padding: 14px;
    border-bottom: 1px solid var(--bms-border-color);

    &-input {
      margin: 0;
    }
  }

  &-tenants {
    &-list {
      max-height: 200px;
      overflow-y: auto;
      padding-top: 0.5em;

      hr {
        display: block;
        appearance: none;
        color: inherit;
        border: 0;
        height: 1px;
        background: currentColor;
        opacity: 0.08;
        margin: 0.5em 0;
      }
    }
  }
}
</style>
