<template>
  <Drawer
    :visible="sidebarState"
    :closeIcon="'pi pi-angle-right'"
    :modal="false"
    position="right"
    :dismissable="false"
    class="!w-[360px]"
    @hide="hide"
    @show="show"
  >
    <template #header>
      <ul class="flex space-x-4 pl-4">
        <li
          class="h1 border-r-2 border-neutral-300 pr-4 cursor-pointer hover:text-neutral-900 hover:duration-700"
          @click="switchTab('summary')"
          :class="tab === 'summary' ? 'text-neutral-900' : ''"
        >
          Summary
        </li>
        <li
          class="h1 border-r-2 border-neutral-300 pr-4 cursor-pointer hover:text-neutral-900 hover:duration-700"
          @click="switchTab('insight')"
          :class="tab === 'insight' ? 'text-neutral-900' : ''"
        >
          Insight
        </li>
      </ul>
    </template>
    <!-- header: summary -->
    <div v-if="tab === 'summary'">
      <!-- Stats -->
      <ul class="pb-4 border-b border-neutral-300">
        <li>
          <p class="h2">{{ i18next.t("Map.FileName") }}</p>
          <div class="flex items-center">
            <div class="blue-dot w-3 h-3 bg-[#0099FF] rounded-full mr-2"></div>
            <span>{{ currentMapFile }}</span>
          </div>
        </li>
      </ul>
      <ul class="pb-4 border-b border-neutral-300">
        <li>
          <p class="h2">Cases</p>
          <div class="flex justify-between items-center">
            <div class="w-full mr-8">
              <span class="block text-[12px]"
                >{{ stats.cases.count.toLocaleString("en-US") }} /
                {{ stats.cases.total.toLocaleString("en-US") }}</span
              >
              <ProgressBar
                :value="valueCases"
                :showValue="false"
                class="!h-2 !rounded-full my-1 !bg-neutral-300"
              ></ProgressBar>
            </div>
            <span
              class="block text-primary text-[20px] text-right font-medium basis-28"
              >{{ getPercentLabel(stats.cases.ratio) }}</span
            >
          </div>
        </li>
        <li>
          <p class="h2">Traces</p>
          <div class="flex justify-between items-center">
            <div class="w-full mr-8">
              <span class="block text-[12px]"
                >{{ stats.traces.count.toLocaleString("en-US") }} /
                {{ stats.traces.total.toLocaleString("en-US") }}</span
              >
              <ProgressBar
                :value="valueTraces"
                :showValue="false"
                class="!h-2 !rounded-full my-1 !bg-neutral-300"
              ></ProgressBar>
            </div>
            <span
              class="block text-primary text-[20px] text-right font-medium basis-28"
              >{{ getPercentLabel(stats.traces.ratio) }}</span
            >
          </div>
        </li>
        <li>
          <p class="h2">Activity Instances</p>
          <div class="flex justify-between items-center">
            <div class="w-full mr-8">
              <span class="block text-[12px]"
                >{{ stats.task_instances.count.toLocaleString("en-US") }} /
                {{ stats.task_instances.total.toLocaleString("en-US") }}</span
              >
              <ProgressBar
                :value="valueTaskInstances"
                :showValue="false"
                class="!h-2 !rounded-full my-1 !bg-neutral-300"
              ></ProgressBar>
            </div>
            <span
              class="block text-primary text-[20px] text-right font-medium basis-28"
              >{{ getPercentLabel(stats.task_instances.ratio) }}</span
            >
          </div>
        </li>
        <li>
          <p class="h2">Activities</p>
          <div class="flex justify-between items-center">
            <div class="w-full mr-8">
              <span class="block text-[12px]"
                >{{ stats.tasks.count.toLocaleString("en-US") }} /
                {{ stats.tasks.total.toLocaleString("en-US") }}</span
              >
              <ProgressBar
                :value="valueTasks"
                :showValue="false"
                class="!h-2 !rounded-full my-1 !bg-neutral-300"
              ></ProgressBar>
            </div>
            <span
              class="block text-primary text-[20px] text-right font-medium basis-28"
              >{{ getPercentLabel(stats.tasks.ratio) }}</span
            >
          </div>
        </li>
      </ul>
      <!-- Log Timeframe -->
      <div class="pt-1 pb-4 border-b border-neutral-300">
        <p class="h2">Log Timeframe</p>
        <div class="text-sm flex items-center">
          <div
            class="blue-dot w-3 h-3 bg-[#0099FF] rounded-full mr-2 flex"
          ></div>
          <span class="pr-1 flex">{{ moment(stats.started_at) }}</span>
          ~
          <span class="pl-1 flex">{{ moment(stats.completed_at) }}</span>
        </div>
      </div>
      <!-- Case Duration -->
      <div class="pt-1 pb-4">
        <p class="h2">Case Duration</p>
        <table class="text-sm caseDurationTable">
          <caption class="hidden">
            Case Duration
          </caption>
          <th class="hidden"></th>
          <tbody>
            <tr>
              <td>
                <Tag
                  value="MIN"
                  class="!text-neutral-900 !bg-neutral-200 mr-2 !w-10"
                ></Tag>
              </td>
              <td class="text-[#0099FF] flex w-20 justify-end">
                {{
                  timeLabel(stats.case_duration.min)[1] +
                  " " +
                  timeLabel(stats.case_duration.min)[2]
                }}
              </td>
            </tr>
            <tr>
              <td>
                <Tag
                  value="AVG"
                  class="!text-neutral-900 !bg-neutral-200 mr-2 !w-10"
                ></Tag>
              </td>
              <td class="text-[#0099FF] flex w-20 justify-end">
                {{
                  timeLabel(stats.case_duration.average)[1] +
                  " " +
                  timeLabel(stats.case_duration.average)[2]
                }}
              </td>
            </tr>
            <tr>
              <td>
                <Tag
                  value="MED"
                  class="!text-neutral-900 !bg-neutral-200 mr-2 !w-10"
                ></Tag>
              </td>
              <td class="text-[#0099FF] flex w-20 justify-end">
                {{
                  timeLabel(stats.case_duration.median)[1] +
                  " " +
                  timeLabel(stats.case_duration.median)[2]
                }}
              </td>
            </tr>
            <tr>
              <td>
                <Tag
                  value="MAX"
                  class="!text-neutral-900 !bg-neutral-200 mr-2 !w-10"
                ></Tag>
              </td>
              <td class="text-[#0099FF] flex w-20 justify-end">
                {{
                  timeLabel(stats.case_duration.max)[1] +
                  " " +
                  timeLabel(stats.case_duration.max)[2]
                }}
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
    <!-- header: insight -->
    <div v-if="tab === 'insight'">
      <div class="border-b-2 border-neutral-300 mb-4">
        <p class="h2">Most Frequent</p>
        <ul class="list-disc ml-6 mb-2 text-sm">
          <li class="leading-5">
            Activity:&nbsp;
            <span
              class="text-[#0099FF] break-words bg-[#F1F5F9] px-2 rounded mx-1"
              v-for="(value, key) in insights.most_freq_tasks"
              :key="key"
              >{{ value }}</span
            >
          </li>
          <li class="leading-5">
            Inbound connections:&nbsp;
            <span
              class="text-[#0099FF] break-words bg-[#F1F5F9] px-2 rounded mx-1"
              v-for="(value, key) in insights.most_freq_in"
              :key="key"
              >{{ value }}
            </span>
          </li>
          <li class="leading-5">
            Outbound connections:&nbsp;
            <span
              class="text-[#0099FF] break-words bg-[#F1F5F9] px-2 rounded mx-1"
              v-for="(value, key) in insights.most_freq_out"
              :key="key"
              >{{ value }}
            </span>
          </li>
        </ul>
        <p class="h2">Most Time-Consuming</p>
        <ul class="list-disc ml-6 mb-4 text-sm">
          <li class="w-full leading-5">
            Activity:&nbsp;
            <span
              class="text-primary break-words bg-[#F1F5F9] px-2 rounded mx-1"
              v-for="(value, key) in insights.most_time_tasks"
              :key="key"
              >{{ value }}
            </span>
          </li>
          <li class="w-full leading-5 mt-2">
            Connection:&nbsp;
            <span
              class="text-primary break-words"
              v-for="(item, key) in insights.most_time_edges"
              :key="key"
            >
              <span v-for="(value, index) in item" :key="index">
                <span class="connection-text bg-[#F1F5F9] px-2 rounded">{{
                  value
                }}</span>
                <span v-if="index !== item.length - 1"
                  >&nbsp;
                  <span class="material-symbols-outlined !text-lg align-sub"
                    >arrow_forward</span
                  >
                  &nbsp;</span
                >
              </span>
              <span
                v-if="key !== insights.most_time_edges.length - 1"
                class="text-neutral-900"
                >,&nbsp;</span
              >
            </span>
          </li>
        </ul>
      </div>
      <div>
        <ul
          class="trace-buttons text-neutral-500 grid grid-cols-2 gap-2 text-center text-sm font-medium mb-2"
        >
          <li
            class="border border-neutral-500 rounded p-2 cursor-pointer hover:text-primary hover:border-primary hover:duration-500"
            @click="onActiveTraceClick(0)"
            :class="activeTrace === 0 ? 'text-primary border-primary' : ''"
          >
            Self-Loop
          </li>
          <li
            class="border border-neutral-500 rounded p-2 cursor-pointer hover:text-primary hover:border-primary hover:duration-500"
            @click="onActiveTraceClick(1)"
            :class="activeTrace === 1 ? 'text-primary border-primary' : ''"
          >
            Short-Loop
          </li>
          <li
            class="border border-neutral-500 rounded p-2 cursor-pointer hover:text-primary hover:border-primary hover:duration-500"
            @click="onActiveTraceClick(2)"
            :class="activeTrace === 2 ? 'text-primary border-primary' : ''"
          >
            Shortest Trace
          </li>
          <li
            class="border border-neutral-500 rounded p-2 cursor-pointer hover:text-primary hover:border-primary hover:duration-500"
            @click="onActiveTraceClick(3)"
            :class="activeTrace === 3 ? 'text-primary border-primary' : ''"
          >
            Longest Trace
          </li>
          <li
            class="border border-neutral-500 rounded p-2 cursor-pointer hover:text-primary hover:border-primary hover:duration-500"
            @click="onActiveTraceClick(4)"
            :class="activeTrace === 4 ? 'text-primary border-primary' : ''"
          >
            Most Frequent Trace
          </li>
        </ul>
        <div
          class="reset-trace-button underline text-[#4E5969] text-[14px] flex justify-end cursor-pointer font-semibold"
          @click="onResetTraceBtnClick"
        >
          {{ i18next.t("Map.Reset") }}
        </div>
        <div>
          <Tabs v-model:value="activeTrace">
            <TabPanel :value="0" header="Self-loop" contentClass="text-sm">
              <p v-if="insights.self_loops.length === 0">No data</p>
              <ul v-else class="ml-6 space-y-1">
                <li v-for="(value, key) in insights.self_loops" :key="key">
                  <span>{{ value }}</span>
                </li>
              </ul>
            </TabPanel>
            <TabPanel :value="1" header="Short-loop" contentClass="text-sm">
              <p v-if="insights.short_loops.length === 0">No data</p>
              <ul v-else class="ml-6 space-y-1">
                <li
                  class="break-words"
                  v-for="(item, key) in insights.short_loops"
                  :key="key"
                >
                  <span v-for="(value, index) in item" :key="index">
                    {{ value }}
                    <span v-if="index !== item.length - 1"
                      >&nbsp;
                      <span class="material-symbols-outlined !text-lg align-sub"
                        >sync_alt</span
                      >
                      &nbsp;</span
                    >
                  </span>
                </li>
              </ul>
            </TabPanel>
            <!-- Iterate starting from shortest_traces -->
            <TabPanel
              v-for="([field, label], i) in fieldNamesAndLabelNames"
              :key="i"
              :value="i + 2"
              :header="label"
              contentClass="text-sm"
            >
              <p
                v-if="insights[field].length === 0"
                class="bg-neutral-100 p-2 rounded"
              >
                No data
              </p>
              <ul v-else class="ml-1 space-y-1">
                <li
                  v-for="(item, key2) in insights[field]"
                  :key="key2"
                  class="mb-2 flex bg-neutral-100 p-2 rounded"
                >
                  <div class="flex left-col mr-1">
                    <input
                      type="radio"
                      name="customRadio"
                      :value="key2"
                      v-model="clickedPathListIndex"
                      class="hidden peer"
                      @click="onPathOptionClick(key2)"
                    />
                    <!-- If in BPMN view mode, path highlighting is not allowed -->
                    <span
                      v-if="!isBPMNOn"
                      @click="onPathOptionClick(key2)"
                      :class="[
                        'w-[18px] h-[18px] rounded-full border-2 inline-flex items-center justify-center cursor-pointer bg-[#FFFFFF]',
                        clickedPathListIndex === key2
                          ? 'border-[#0099FF]'
                          : 'border-[#CBD5E1]',
                      ]"
                    >
                      <div
                        :class="[
                          'w-[9px] h-[9px] rounded-full transition-opacity cursor-pointer',
                          clickedPathListIndex === key2
                            ? 'bg-[#0099FF]'
                            : 'opacity-0',
                        ]"
                      ></div>
                    </span>
                  </div>
                  <div class="right-col">
                    <span v-for="(value, index) in item" :key="index">
                      {{ value }}
                      <span v-if="index !== item.length - 1">
                        &nbsp;
                        <span
                          class="material-symbols-outlined !text-lg align-sub"
                          >arrow_forward</span
                        >
                        &nbsp;
                      </span>
                    </span>
                  </div>
                </li>
              </ul>
            </TabPanel>
          </Tabs>
        </div>
      </div>
    </div>
  </Drawer>
</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/SidebarState
 *   Summary statistics sidebar for the Map view
 *   displaying cases, traces, activities, timeframe,
 *   and case duration.
 */

import { computed, ref } from "vue";
import { usePageAdminStore } from "@/stores/pageAdmin";
import { useMapPathStore } from "@/stores/mapPathStore";
import { getTimeLabel } from "@/module/timeLabel.js";
import getMoment from "moment";
import i18next from "@/i18n/i18n";
import { INSIGHTS_FIELDS_AND_LABELS } from "@/constants/constants";

// Remove the first and second elements
const fieldNamesAndLabelNames = [...INSIGHTS_FIELDS_AND_LABELS].slice(2);

const props = defineProps({
  sidebarState: {
    type: Boolean,
    require: false,
  },
  stats: {
    type: Object,
    required: false,
  },
  insights: {
    type: Object,
    required: false,
  },
});

const pageAdmin = usePageAdminStore();
const mapPathStore = useMapPathStore();

const activeTrace = ref(0);
const currentMapFile = computed(() => pageAdmin.currentMapFile);
const clickedPathListIndex = ref(0);
const isBPMNOn = computed(() => mapPathStore.isBPMNOn);

const tab = ref("summary");
const valueCases = ref(0);
const valueTraces = ref(0);
const valueTaskInstances = ref(0);
const valueTasks = ref(0);

/**
 * Handles click on an active trace to highlight it.
 * @param {number} clickedActiveTraceIndex - The clicked trace index.
 */
function onActiveTraceClick(clickedActiveTraceIndex) {
  mapPathStore.clearAllHighlight();
  activeTrace.value = clickedActiveTraceIndex;
  mapPathStore.highlightClickedPath(
    clickedActiveTraceIndex,
    clickedPathListIndex.value,
  );
}

/**
 * Handles click on a path option to highlight it.
 * @param {number} clickedPath - The clicked path index.
 */
function onPathOptionClick(clickedPath) {
  clickedPathListIndex.value = clickedPath;
  mapPathStore.highlightClickedPath(activeTrace.value, clickedPath);
}

/** Resets the trace highlight to default. */
function onResetTraceBtnClick() {
  if (isBPMNOn.value) {
    return;
  }
  clickedPathListIndex.value = undefined;
}

/**
 * @param {string} newTab Summary or Insight
 */
function switchTab(newTab) {
  tab.value = newTab;
}

/**
 * @param {number} time use timeLabel.js
 */
function timeLabel(time) {
  // sonar-qube prevent super-linear runtime due to backtracking; change * to ?
  //
  const label = getTimeLabel(time).replaceAll(/\s+/g, " "); // Collapse all consecutive whitespace into a single space
  const result = label.match(/^([\d.]+)\s?([a-zA-Z]+)$/); // add ^ and $ to meet sonar-qube need
  return result;
}

/**
 * @param {number} time use moment
 */
function moment(time) {
  return getMoment(time).format("YYYY-MM-DD HH:mm");
}

/**
 * Number to percentage
 * @param   {number} val - The raw ratio value.
 * @returns {string} The formatted percentage string.
 */
function getPercentLabel(val) {
  if (Number((val * 100).toFixed(1)) >= 100) return `100%`;
  else return `${(val * 100).toFixed(1)}%`;
}

/**
 * Behavior when show
 */
function show() {
  valueCases.value = props.stats.cases.ratio * 100;
  valueTraces.value = props.stats.traces.ratio * 100;
  valueTaskInstances.value = props.stats.task_instances.ratio * 100;
  valueTasks.value = props.stats.tasks.ratio * 100;
}

/**
 * Behavior when hidden
 */
function hide() {
  valueCases.value = 0;
  valueTraces.value = 0;
  valueTaskInstances.value = 0;
  valueTasks.value = 0;
}
</script>

<style scoped>
@reference "../../../assets/tailwind.css";
:deep(.p-progressbar .p-progressbar-value) {
  @apply bg-primary;
}
:deep(.p-tablist) {
  @apply hidden;
}
:deep(.p-tabpanels) {
  @apply p-2 rounded;
}
:deep(.p-tabpanel) {
  @apply animate-fadein;
}
.caseDurationTable td {
  @apply scroll-pb-12;
}
.caseDurationTable td:nth-child(2) {
  @apply text-right;
}
.caseDurationTable td:last-child {
  @apply pl-2;
}
</style>
