<script setup lang="ts">
import {
  GenericDoc,
  GenericDocForAccompanyingPeriod,
} from "ChillDocStoreAssets/types/generic_doc";
import PickGenericDocItem from "ChillMainAssets/vuejs/WorkflowAttachment/Component/PickGenericDocItem.vue";
import { fetch_generic_docs_by_accompanying_period } from "ChillDocStoreAssets/js/generic-doc-api";
import { computed, onMounted, ref } from "vue";
import { EntityWorkflow } from "ChillMainAssets/types";

interface PickGenericDocProps {
  workflow: EntityWorkflow | null;
  accompanyingPeriodId: number;
  pickedList: GenericDocForAccompanyingPeriod[];
  toRemove: GenericDocForAccompanyingPeriod[];
}

const props = defineProps<PickGenericDocProps>();
const emit = defineEmits<{
  (
    e: "pickGenericDoc",
    payload: { genericDoc: GenericDocForAccompanyingPeriod },
  ): void;

  (
    e: "removeGenericDoc",
    payload: { genericDoc: GenericDocForAccompanyingPeriod },
  ): void;
}>();

const genericDocs = ref<GenericDocForAccompanyingPeriod[]>([]);
const loaded = ref(false);

const isPicked = (genericDoc: GenericDocForAccompanyingPeriod): boolean =>
  props.pickedList.findIndex(
    (element: GenericDocForAccompanyingPeriod) =>
      element.uniqueKey === genericDoc.uniqueKey,
  ) !== -1;

onMounted(async () => {
  const fetchedGenericDocs = await fetch_generic_docs_by_accompanying_period(
    props.accompanyingPeriodId,
  );
  const documentClasses = [
    "Chill\\DocStoreBundle\\Entity\\AccompanyingCourseDocument",
    "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument",
    "Chill\\DocStoreBundle\\Entity\\PersonDocument",
  ];

  genericDocs.value = fetchedGenericDocs.filter(
    (doc) =>
      !documentClasses.includes(props.workflow?.relatedEntityClass || "") ||
      props.workflow?.relatedEntityId !== doc.identifiers.id,
  );
  loaded.value = true;
});

const textFilter = ref<string>("");
const dateFromFilter = ref<string | null>(null);
const dateToFilter = ref<string | null>(null);
const placesFilter = ref<string[]>([]);

const availablePlaces = computed<string[]>(() => {
  const places = new Set<string>(
    genericDocs.value.map((genericDoc: GenericDoc) => genericDoc.key),
  );

  return Array.from(places).sort((a, b) => (a < b ? -1 : a === b ? 0 : 1));
});

const placeTrans = (str: string): string => {
  switch (str) {
    case "accompanying_course_document":
      return "Documents du parcours";
    case "person_document":
      return "Documents de l'usager";
    case "accompanying_period_calendar_document":
      return "Document des rendez-vous des parcours";
    case "accompanying_period_activity_document":
      return "Document des échanges des parcours";
    case "accompanying_period_work_evaluation_document":
      return "Document des actions d'accompagnement";
    default:
      return str;
  }
};

const onPickDocument = (payload: {
  genericDoc: GenericDocForAccompanyingPeriod;
}) => emit("pickGenericDoc", payload);

const onRemoveGenericDoc = (payload: {
  genericDoc: GenericDocForAccompanyingPeriod;
}) => emit("removeGenericDoc", payload);

const filteredDocuments = computed<GenericDocForAccompanyingPeriod[]>(() => {
  if (false === loaded.value) {
    return [];
  }

  return genericDocs.value
    .filter(
      (genericDoc: GenericDocForAccompanyingPeriod) =>
        !props.toRemove
          .map((g: GenericDocForAccompanyingPeriod) => g.uniqueKey)
          .includes(genericDoc.uniqueKey),
    )
    .filter((genericDoc: GenericDocForAccompanyingPeriod) => {
      if (textFilter.value === "") {
        return true;
      }

      const needles = textFilter.value
        .trim()
        .split(" ")
        .map((str: string) => str.trim().toLowerCase())
        .filter((str: string) => str.length > 0);
      const title: string =
        "title" in genericDoc.metadata
          ? (genericDoc.metadata.title as string)
          : "";
      if (title === "") {
        return false;
      }

      return needles.every((n: string) => title.toLowerCase().includes(n));
    })
    .filter((genericDoc: GenericDocForAccompanyingPeriod) => {
      if (placesFilter.value.length === 0) {
        return true;
      }

      return placesFilter.value.includes(genericDoc.key);
    })
    .filter((genericDoc: GenericDocForAccompanyingPeriod) => {
      if (dateToFilter.value === null) {
        return true;
      }

      return genericDoc.doc_date.datetime8601 < dateToFilter.value;
    })
    .filter((genericDoc: GenericDocForAccompanyingPeriod) => {
      if (dateFromFilter.value === null) {
        return true;
      }

      return genericDoc.doc_date.datetime8601 > dateFromFilter.value;
    });
});
</script>

<template>
  <div v-if="loaded">
    <div>
      <form name="f" method="get">
        <div class="accordion my-3" id="filterOrderAccordion">
          <h2 class="accordion-header" id="filterOrderHeading">
            <button
              class="accordion-button"
              type="button"
              data-bs-toggle="collapse"
              data-bs-target="#filterOrderCollapse"
              aria-expanded="true"
              aria-controls="filterOrderCollapse"
            >
              <strong
                ><i class="fa fa-fw fa-filter"></i>Filtrer la liste</strong
              >
            </button>
          </h2>
          <div
            class="accordion-collapse collapse"
            id="filterOrderCollapse"
            aria-labelledby="filterOrderHeading"
            data-bs-parent="#filterOrderAccordion"
            style=""
          >
            <div
              class="accordion-body chill_filter_order container-xxl p-5 py-2"
            >
              <div class="row my-2">
                <div class="col-sm-12">
                  <div class="input-group">
                    <input
                      v-model="textFilter"
                      type="search"
                      id="f_q"
                      name="f[q]"
                      placeholder="Chercher dans la liste"
                      class="form-control"
                    />
                    <button type="submit" class="btn btn-misc">
                      <i class="fa fa-search"></i>
                    </button>
                  </div>
                </div>
              </div>

              <div class="row my-2">
                <legend class="col-form-label col-sm-4 required">
                  Date du document
                </legend>
                <div class="col-sm-8 pt-1">
                  <div class="input-group">
                    <span class="input-group-text">Du</span>
                    <input
                      v-model="dateFromFilter"
                      type="date"
                      id="f_dateRanges_dateRange_from"
                      name="f[dateRanges][dateRange][from]"
                      class="form-control"
                    />
                    <span class="input-group-text">Au</span>
                    <input
                      v-model="dateToFilter"
                      type="date"
                      id="f_dateRanges_dateRange_to"
                      name="f[dateRanges][dateRange][to]"
                      class="form-control"
                    />
                  </div>
                </div>
              </div>

              <div class="row my-2">
                <div class="col-sm-4 col-form-label">Filtrer par</div>
                <div class="col-sm-8 pt-2">
                  <div class="form-check" v-for="p in availablePlaces" :key="p">
                    <input
                      type="checkbox"
                      v-model="placesFilter"
                      name="f[checkboxes][places][]"
                      class="form-check-input"
                      :value="p"
                    />
                    <label class="form-check-label">{{ placeTrans(p) }}</label>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </form>
    </div>

    <div v-if="genericDocs.length > 0" class="flex-table chill-task-list">
      <pick-generic-doc-item
        v-for="g in filteredDocuments"
        :key="g.uniqueKey"
        :accompanying-period-id="accompanyingPeriodId"
        :genericDoc="g"
        :is-picked="isPicked(g)"
        @pickGenericDoc="onPickDocument"
        @removeGenericDoc="onRemoveGenericDoc"
      ></pick-generic-doc-item>
    </div>
    <div v-else class="text-center chill-no-data-statement">
      Aucun document dans ce parcours
    </div>
  </div>
  <div v-else>
    <div class="d-flex align-items-center">
      <strong>Chargement…</strong>
      <div
        class="spinner-border ms-auto"
        role="status"
        aria-hidden="true"
      ></div>
    </div>
  </div>
</template>

<style scoped lang="scss"></style>
