<template>
  <div class="w-full h-full">
    <div
      class="h-[calc(100%_-_58px)] border-b border-neutral-400 mb-2 scrollbar overflow-x-hidden overflow-y-auto"
    >
      <div
        v-if="this.temporaryData.length === 0"
        class="h-full flex justify-center items-center"
      >
        <span class="text-neutral-500">No Filter.</span>
      </div>
      <div v-else>
        <div class="text-primary h2 flex items-center justify-start my-4">
          <span class="material-symbols-outlined m-2">info</span>
          <p>Disabled filters will not be saved.</p>
        </div>
        <Timeline :value="ruleData">
          <template #content="rule">
            <div
              class="border-b border-neutral-300 flex justify-between items-center space-x-2"
            >
              <!-- content -->
              <div class="pl-2 mb-2">
                <p class="text-sm font-medium leading-5">
                  {{ rule.item.type }}:&nbsp;<span class="text-neutral-500">{{
                    rule.item.label
                  }}</span>
                </p>
              </div>
              <!-- button -->
              <div class="min-w-fit">
                <ToggleSwitch
                  v-model="rule.item.toggle"
                  @input="isRule($event, rule.index)"
                />
                <button
                  type="button"
                  class="m-2 focus:ring focus:ring-danger/20 text-neutral-500 hover:text-danger"
                  @click.stop="deleteRule(rule.index)"
                >
                  <span class="material-symbols-outlined">delete</span>
                </button>
              </div>
            </div>
          </template>
        </Timeline>
      </div>
    </div>
    <!-- Button -->
    <div>
      <div class="float-right space-x-4 px-4 py-2">
        <button
          type="button"
          class="btn btn-sm"
          :class="[temporaryData.length === 0 ? 'btn-disable' : 'btn-neutral']"
          :disabled="temporaryData.length === 0"
          @click="deleteRule('all')"
        >
          Delete All
        </button>
        <button
          type="button"
          class="btn btn-sm"
          :class="[temporaryData.length === 0 ? 'btn-disable' : 'btn-neutral']"
          :disabled="temporaryData.length === 0"
          @click="submitAll"
        >
          Apply All
        </button>
      </div>
    </div>
  </div>
</template>

<script setup>
// The Lucia project.
// Copyright 2023-2026 DSP, inc.  All rights reserved.
// Authors:
//   chiayin.kuo@dsp.im (chiayin), 2023/1/31
/**
 * @module components/Discover/Map/Filter/Funnel Filter funnel
 *   panel showing applied filter rules with toggle, delete, and
 *   apply-all actions.
 */

import { storeToRefs } from "pinia";
import { useToast } from "vue-toast-notification";
import { useLoadingStore } from "@/stores/loading";
import { useAllMapDataStore } from "@/stores/allMapData";
import { delaySecond } from "@/utils/timeUtil.js";

const emit = defineEmits(["submit-all"]);
const $toast = useToast();

const loadingStore = useLoadingStore();
const allMapDataStore = useAllMapDataStore();
const { isLoading } = storeToRefs(loadingStore);
const {
  hasResultRule,
  temporaryData,
  postRuleData,
  ruleData,
  isRuleData,
  tempFilterId,
} = storeToRefs(allMapDataStore);

/**
 * Toggles a filter rule on or off.
 * @param {boolean} e - Whether the rule is enabled.
 * @param {number} index - The rule index.
 */
function isRule(e, index) {
  const rule = isRuleData.value[index];
  // First get the rule object
  // To preserve data order, set the value to 0 and remove it during submitAll
  if (e) temporaryData.value[index] = rule;
  else temporaryData.value[index] = 0;
}

/**
 * Deletes a single filter rule or all rules.
 * @param {number|string} index - The rule index, or 'all' to delete all.
 */
async function deleteRule(index) {
  if (index === "all") {
    temporaryData.value = [];
    isRuleData.value = [];
    ruleData.value = [];
    if (tempFilterId.value) {
      isLoading.value = true;
      tempFilterId.value = null;
      await allMapDataStore.getAllMapData();
      await allMapDataStore.getAllTrace(); // SidebarTrace needs to update in sync
      emit("submit-all");
      isLoading.value = false;
    }
    $toast.success("Filter(s) deleted.");
  } else {
    $toast.success(`Filter deleted.`);
    temporaryData.value.splice(index, 1);
    isRuleData.value.splice(index, 1);
    ruleData.value.splice(index, 1);
  }
}

/** Submits all enabled filter rules and refreshes the map data. */
async function submitAll() {
  postRuleData.value = temporaryData.value.filter((item) => item !== 0); // Get submit data; if toggle buttons are used, find and remove items set to 0
  if (!postRuleData.value?.length) return $toast.error("Not selected");
  await allMapDataStore.checkHasResult(); // Quick backend check for results

  if (hasResultRule.value === null) {
    return;
  } else if (hasResultRule.value) {
    isLoading.value = true;
    await allMapDataStore.addTempFilterId();
    await allMapDataStore.getAllMapData();
    await allMapDataStore.getAllTrace(); // SidebarTrace needs to update in sync
    if (temporaryData.value[0]?.type) {
      allMapDataStore.traceId = allMapDataStore.traces[0]?.id;
    }
    emit("submit-all");
    isLoading.value = false;
    $toast.success("Filter(s) applied.");
    return;
  }

  // sonar-qube "This statement will not be executed conditionally"
  isLoading.value = true;
  await delaySecond(1);
  isLoading.value = false;
  $toast.warning("No result.");
}
</script>

<style scoped>
@reference "../../../../assets/tailwind.css";
/* TimeLine */
:deep(.p-timeline) {
  @apply leading-none my-4;
}
:deep(.p-timeline-event-opposite) {
  @apply hidden;
}
:deep(.p-timeline-event-separator) {
  @apply mx-4;
}
:deep(.p-timeline-event-marker) {
  @apply !bg-primary !border-primary !w-2 !h-2;
}
:deep(.p-timeline-event-connector) {
  @apply !bg-primary my-2 !w-[1px];
}
:deep(.p-timeline-event-content) {
  @apply !px-0;
}
</style>
