<template>
  <a
    class="btn"
    :class="getClassButton"
    :title="buttonTitle"
    @click="openModalChoose"
  >
    <span v-if="displayTextButton">{{ buttonTitle }}</span>
  </a>

  <person-choose-modal
    v-if="showModalChoose"
    ref="personChooseModal"
    :modal-title="modalTitle"
    :options="options"
    :selected="selected"
    :modal-dialog-class="'modal-dialog-scrollable modal-xl'"
    :allow-create="props.allowCreate"
    @close="closeModalChoose"
    @onPickEntities="onPickEntities"
    @onAskForCreate="onAskForCreate"
    @triggerAddContact="triggerAddContact"
    @updateSelected="updateSelected"
    @cleanSelected="emptySelected"
  />

  <CreateModal
    v-if="
      creatableEntityTypes.length > 0 &&
      showModalCreate &&
      null == thirdPartyParentAddContact
    "
    action="create"
    :allowed-types="creatableEntityTypes"
    :query="query"
    :parent="null"
    modalTitle="test"
    @close="closeModalCreate"
    @onPersonCreated="onPersonCreated"
    @onThirdPartyCreated="onThirdPartyCreated"
  ></CreateModal>

  <CreateModal
    v-if="showModalCreate && thirdPartyParentAddContact !== null"
    :allowed-types="['thirdparty']"
    action="addContact"
    modalTitle="test"
    :parent="thirdPartyParentAddContact"
    :query="''"
    @close="closeModalCreate"
    @onPersonCreated="onPersonCreated"
    @onThirdPartyCreated="onThirdPartyCreated"
  ></CreateModal>
</template>

<script setup lang="ts">
import { ref, computed, nextTick, useTemplateRef } from "vue";
import PersonChooseModal from "./AddPersons/PersonChooseModal.vue";
import type {
  Suggestion,
  SearchOptions,
  CreatableEntityType,
  EntityType,
  Person,
} from "ChillPersonAssets/types";
import { marked } from "marked";
import options = marked.options;
import CreateModal from "ChillMainAssets/vuejs/OnTheFly/components/CreateModal.vue";
import {
  Thirdparty,
  ThirdpartyCompany,
} from "../../../../../ChillThirdPartyBundle/Resources/public/types";

interface AddPersonsConfig {
  suggested?: Suggestion[];
  buttonTitle: string;
  modalTitle: string;
  options: SearchOptions;
  allowCreate?: boolean;
  types?: EntityType[] | undefined;
}

const props = withDefaults(defineProps<AddPersonsConfig>(), {
  suggested: () => [],
  allowCreate: () => true,
  types: () => ["person"],
});

const emit =
  defineEmits<
    (e: "addNewPersons", payload: { selected: Suggestion[] }) => void
  >();

type PersonChooseModalType = InstanceType<typeof PersonChooseModal>;
const personChooseModal =
  useTemplateRef<PersonChooseModalType>("personChooseModal");

/**
 * Flag to show/hide the modal "choose".
 */
const showModalChoose = ref(false);

/**
 * Flag to show/hide the modal "create".
 */
const showModalCreate = ref(false);

/**
 * Store the previous search query, stored while going from "search" state to "create"
 */
const query = ref("");

/**
 * Temporarily store the thirdparty company when calling "addContact"
 */
const thirdPartyParentAddContact = ref<ThirdpartyCompany | null>(null);

/**
 * Contains the selected elements.
 *
 * If the property option.uniq is true, this will contains only one element.
 *
 * Suggestion must be added/removed using the @link{addSuggestionToSelected} and @link{removeSuggestionFromSelected}
 * methods.
 */
const selected = ref<Map<string, Suggestion>>(new Map());

const getClassButton = computed(() => {
  const size = props.options?.button?.size ?? "";
  const type = props.options?.button?.type ?? "btn-create";
  return size ? `${size} ${type}` : type;
});

const displayTextButton = computed(() =>
  props.options?.button?.display !== undefined
    ? props.options.button.display
    : true,
);

const creatableEntityTypes = computed<CreatableEntityType[]>(() => {
  if (typeof props.options.type !== "undefined") {
    return props.options.type.filter(
      (e: EntityType) => e === "thirdparty" || e === "person",
    );
  }
  return props.types.filter(
    (e: EntityType) => e === "thirdparty" || e === "person",
  );
});

function onAskForCreate(payload: { query: string }): void {
  query.value = payload.query;
  closeModalChoose();
  showModalCreate.value = true;
}

function openModalChoose(): void {
  showModalChoose.value = true;
}

function closeModalChoose(): void {
  showModalChoose.value = false;
}

function closeModalCreate(): void {
  if (null !== thirdPartyParentAddContact.value) {
    thirdPartyParentAddContact.value = null;
  }
  showModalCreate.value = false;
}

/**
 * Called by PersonSuggestion's updateSelection event, when an element is checked/unchecked
 */
function updateSelected(payload: {
  suggestion: Suggestion;
  isSelected: boolean;
}): void {
  if (payload.isSelected) {
    addSuggestionToSelected(payload.suggestion);
  } else {
    removeSuggestionFromSelected(payload.suggestion);
  }
}

function addSuggestionToSelected(suggestion: Suggestion): void {
  if (props.options.uniq) {
    selected.value.clear();
  }
  selected.value.set(suggestion.key, suggestion);
}

function removeSuggestionFromSelected(suggestion: Suggestion): void {
  selected.value.delete(suggestion.key);
}

function emptySelected(): void {
  selected.value = new Map();
}

function onPickEntities(): void {
  const alls = Array.from(selected.value.values());
  emit("addNewPersons", { selected: alls });
  closeModalChoose();
}

function triggerAddContact({ parent }: { parent: ThirdpartyCompany }): void {
  closeModalChoose();
  openModalChoose();
  thirdPartyParentAddContact.value = parent;
  showModalCreate.value = true;
}

function onPersonCreated(payload: { person: Person }): void {
  showModalCreate.value = false;
  const suggestion = {
    result: payload.person,
    relevance: 999999,
    key: "person",
  };
  addSuggestionToSelected(suggestion);
  if (props.options.uniq) {
    emit("addNewPersons", { selected: [suggestion] });
  } else {
    openModalChoose();
  }
}

function onThirdPartyCreated(payload: { thirdParty: Thirdparty }): void {
  showModalCreate.value = false;
  const suggestion = {
    result: payload.thirdParty,
    relevance: 999999,
    key: "thirdparty",
  };
  addSuggestionToSelected(suggestion);
  if (props.options.uniq) {
    emit("addNewPersons", { selected: [suggestion] });
  } else {
    openModalChoose();
  }
}

function resetSearch(): void {
  selected.value = new Map();
  personChooseModal.value?.resetSearch();
}

defineExpose({ resetSearch });
</script>

<style lang="scss" scoped>
/* Button styles can remain here if needed */
</style>
