<template>
  <div class="row">
    <div class="col-12">
      <div class="input-group mb-2">
        <vue-multiselect
          name="selectMotive"
          id="selectMotive"
          label="displayLabel"
          :custom-label="(value: Motive) => localizeString(value.label)"
          track-by="id"
          :open-direction="openDirection"
          :multiple="false"
          :searchable="true"
          :internalSearch="false"
          :placeholder="trans(CHILL_TICKET_TICKET_SET_MOTIVE_LABEL)"
          :options="options"
          :loading="isLoading"
          v-model="motive"
          class="form-control"
          @remove="(value: Motive) => $emit('remove', value)"
          @search-change="search"
          :disabled="disabled"
        >
          <template
            #option="{
              option,
            }: {
              option: Motive & {
                isChild?: boolean;
                isParent?: boolean;
                level?: number;
                breadcrumb: string[];
              };
            }"
          >
            <span
              :data-select="trans(MULTISELECT_SELECT_LABEL)"
              :data-selected="trans(MULTISELECT_SELECTED_LABEL)"
              :data-deselect="trans(MULTISELECT_DESELECT_LABEL)"
            >
              <span v-for="(crumb, idx) in option.breadcrumb" :key="idx">
                <template v-if="idx < option.breadcrumb.length - 1">
                  <i>{{ crumb }}</i> &gt;
                </template>
                <template v-else>
                  {{ crumb }}
                </template>
              </span>
            </span>
          </template>
        </vue-multiselect>
        <div class="input-group-append">
          <peloton-component
            :stored-objects="motive ? motive.storedObjects : null"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from "vue";
import VueMultiselect from "vue-multiselect";

// Types
import { Motive, MotiveWithParent } from "../../../../types";

// Translations
import {
  trans,
  CHILL_TICKET_TICKET_SET_MOTIVE_LABEL,
  MULTISELECT_SELECT_LABEL,
  MULTISELECT_DESELECT_LABEL,
  MULTISELECT_SELECTED_LABEL,
} from "translator";

// Component
import PelotonComponent from "../PelotonComponent.vue";

// Utils
import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
import { useStore } from "vuex";

const props = defineProps({
  modelValue: {
    type: Object as () => MotiveWithParent | Motive | null,
    default: null,
  },
  motives: {
    type: Array as () => Motive[],
    default: () => [],
  },
  openDirection: {
    type: String,
    default: "bottom",
  },
  allowParentSelection: {
    type: Boolean,
    default: false,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
});
const store = useStore();

const emit = defineEmits<{
  (e: "update:modelValue", value: Motive | null): void;
  (e: "remove", value: Motive): void;
}>();

const motive = computed<Motive | null>({
  get() {
    return store.getters.getMotiveById(props.modelValue?.id);
  },
  set(value: Motive | null) {
    emit("update:modelValue", value);
  },
});
type MotiveOptions = Motive & {
  isChild?: boolean;
  isParent?: boolean;
  level?: number;
  displayLabel: string;
  breadcrumb: string[];
};

const searchQuery = ref<string>("");
const isLoading = ref<boolean>(false);

const allMotiveOptions = computed<MotiveOptions[]>(() => {
  const result: MotiveOptions[] = [];

  const processMotiveRecursively = (
    motive: Motive,
    isChild = false,
    level = 0,
    parentBreadcrumb: string[] = [],
  ) => {
    const hasChildren = motive.children && motive.children.length > 0;
    const displayLabel = localizeString(motive.label);
    const breadcrumb = [...parentBreadcrumb, displayLabel];

    if (props.allowParentSelection || !hasChildren) {
      result.push({
        ...motive,
        isChild,
        isParent: hasChildren,
        level,
        breadcrumb,
        displayLabel,
      });
    }

    if (hasChildren) {
      motive.children.forEach((childMotive) => {
        processMotiveRecursively(childMotive, true, level + 1, breadcrumb);
      });
    }
  };

  props.motives.forEach((motive) => {
    processMotiveRecursively(motive);
  });

  return result;
});

const options = computed<MotiveOptions[]>(() => {
  if (!searchQuery.value.trim()) {
    return allMotiveOptions.value;
  }
  return allMotiveOptions.value.filter((m) =>
    m.breadcrumb.some((crumb) =>
      crumb.toLowerCase().includes(searchQuery.value.trim().toLowerCase()),
    ),
  );
});

function search(query: string) {
  isLoading.value = true;
  searchQuery.value = query;
  isLoading.value = false;
}
</script>

<style lang="scss" scoped>
.form-control {
  padding: 0 !important;
}
</style>
