<template>
  <section class="animate-fadein w-full h-full">
    <!-- Have activity -->
    <ActList
      v-if="selectedRuleType === 'Have activity'"
      :data="conformanceTask"
      :select="isSubmitTask"
    ></ActList>

    <!-- Activity sequence  -->
    <div
      v-if="
        selectedRuleType === 'Activity sequence' &&
        selectedActivitySequence === 'Start & End'
      "
      class="flex justify-between items-center w-full h-full"
    >
      <ActRadio
        :title="'Start activity'"
        :select="isSubmitStartAndEnd?.[0].task"
        :data="cfmSeqStartData"
        :category="'cfmSeqStart'"
        :task="taskStart"
        :isSubmit="isSubmit"
        @selected-task="selectStart"
        class="w-1/2"
      />
      <ActRadio
        :title="'End activity'"
        :select="isSubmitStartAndEnd?.[1].task"
        :data="cfmSeqEndData"
        :category="'cfmSeqEnd'"
        :task="taskEnd"
        :isSubmit="isSubmit"
        @selected-task="selectEnd"
        class="w-1/2"
      />
    </div>

    <!-- actSeqDrag -->
    <ActSeqDrag
      v-if="
        selectedRuleType === 'Activity sequence' &&
        selectedActivitySequence === 'Sequence' &&
        selectedMode === 'Directly follows'
      "
      :data="conformanceTask"
      :listSeq="isSubmitCfmSeqDirectly"
      :isSubmit="isSubmit"
      :category="'cfmSeqDirectly'"
    ></ActSeqDrag>
    <ActSeqDrag
      v-if="
        selectedRuleType === 'Activity sequence' &&
        selectedActivitySequence === 'Sequence' &&
        selectedMode === 'Eventually follows'
      "
      :data="conformanceTask"
      :listSeq="isSubmitCfmSeqEventually"
      :isSubmit="isSubmit"
      :category="'cfmSeqEventually'"
    ></ActSeqDrag>

    <!-- Activity duration -->
    <ActRadio
      v-if="selectedRuleType === 'Activity duration'"
      :title="'Activities include'"
      :select="isSubmitDurationData?.[0]"
      :data="conformanceTask"
      :category="'cfmDur'"
      :isSubmit="isSubmit"
    />

    <!-- Processing time -->
    <ActRadio
      v-if="
        selectedRuleType === 'Processing time' &&
        selectedProcessScope === 'End to end' &&
        selectedActSeqMore === 'Start'
      "
      :title="'Start'"
      :select="isSubmitCfmPtEteStart?.[0].task"
      :data="cfmPtEteStartData"
      :category="'cfmPtEteStart'"
      :isSubmit="isSubmit"
    />
    <ActRadio
      v-if="
        selectedRuleType === 'Processing time' &&
        selectedProcessScope === 'End to end' &&
        selectedActSeqMore === 'End'
      "
      :title="'End'"
      :select="isSubmitCfmPtEteEnd?.[0].task"
      :data="cfmPtEteEndData"
      :category="'cfmPtEteEnd'"
      :isSubmit="isSubmit"
    />
    <div
      v-if="
        selectedRuleType === 'Processing time' &&
        selectedProcessScope === 'End to end' &&
        selectedActSeqMore === 'Start & End'
      "
      class="flex justify-between items-center w-full h-full"
    >
      <ActRadio
        :title="'Start'"
        :select="isSubmitCfmPtEteSE?.[0].task"
        :data="cfmPtEteSEStartData"
        :category="'cfmPtEteSEStart'"
        :task="taskStart"
        :isSubmit="isSubmit"
        @selected-task="selectStart"
        class="w-1/2"
      />
      <ActRadio
        :title="'End'"
        :select="isSubmitCfmPtEteSE?.[1].task"
        :data="cfmPtEteSEEndData"
        :category="'cfmPtEteSEEnd'"
        :task="taskEnd"
        :isSubmit="isSubmit"
        @selected-task="selectEnd"
        class="w-1/2"
      />
    </div>
    <ActRadio
      v-if="
        selectedRuleType === 'Processing time' &&
        selectedProcessScope === 'Partial' &&
        selectedActSeqFromTo === 'From'
      "
      :title="'From'"
      :select="isSubmitCfmPtPStart?.[0].task"
      :data="cfmPtPStartData"
      :category="'cfmPtPStart'"
      :isSubmit="isSubmit"
    />
    <ActRadio
      v-if="
        selectedRuleType === 'Processing time' &&
        selectedProcessScope === 'Partial' &&
        selectedActSeqFromTo === 'To'
      "
      :title="'To'"
      :select="isSubmitCfmPtPEnd?.[0].task"
      :data="cfmPtPEndData"
      :category="'cfmPtPEnd'"
      :isSubmit="isSubmit"
    />
    <div
      v-if="
        selectedRuleType === 'Processing time' &&
        selectedProcessScope === 'Partial' &&
        selectedActSeqFromTo === 'From & To'
      "
      class="flex justify-between items-center w-full h-full"
    >
      <ActRadio
        :title="'From'"
        :select="isSubmitCfmPtPSE?.[0].task"
        :data="cfmPtPSEStartData"
        class="w-1/2"
        :category="'cfmPtPSEStart'"
        :task="taskStart"
        :isSubmit="isSubmit"
        @selected-task="selectStart"
      />
      <ActRadio
        :title="'To'"
        :select="isSubmitCfmPtPSE?.[1].task"
        :data="cfmPtPSEEndData"
        class="w-1/2"
        :category="'cfmPtPSEEnd'"
        :task="taskEnd"
        :isSubmit="isSubmit"
        @selected-task="selectEnd"
      />
    </div>

    <!-- Waiting time -->
    <ActRadio
      v-if="
        selectedRuleType === 'Waiting time' &&
        selectedProcessScope === 'End to end' &&
        selectedActSeqMore === 'Start'
      "
      :title="'Start'"
      :select="isSubmitCfmWtEteStart?.[0].task"
      :data="cfmWtEteStartData"
      :category="'cfmWtEteStart'"
      :isSubmit="isSubmit"
    />
    <ActRadio
      v-if="
        selectedRuleType === 'Waiting time' &&
        selectedProcessScope === 'End to end' &&
        selectedActSeqMore === 'End'
      "
      :title="'End'"
      :select="isSubmitCfmWtEteEnd?.[0].task"
      :data="cfmWtEteEndData"
      :category="'cfmWtEteEnd'"
      :isSubmit="isSubmit"
    />
    <div
      v-if="
        selectedRuleType === 'Waiting time' &&
        selectedProcessScope === 'End to end' &&
        selectedActSeqMore === 'Start & End'
      "
      class="flex justify-between items-center w-full h-full"
    >
      <ActRadio
        :title="'Start'"
        :select="isSubmitCfmWtEteSE?.[0].task"
        :data="cfmWtEteSEStartData"
        class="w-1/2"
        :category="'cfmWtEteSEStart'"
        :task="taskStart"
        :isSubmit="isSubmit"
        @selected-task="selectStart"
      />
      <ActRadio
        :title="'End'"
        :select="isSubmitCfmWtEteSE?.[1].task"
        :data="cfmWtEteSEEndData"
        class="w-1/2"
        :category="'cfmWtEteSEEnd'"
        :task="taskEnd"
        :isSubmit="isSubmit"
        @selected-task="selectEnd"
      />
    </div>
    <ActRadio
      v-if="
        selectedRuleType === 'Waiting time' &&
        selectedProcessScope === 'Partial' &&
        selectedActSeqFromTo === 'From'
      "
      :title="'From'"
      :select="isSubmitCfmWtPStart?.[0].task"
      :data="cfmWtPStartData"
      :category="'cfmWtPStart'"
      :isSubmit="isSubmit"
    />
    <ActRadio
      v-if="
        selectedRuleType === 'Waiting time' &&
        selectedProcessScope === 'Partial' &&
        selectedActSeqFromTo === 'To'
      "
      :title="'To'"
      :select="isSubmitCfmWtPEnd?.[0].task"
      :data="cfmWtPEndData"
      :category="'cfmWtPEnd'"
      :isSubmit="isSubmit"
    />
    <div
      v-if="
        selectedRuleType === 'Waiting time' &&
        selectedProcessScope === 'Partial' &&
        selectedActSeqFromTo === 'From & To'
      "
      class="flex justify-between items-center w-full h-full"
    >
      <ActRadio
        :title="'From'"
        :select="isSubmitCfmWtPSE?.[0].task"
        :data="cfmWtPSEStartData"
        class="w-1/2"
        :category="'cfmWtPSEStart'"
        :task="taskStart"
        :isSubmit="isSubmit"
        @selected-task="selectStart"
      />
      <ActRadio
        :title="'To'"
        :select="isSubmitCfmWtPSE?.[1].task"
        :data="cfmWtPSEEndData"
        class="w-1/2"
        :category="'cfmWtPSEEnd'"
        :task="taskEnd"
        :isSubmit="isSubmit"
        @selected-task="selectEnd"
      />
    </div>

    <!-- Cycle time -->
    <ActRadio
      v-if="
        selectedRuleType === 'Cycle time' &&
        selectedProcessScope === 'End to end' &&
        selectedActSeqMore === 'Start'
      "
      :title="'Start'"
      :select="isSubmitCfmCtEteStart?.[0].task"
      :data="cfmCtEteStartData"
      :category="'cfmCtEteStart'"
      :isSubmit="isSubmit"
    />
    <ActRadio
      v-if="
        selectedRuleType === 'Cycle time' &&
        selectedProcessScope === 'End to end' &&
        selectedActSeqMore === 'End'
      "
      :title="'End'"
      :select="isSubmitCfmCtEteEnd?.[0].task"
      :data="cfmCtEteEndData"
      :category="'cfmCtEteEnd'"
      :isSubmit="isSubmit"
    />
    <div
      v-if="
        selectedRuleType === 'Cycle time' &&
        selectedProcessScope === 'End to end' &&
        selectedActSeqMore === 'Start & End'
      "
      class="flex justify-between items-center w-full h-full"
    >
      <ActRadio
        :title="'Start'"
        :select="isSubmitCfmCtEteSE?.[0].task"
        :data="cfmCtEteSEStartData"
        class="w-1/2"
        :category="'cfmCtEteSEStart'"
        :task="taskStart"
        :isSubmit="isSubmit"
        @selected-task="selectStart"
      />
      <ActRadio
        :title="'End'"
        :select="isSubmitCfmCtEteSE?.[1].task"
        :data="cfmCtEteSEEndData"
        class="w-1/2"
        :category="'cfmCtEteSEEnd'"
        :task="taskEnd"
        :isSubmit="isSubmit"
        @selected-task="selectEnd"
      />
    </div>
  </section>
</template>
<script setup>
// The Lucia project.
// Copyright 2023-2026 DSP, inc.  All rights reserved.
// Authors:
//   chiayin.kuo@dsp.im (chiayin), 2023/1/31
//   cindy.chang@dsp.im (Cindy Chang), 2024/5/30
//   imacat.yang@dsp.im (imacat), 2023/9/23
/**
 * @module components/Discover/Conformance/ConformanceSidebar/ConformanceShowBar
 *   Horizontal bar chart component displaying conformance
 *   check result statistics.
 */

import { ref, computed, watch, onBeforeUnmount } from "vue";
import { storeToRefs } from "pinia";
import { useLoadingStore } from "@/stores/loading";
import { useConformanceStore } from "@/stores/conformance";
import emitter from "@/utils/emitter";
import ActList from "./ActList.vue";
import ActRadio from "./ActRadio.vue";
import ActSeqDrag from "./ActSeqDrag.vue";

const loadingStore = useLoadingStore();
const conformanceStore = useConformanceStore();
const { isLoading } = storeToRefs(loadingStore);
const {
  selectedRuleType,
  selectedActivitySequence,
  selectedMode,
  selectedProcessScope,
  selectedActSeqMore,
  selectedActSeqFromTo,
  conformanceTask,
  cfmSeqStart,
  cfmSeqEnd,
  cfmPtEteStart,
  cfmPtEteEnd,
  cfmPtEteSE,
  cfmPtPStart,
  cfmPtPEnd,
  cfmPtPSE,
  cfmWtEteStart,
  cfmWtEteEnd,
  cfmWtEteSE,
  cfmWtPStart,
  cfmWtPEnd,
  cfmWtPSE,
  cfmCtEteStart,
  cfmCtEteEnd,
  cfmCtEteSE,
  isStartSelected,
  isEndSelected,
} = storeToRefs(conformanceStore);

const props = defineProps([
  "isSubmit",
  "isSubmitTask",
  "isSubmitStartAndEnd",
  "isSubmitCfmSeqDirectly",
  "isSubmitCfmSeqEventually",
  "isSubmitDurationData",
  "isSubmitCfmPtEteStart",
  "isSubmitCfmPtEteEnd",
  "isSubmitCfmPtEteSE",
  "isSubmitCfmPtPStart",
  "isSubmitCfmPtPEnd",
  "isSubmitCfmPtPSE",
  "isSubmitCfmWtEteStart",
  "isSubmitCfmWtEteEnd",
  "isSubmitCfmWtEteSE",
  "isSubmitCfmWtPStart",
  "isSubmitCfmWtPEnd",
  "isSubmitCfmWtPSE",
  "isSubmitCfmCtEteStart",
  "isSubmitCfmCtEteEnd",
  "isSubmitCfmCtEteSE",
  "isSubmitShowDataSeq",
  "isSubmitShowDataPtEte",
  "isSubmitShowDataPtP",
  "isSubmitShowDataWtEte",
  "isSubmitShowDataWtP",
  "isSubmitShowDataCt",
]);

const task = ref(null);
const taskStart = ref(null);
const taskEnd = ref(null);

// Activity sequence
const cfmSeqStartData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataSeq?.task ?? null;
  return isEndSelected.value
    ? setSeqStartAndEndData(cfmSeqEnd.value, "sources", selectedTask)
    : cfmSeqStart.value.map((i) => i.label);
});
const cfmSeqEndData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataSeq?.task ?? null;
  return isStartSelected.value
    ? setSeqStartAndEndData(cfmSeqStart.value, "sinks", selectedTask)
    : cfmSeqEnd.value.map((i) => i.label);
});
// Processing time
const cfmPtEteStartData = computed(() => {
  return cfmPtEteStart.value.map((i) => i.task);
});
const cfmPtEteEndData = computed(() => {
  return cfmPtEteEnd.value.map((i) => i.task);
});
const cfmPtEteSEStartData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataPtEte?.task ?? null;
  return isEndSelected.value
    ? setStartAndEndData(cfmPtEteSE.value, "end", selectedTask)
    : setTaskData(cfmPtEteSE.value, "start");
});
const cfmPtEteSEEndData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataPtEte?.task ?? null;
  return isStartSelected.value
    ? setStartAndEndData(cfmPtEteSE.value, "start", selectedTask)
    : setTaskData(cfmPtEteSE.value, "end");
});
const cfmPtPStartData = computed(() => {
  return cfmPtPStart.value.map((i) => i.task);
});
const cfmPtPEndData = computed(() => {
  return cfmPtPEnd.value.map((i) => i.task);
});
const cfmPtPSEStartData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataPtP?.task ?? null;
  return isEndSelected.value
    ? setStartAndEndData(cfmPtPSE.value, "end", selectedTask)
    : setTaskData(cfmPtPSE.value, "start");
});
const cfmPtPSEEndData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataPtP?.task ?? null;
  return isStartSelected.value
    ? setStartAndEndData(cfmPtPSE.value, "start", selectedTask)
    : setTaskData(cfmPtPSE.value, "end");
});
// Waiting time
const cfmWtEteStartData = computed(() => {
  return cfmWtEteStart.value.map((i) => i.task);
});
const cfmWtEteEndData = computed(() => {
  return cfmWtEteEnd.value.map((i) => i.task);
});
const cfmWtEteSEStartData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataWtEte?.task ?? null;
  return isEndSelected.value
    ? setStartAndEndData(cfmWtEteSE.value, "end", selectedTask)
    : setTaskData(cfmWtEteSE.value, "start");
});
const cfmWtEteSEEndData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataWtEte?.task ?? null;
  return isStartSelected.value
    ? setStartAndEndData(cfmWtEteSE.value, "start", selectedTask)
    : setTaskData(cfmWtEteSE.value, "end");
});
const cfmWtPStartData = computed(() => {
  return cfmWtPStart.value.map((i) => i.task);
});
const cfmWtPEndData = computed(() => {
  return cfmWtPEnd.value.map((i) => i.task);
});
const cfmWtPSEStartData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataWtP?.task ?? null;
  return isEndSelected.value
    ? setStartAndEndData(cfmWtPSE.value, "end", selectedTask)
    : setTaskData(cfmWtPSE.value, "start");
});
const cfmWtPSEEndData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataWtP?.task ?? null;
  return isStartSelected.value
    ? setStartAndEndData(cfmWtPSE.value, "start", selectedTask)
    : setTaskData(cfmWtPSE.value, "end");
});
// Cycle time
const cfmCtEteStartData = computed(() => {
  return cfmCtEteStart.value.map((i) => i.task);
});
const cfmCtEteEndData = computed(() => {
  return cfmCtEteEnd.value.map((i) => i.task);
});
const cfmCtEteSEStartData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataCt?.task ?? null;
  return isEndSelected.value
    ? setStartAndEndData(cfmCtEteSE.value, "end", selectedTask)
    : setTaskData(cfmCtEteSE.value, "start");
});
const cfmCtEteSEEndData = computed(() => {
  const selectedTask = task.value ?? props.isSubmitShowDataCt?.task ?? null;
  return isStartSelected.value
    ? setStartAndEndData(cfmCtEteSE.value, "start", selectedTask)
    : setTaskData(cfmCtEteSE.value, "end");
});

// Watchers - Fix issue where saved rule files could not be re-edited
watch(
  () => props.isSubmitShowDataSeq,
  (newValue) => {
    taskStart.value = newValue.taskStart;
    taskEnd.value = newValue.taskEnd;
  },
);
watch(
  () => props.isSubmitShowDataPtEte,
  (newValue) => {
    taskStart.value = newValue.taskStart;
    taskEnd.value = newValue.taskEnd;
  },
);
watch(
  () => props.isSubmitShowDataPtP,
  (newValue) => {
    taskStart.value = newValue.taskStart;
    taskEnd.value = newValue.taskEnd;
  },
);
watch(
  () => props.isSubmitShowDataWtEte,
  (newValue) => {
    taskStart.value = newValue.taskStart;
    taskEnd.value = newValue.taskEnd;
  },
);
watch(
  () => props.isSubmitShowDataWtP,
  (newValue) => {
    taskStart.value = newValue.taskStart;
    taskEnd.value = newValue.taskEnd;
  },
);
watch(
  () => props.isSubmitShowDataCt,
  (newValue) => {
    taskStart.value = newValue.taskStart;
    taskEnd.value = newValue.taskEnd;
  },
);

/**
 * Sets the start and end radio data.
 * @param {object} data - Activities list data from the backend (cfmSeqStart, cfmSeqEnd, cfmPtEteSE, etc.).
 * @param {string} category - 'start' or 'end'.
 * @returns {array}
 */
function setTaskData(data, category) {
  let newData = data.map((i) => i[category]);
  newData = [...new Set(newData)]; // Set is a collection type that only stores unique values.
  return newData;
}
/**
 * Resets the linked start and end radio data.
 * @param {object} data - Activities list data from the backend (cfmPtEteSE, cfmPtPSE, etc.).
 * @param {string} category - 'start' or 'end'.
 * @param {string} task - The selected activity task.
 * @returns {array}
 */
function setStartAndEndData(data, category, taskVal) {
  let oppositeCategory = "";
  if (category === "start") {
    oppositeCategory = "end";
  } else {
    oppositeCategory = "start";
  }
  let newData = data
    .filter((i) => i[category] === taskVal)
    .map((i) => i[oppositeCategory]);
  newData = [...new Set(newData)];
  return newData;
}
/**
 * Resets the activity sequence linked start and end radio data.
 * @param {object} data - Activities list data from the backend (cfmSeqStart or cfmSeqEnd).
 * @param {string} category - 'sources' or 'sinks'.
 * @param {string} task - The selected activity task.
 * @returns {array}
 */
function setSeqStartAndEndData(data, category, taskVal) {
  let newData = data.filter((i) => i.label === taskVal).map((i) => i[category]);
  newData = [...new Set(...newData)];
  return newData;
}
/**
 * select start list's task
 * @param {Event} e - The input event.
 */
function selectStart(e) {
  taskStart.value = e;
  if (isStartSelected.value === null || isStartSelected.value === true) {
    isStartSelected.value = true;
    isEndSelected.value = false;
    task.value = e;
    taskEnd.value = null;
  }
}
/**
 * select End list's task
 * @param {Event} e - The input event.
 */
function selectEnd(e) {
  taskEnd.value = e;
  if (isEndSelected.value === null || isEndSelected.value === true) {
    isEndSelected.value = true;
    isStartSelected.value = false;
    task.value = e;
    taskStart.value = null;
  }
}
/**
 * reset all data.
 */
function reset() {
  task.value = null;
  isStartSelected.value = null;
  isEndSelected.value = null;
  taskStart.value = null;
  taskEnd.value = null;
}
/**
 * Updates linked Start & End data when radio selection changes.
 * @param {boolean} data - Whether data should be restored from submission state.
 */
function setResetData(data) {
  if (data) {
    if (props.isSubmit) {
      switch (selectedRuleType.value) {
        case "Activity sequence":
          task.value = props.isSubmitShowDataSeq.task;
          isStartSelected.value = props.isSubmitShowDataSeq.isStartSelected;
          isEndSelected.value = props.isSubmitShowDataSeq.isEndSelected;
          break;
        case "Processing time":
          switch (selectedProcessScope.value) {
            case "End to end":
              task.value = props.isSubmitShowDataPtEte.task;
              isStartSelected.value =
                props.isSubmitShowDataPtEte.isStartSelected;
              isEndSelected.value = props.isSubmitShowDataPtEte.isEndSelected;
              break;
            case "Partial":
              task.value = props.isSubmitShowDataPtP.task;
              isStartSelected.value = props.isSubmitShowDataPtP.isStartSelected;
              isEndSelected.value = props.isSubmitShowDataPtP.isEndSelected;
              break;
            default:
              break;
          }
          break;
        case "Waiting time":
          switch (selectedProcessScope.value) {
            case "End to end":
              task.value = props.isSubmitShowDataWtEte.task;
              isStartSelected.value =
                props.isSubmitShowDataWtEte.isStartSelected;
              isEndSelected.value = props.isSubmitShowDataWtEte.isEndSelected;
              break;
            case "Partial":
              task.value = props.isSubmitShowDataWtP.task;
              isStartSelected.value = props.isSubmitShowDataWtP.isStartSelected;
              isEndSelected.value = props.isSubmitShowDataWtP.isEndSelected;
              break;
            default:
              break;
          }
          break;
        case "Cycle time":
          task.value = props.isSubmitShowDataCt.task;
          isStartSelected.value = props.isSubmitShowDataCt.isStartSelected;
          isEndSelected.value = props.isSubmitShowDataCt.isEndSelected;
          break;
        default:
          break;
      }
    } else {
      reset();
    }
  }
}

// created() logic
emitter.on("isRadioChange", (data) => {
  setResetData(data);
});
emitter.on("isRadioSeqChange", (data) => {
  setResetData(data);
});
emitter.on("isRadioProcessScopeChange", (data) => {
  if (data) {
    setResetData(data);
  }
});
emitter.on("isRadioActSeqMoreChange", (data) => {
  if (data) {
    setResetData(data);
  }
});
emitter.on("isRadioActSeqFromToChange", (data) => {
  if (data) {
    setResetData(data);
  }
});
emitter.on("reset", (data) => {
  reset();
});

onBeforeUnmount(() => {
  emitter.off("isRadioChange");
  emitter.off("isRadioSeqChange");
  emitter.off("isRadioProcessScopeChange");
  emitter.off("isRadioActSeqMoreChange");
  emitter.off("isRadioActSeqFromToChange");
  emitter.off("reset");
});
</script>
