<template>
  <a v-if="isDisplayBadge" @click="openModal">
    <span class="chill-entity" :class="badgeType">
      {{ buttonText }}<span v-if="isDead"> (‡)</span>
    </span>
  </a>
  <a
    v-else
    class="btn btn-sm"
    target="_blank"
    :class="classAction"
    :title="titleAction"
    @click="openModal"
  >
    {{ buttonText }}<span v-if="isDead"> (‡)</span>
  </a>

  <teleport to="body">
    <modal
      v-if="modal.showModal"
      :modal-dialog-class="modal.modalDialogClass"
      @close="modal.showModal = false"
    >
      <template #header>
        <h3 v-if="parent" class="modal-title">
          {{ titleModal }}
        </h3>
        <h3 v-else class="modal-title">
          {{ titleModal }}
        </h3>
      </template>

      <template #body>
        <!-- person / show -->
        <template v-if="type === 'person' && action === 'show'">
          <on-the-fly-person
            :id="id"
            :type="type"
            :action="action"
            ref="castPerson"
          />
          <div v-if="hasResourceComment">
            <h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
            <blockquote class="chill-user-quote">
              {{ parent?.comment }}
            </blockquote>
          </div>
        </template>

        <!-- person / edit -->
        <template v-else-if="type === 'person' && action === 'edit'">
          <PersonEdit
            :id="id"
            :action="'edit'"
            :query="''"
            ref="castEditPerson"
          />
        </template>

        <!-- thirdparty / show -->
        <template v-else-if="type === 'thirdparty' && action === 'show'">
          <on-the-fly-thirdparty
            :id="id"
            :type="type"
            :action="action"
            ref="castThirdparty"
          />
          <div v-if="hasResourceComment">
            <h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
            <blockquote class="chill-user-quote">
              {{ parent?.comment }}
            </blockquote>
          </div>
        </template>

        <!-- thirdparty / edit -->
        <template v-else-if="type === 'thirdparty' && action === 'edit'">
          <ThirdPartyEdit ref="castEditThirdParty" action="edit" :id="id" />
        </template>

        <!-- parent provided (thirdparty create with parent) -->
        <template v-else-if="parent">
          <on-the-fly-thirdparty
            :parent="parent"
            :action="action"
            type="thirdparty"
            ref="castThirdparty"
          />
        </template>

        <!-- default: creation wizard -->
        <template v-else>
          <on-the-fly-create
            :action="action"
            :allowed-types="allowedTypes"
            :query="query || ''"
            ref="castNew"
          />
        </template>
      </template>

      <template #footer>
        <a
          v-if="action === 'show'"
          :href="buildLocation(id, type)"
          :title="titleMessage"
          class="btn btn-show"
          >{{ buttonMessage }}
        </a>
        <a v-else class="btn btn-save" @click="saveAction">
          {{ trans(ACTION_SAVE) }}
        </a>
      </template>
    </modal>
  </teleport>
</template>
<script setup lang="ts">
import { ref, computed, defineEmits, defineProps, useTemplateRef } from "vue";
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
import OnTheFlyCreate from "./Create.vue";
import OnTheFlyPerson from "ChillPersonAssets/vuejs/_components/OnTheFly/Person.vue";
import OnTheFlyThirdparty from "ChillThirdPartyAssets/vuejs/_components/OnTheFly/ThirdParty.vue";
import {
  trans,
  ACTION_SHOW,
  ACTION_EDIT,
  ACTION_CREATE,
  ACTION_SAVE,
  ONTHEFLY_CREATE_TITLE_DEFAULT,
  ONTHEFLY_CREATE_TITLE_PERSON,
  ONTHEFLY_CREATE_TITLE_THIRDPARTY,
  ONTHEFLY_SHOW_PERSON,
  ONTHEFLY_SHOW_THIRDPARTY,
  ONTHEFLY_EDIT_PERSON,
  ONTHEFLY_EDIT_THIRDPARTY,
  ACTION_REDIRECT_PERSON,
  ACTION_REDIRECT_THIRDPARTY,
  ONTHEFLY_SHOW_FILE_PERSON,
  ONTHEFLY_SHOW_FILE_THIRDPARTY,
  ONTHEFLY_SHOW_FILE_DEFAULT,
  ONTHEFLY_RESOURCE_COMMENT_TITLE,
  THIRDPARTY_ADDCONTACT,
  THIRDPARTY_ADDCONTACT_TITLE,
} from "translator";
import PersonEdit from "ChillPersonAssets/vuejs/_components/OnTheFly/PersonEdit.vue";
import ThirdPartyEdit from "ChillThirdPartyAssets/vuejs/_components/OnTheFly/ThirdPartyEdit.vue";

// Types
type EntityType = "person" | "thirdparty";
type ActionType = "show" | "edit" | "create" | "addContact";

interface ParentRef {
  type: string;
  id: string | number;
  text?: string;
  comment?: string | null;
}

interface OnTheFlyComponentProps {
  type: EntityType;
  id: number;
  action: ActionType;
  buttonText?: string | null;
  displayBadge?: boolean;
  isDead?: boolean;
  parent?: ParentRef | null;
  allowedTypes?: EntityType[];
  query?: string;
}

const props = withDefaults(defineProps<OnTheFlyComponentProps>(), {
  buttonText: null,
  displayBadge: false,
  isDead: false,
  parent: null,
  allowedTypes: () => ["person", "thirdparty"] as EntityType[],
  query: "",
});

const emit =
  defineEmits<
    (
      e: "saveFormOnTheFly",
      payload: { type: string | undefined; data: any },
    ) => void
  >();

type castEditPersonType = InstanceType<typeof PersonEdit>;
type castEditThirdPartyType = InstanceType<typeof ThirdPartyEdit>;
const castEditPerson = useTemplateRef<castEditPersonType>("castEditPerson");
const castEditThirdParty =
  useTemplateRef<castEditThirdPartyType>("castEditThirdParty");

const modal = ref<{ showModal: boolean; modalDialogClass: string }>({
  showModal: false,
  modalDialogClass: "modal-dialog-scrollable modal-xl",
});

const hasResourceComment = computed<boolean>(() => {
  return (
    typeof props.parent !== "undefined" &&
    props.parent !== null &&
    props.action === "show" &&
    props.parent.type === "accompanying_period_resource" &&
    props.parent.comment !== null &&
    props.parent.comment !== ""
  );
});

const classAction = computed<string>(() => {
  switch (props.action) {
    case "show":
      return "btn-show";
    case "edit":
      return "btn-update";
    case "create":
      return "btn-create";
    case "addContact":
      return "btn-tpchild";
    default:
      return "";
  }
});

const titleAction = computed<string>(() => {
  switch (props.action) {
    case "show":
      return ACTION_SHOW as unknown as string;
    case "edit":
      return ACTION_EDIT as unknown as string;
    case "create":
      return ACTION_CREATE as unknown as string;
    case "addContact":
      return THIRDPARTY_ADDCONTACT as unknown as string;
    default:
      return "";
  }
});

const titleCreate = computed<string>(() => {
  if (typeof props.allowedTypes === "undefined") {
    return trans(ONTHEFLY_CREATE_TITLE_DEFAULT);
  }
  return props.allowedTypes.every((t: EntityType) => t === "person")
    ? trans(ONTHEFLY_CREATE_TITLE_PERSON)
    : props.allowedTypes.every((t: EntityType) => t === "thirdparty")
      ? trans(ONTHEFLY_CREATE_TITLE_THIRDPARTY)
      : trans(ONTHEFLY_CREATE_TITLE_DEFAULT);
});

const titleModal = computed<string>(() => {
  switch (props.action) {
    case "show":
      if (props.type == "person") {
        return trans(ONTHEFLY_SHOW_PERSON);
      } else if (props.type == "thirdparty") {
        return trans(ONTHEFLY_SHOW_THIRDPARTY);
      }
      break;
    case "edit":
      if (props.type == "person") {
        return trans(ONTHEFLY_EDIT_PERSON);
      } else if (props.type == "thirdparty") {
        return trans(ONTHEFLY_EDIT_THIRDPARTY);
      }
      break;
    case "create":
      return titleCreate.value;
    case "addContact":
      return trans(THIRDPARTY_ADDCONTACT_TITLE);
    default:
      break;
  }
  return "";
});

const titleMessage = computed<string>(() => {
  switch (props.type) {
    case "person":
      return trans(ACTION_REDIRECT_PERSON);
    case "thirdparty":
      return trans(ACTION_REDIRECT_THIRDPARTY);
    default:
      return "";
  }
});

const buttonMessage = computed<string>(() => {
  switch (props.type) {
    case "person":
      return trans(ONTHEFLY_SHOW_FILE_PERSON);
    case "thirdparty":
      return trans(ONTHEFLY_SHOW_FILE_THIRDPARTY);
    default:
      return trans(ONTHEFLY_SHOW_FILE_DEFAULT);
  }
});

const isDisplayBadge = computed<boolean>(() => {
  return props.displayBadge && props.buttonText !== null;
});

const badgeType = computed<string>(() => {
  return "entity-" + (props.type ?? "") + " badge-" + (props.type ?? "");
});

const getReturnPath = computed<string>(() => {
  return `?returnPath=${window.location.pathname}${window.location.search}${window.location.hash}`;
});

function closeModal(): void {
  modal.value.showModal = false;
}

function openModal(): void {
  modal.value.showModal = true;
}

function buildLocation(
  id: string | number | undefined,
  type: EntityType | undefined,
): string | undefined {
  if (type === "person") {
    return encodeURI(`/fr/person/${id}/general${getReturnPath.value}`);
  } else if (type === "thirdparty") {
    return encodeURI(`/fr/3party/3party/${id}/view${getReturnPath.value}`);
  }
  return undefined;
}

async function saveAction() {
  if (props.type === "person") {
    const person = await castEditPerson.value?.postPerson();
    if (null !== person) {
      emit("saveFormOnTheFly", { type: props.type, data: person });
    }
  } else if (props.type === "thirdparty") {
    const thirdParty = await castEditThirdParty.value?.postThirdParty();
    if (null !== thirdParty) {
      emit("saveFormOnTheFly", { type: props.type, data: thirdParty });
    }
  }
}

defineExpose({
  openModal,
  closeModal,
  hasResourceComment,
  modal,
  isDisplayBadge,
  Modal,
});
</script>

<style lang="css" scoped>
a {
  cursor: pointer;
}

/* .btn-add-contact {
   background-color: pink;
} */
</style>
