<template>
  <div class="flex justify-center pt-2">
    <div class="flex w-[1216px] flex-col items-center">
      <div class="flex w-full justify-between py-2 items-center">
        <button
          id="create_new_acct_btn"
          class="flex rounded-full bg-primary text-[#ffffff] flex justify-center items-center px-6 py-[10px]"
          @click="onCreateNewClick"
        >
          {{ i18next.t("AcctMgmt.CreateNew") }}
        </button>
        <SearchBar
          @on-search-account-button-click="onSearchAccountButtonClick"
        />
      </div>
      <div
        id="acct_mgmt_data_grid"
        class="flex w-full overflow-y-auto h-[570px]"
        @scroll="handleScroll"
      >
        <DataTable
          :value="accountSearchResults"
          dataKey="username"
          tableClass="w-full mt-4 text-sm relative table-fixed"
          :rowClass="getRowClass"
        >
          <Column
            field="username"
            :header="i18next.t('AcctMgmt.Account')"
            bodyClass="font-medium"
            sortable
          >
            <template #body="slotProps">
              <div
                class="row-container flex-w-full-hoverable w-full"
                @mouseenter="handleRowMouseOver(slotProps.data.username)"
                @mouseout="handleRowMouseOut(slotProps.data.username)"
              >
                <div
                  @dblclick="onAcctDoubleClick(slotProps.data.username)"
                  class="account-cell cursor-pointer whitespace-nowrap overflow-hidden text-ellipsis"
                >
                  {{ slotProps.data.username }}
                </div>
                <span
                  id="just_create_badge"
                  class="flex ml-4"
                  v-if="
                    isOneAccountJustCreate &&
                    slotProps.data.username === justCreateUsername
                  "
                >
                  <img src="@/assets/icon-new.svg" alt="New" />
                </span>
              </div>
            </template>
          </Column>
          <Column
            field="name"
            :header="i18next.t('AcctMgmt.FullName')"
            bodyClass="text-neutral-500"
            sortable
          >
            <template #body="slotProps">
              <div
                class="row-container flex-w-full-hoverable w-full"
                @mouseenter="handleRowMouseOver(slotProps.data.username)"
                @mouseout="handleRowMouseOut(slotProps.data.username)"
              >
                <div
                  class="fullname-cell whitespace-nowrap overflow-hidden text-ellipsis"
                >
                  {{ slotProps.data.name }}
                </div>
              </div>
            </template>
          </Column>
          <Column
            field="is_admin"
            :header="i18next.t('AcctMgmt.AdminRights')"
            bodyClass="text-neutral-500 flex justify-center"
            headerClass="header-center"
          >
            <template #body="slotProps">
              <div
                v-if="!slotProps.data.isCurrentLoggedIn"
                class="row-container flex-w-full-hoverable flex w-full justify-center"
                @mouseenter="handleRowMouseOver(slotProps.data.username)"
                @mouseout="handleRowMouseOut(slotProps.data.username)"
              >
                <img
                  v-if="slotProps.data.is_admin"
                  src="@/assets/radioOn.svg"
                  alt="Radio On"
                  class="btn-admin cursor-pointer flex justify-center"
                  @click="onAdminInputClick(slotProps.data, false)"
                />
                <img
                  v-else
                  src="@/assets/radioOff.svg"
                  alt="Radio Off"
                  class="btn-admin cursor-pointer flex justify-center"
                  @click="onAdminInputClick(slotProps.data, true)"
                />
              </div>
              <div
                v-else
                @mouseenter="handleRowMouseOver(slotProps.data.username)"
                @mouseout="handleRowMouseOut(slotProps.data.username)"
                class="row-container flex-w-full-hoverable flex w-full h-6"
              ></div>
            </template>
          </Column>
          <Column
            field="is_active"
            :header="i18next.t('AcctMgmt.AccountActivation')"
            bodyClass="text-neutral-500"
            headerClass="header-center"
          >
            <template #body="slotProps">
              <div
                v-if="!slotProps.data.isCurrentLoggedIn"
                class="row-container flex-w-full-hoverable w-full"
                @mouseenter="handleRowMouseOver(slotProps.data.username)"
                @mouseout="handleRowMouseOut(slotProps.data.username)"
              >
                <div class="w-full flex justify-center">
                  <img
                    v-if="slotProps.data.is_active"
                    src="@/assets/radioOn.svg"
                    alt="Radio On"
                    class="btn-activate cursor-pointer flex"
                    @click="setIsActiveInput(slotProps.data, false)"
                  />
                  <img
                    v-else
                    src="@/assets/radioOff.svg"
                    alt="Radio Off"
                    class="btn-activate cursor-pointer flex"
                    @click="setIsActiveInput(slotProps.data, true)"
                  />
                </div>
              </div>
              <div
                v-else
                @mouseenter="handleRowMouseOver(slotProps.data.username)"
                @mouseout="handleRowMouseOut(slotProps.data.username)"
                class="row-container flex-w-full-hoverable flex w-full h-6"
              ></div>
            </template>
          </Column>
          <Column
            :header="i18next.t('AcctMgmt.Detail')"
            bodyClass="text-neutral-500"
            headerClass="header-center"
          >
            <template #body="slotProps">
              <div
                class="row-container flex-w-full-hoverable w-full flex justify-center"
                @mouseenter="handleRowMouseOver(slotProps.data.username)"
                @mouseout="handleRowMouseOut(slotProps.data.username)"
              >
                <img
                  :src="
                    slotProps.data.isDetailHovered
                      ? iconDetailOn
                      : iconDetailOff
                  "
                  alt="Detail"
                  class="btn-detail cursor-pointer"
                  @click="onDetailBtnClick(slotProps.data.username)"
                  @mouseover="handleDetailMouseOver(slotProps.data.username)"
                  @mouseout="handleDetailMouseOut(slotProps.data.username)"
                />
              </div>
            </template>
          </Column>
          <Column
            :header="i18next.t('AcctMgmt.Edit')"
            bodyClass="text-neutral-500"
            headerClass="header-center"
          >
            <template #body="slotProps">
              <div
                class="row-container flex-w-full-hoverable w-full flex justify-center"
                @mouseenter="handleRowMouseOver(slotProps.data.username)"
              >
                <img
                  :src="slotProps.data.isEditHovered ? iconEditOn : iconEditOff"
                  alt="Edit"
                  class="btn-edit cursor-pointer"
                  @click="onEditButtonClick(slotProps.data.username)"
                  @mouseover="handleEditMouseOver(slotProps.data.username)"
                  @mouseout="handleEditMouseOut(slotProps.data.username)"
                />
              </div>
            </template>
          </Column>
          <Column
            :header="i18next.t('AcctMgmt.Delete')"
            bodyClass="text-neutral-500 flex justify-center"
            headerClass="header-center"
          >
            <template #body="slotProps">
              <div
                v-if="!slotProps.data.isCurrentLoggedIn"
                class="row-container flex-w-full-hoverable w-full flex justify-center"
                @mouseenter="handleRowMouseOver(slotProps.data.username)"
              >
                <img
                  :src="
                    slotProps.data.isDeleteHovered
                      ? iconDeleteRed
                      : iconDeleteGray
                  "
                  :alt="
                    slotProps.data.isDeleteHovered ? 'hovered' : 'not-hovered'
                  "
                  class="delete-account cursor-pointer flex"
                  @mouseover="handleDeleteMouseOver(slotProps.data.username)"
                  @mouseout="handleDeleteMouseOut(slotProps.data.username)"
                  @click="onDeleteBtnClick(slotProps.data.username)"
                />
              </div>
              <div
                v-else
                @mouseenter="handleRowMouseOver(slotProps.data.username)"
                @mouseout="handleRowMouseOut(slotProps.data.username)"
                class="row-container flex-w-full-hoverable flex w-full h-6"
              ></div>
            </template>
          </Column>
        </DataTable>
      </div>
    </div>
  </div>
</template>

<script setup>
// The Lucia project.
// Copyright 2024-2026 DSP, inc.  All rights reserved.
// Authors:
//   cindy.chang@dsp.im (Cindy Chang), 2024/5/30
/**
 * @module views/AccountManagement/AccountAdmin Account
 *   administration page with user list, search, create/edit/
 *   delete actions, admin toggle, and infinite scroll.
 */

import { ref, computed, onMounted, watch } from "vue";
import { useLoadingStore } from "@/stores/loading";
import { useModalStore } from "@/stores/modal";
import { useAcctMgmtStore } from "@/stores/acctMgmt";
import { useLoginStore } from "@/stores/login";
import SearchBar from "../../../components/AccountMenu/SearchBar.vue";
import i18next from "@/i18n/i18n.js";
import { useToast } from "vue-toast-notification";
import {
  MODAL_CREATE_NEW,
  MODAL_ACCT_EDIT,
  MODAL_ACCT_INFO,
  MODAL_DELETE,
  ONCE_RENDER_NUM_OF_DATA,
} from "@/constants/constants.js";
import iconDeleteGray from "@/assets/icon-delete-gray.svg";
import iconDeleteRed from "@/assets/icon-delete-red.svg";
import iconEditOff from "@/assets/icon-edit-off.svg";
import iconEditOn from "@/assets/icon-edit-on.svg";
import iconDetailOn from "@/assets/icon-detail-on.svg";
import iconDetailOff from "@/assets/icon-detail-card.svg";

const toast = useToast();
const acctMgmtStore = useAcctMgmtStore();
const loadingStore = useLoadingStore();
const modalStore = useModalStore();
const loginStore = useLoginStore();
const infiniteStart = ref(0);

const shouldUpdateList = computed(() => acctMgmtStore.shouldUpdateList);

const allAccountResponsive = computed(() => acctMgmtStore.allUserAccountList);
const infiniteAcctData = computed(() =>
  allAccountResponsive.value.slice(
    0,
    infiniteStart.value + ONCE_RENDER_NUM_OF_DATA,
  ),
);
const loginUserData = ref(null);

const isOneAccountJustCreate = computed(
  () => acctMgmtStore.isOneAccountJustCreate,
);
const justCreateUsername = computed(() => acctMgmtStore.justCreateUsername);

const inputQuery = ref("");

const fetchLoginUserData = async () => {
  await loginStore.getUserData();
  loginUserData.value = loginStore.userData;
};

const moveJustCreateUserToFirstRow = () => {
  if (infiniteAcctData.value && infiniteAcctData.value.length) {
    const index = acctMgmtStore.allUserAccountList.findIndex(
      (user) => user.username === acctMgmtStore.justCreateUsername,
    );
    if (index !== -1) {
      const justCreateUser = acctMgmtStore.allUserAccountList[index];
      infiniteAcctData.value.unshift(justCreateUser);
    }
  }
};

const accountSearchResults = computed(() => {
  if (!inputQuery.value) {
    return infiniteAcctData.value;
  }
  return acctMgmtStore.allUserAccountList.filter((user) =>
    user.username.includes(inputQuery.value),
  );
});

const onCreateNewClick = () => {
  acctMgmtStore.clearCurrentViewingUser();
  modalStore.openModal(MODAL_CREATE_NEW);
};

const onAcctDoubleClick = (username) => {
  acctMgmtStore.setCurrentViewingUser(username);
  modalStore.openModal(MODAL_ACCT_INFO);
};

const handleDeleteMouseOver = (username) => {
  acctMgmtStore.changeIsDeleteHoveredByUser(username, true);
};

const handleDeleteMouseOut = (username) => {
  acctMgmtStore.changeIsDeleteHoveredByUser(username, false);
  acctMgmtStore.changeIsRowHoveredByUser(username, false);
};

const handleRowMouseOver = (username) => {
  acctMgmtStore.changeIsRowHoveredByUser(username, true);
};

const handleRowMouseOut = (username) => {
  acctMgmtStore.changeIsRowHoveredByUser(username, false);
};

const handleEditMouseOver = (username) => {
  acctMgmtStore.changeIsEditHoveredByUser(username, true);
};

const handleEditMouseOut = (username) => {
  acctMgmtStore.changeIsEditHoveredByUser(username, false);
  acctMgmtStore.changeIsRowHoveredByUser(username, false);
};

const handleDetailMouseOver = (username) => {
  acctMgmtStore.changeIsDetailHoveredByUser(username, true);
};

const handleDetailMouseOut = (username) => {
  acctMgmtStore.changeIsDetailHoveredByUser(username, false);
  acctMgmtStore.changeIsRowHoveredByUser(username, false);
};

const onEditButtonClick = (userNameToEdit) => {
  acctMgmtStore.setCurrentViewingUser(userNameToEdit);
  modalStore.openModal(MODAL_ACCT_EDIT);
};

const onDeleteBtnClick = (usernameToDelete) => {
  acctMgmtStore.setCurrentViewingUser(usernameToDelete);
  modalStore.openModal(MODAL_DELETE);
};

const getRowClass = (curData) => {
  return curData?.isRowHovered ? "bg-[#F1F5F9]" : "";
};

const onDetailBtnClick = (dataKey) => {
  acctMgmtStore.setCurrentViewingUser(dataKey);
  modalStore.openModal(MODAL_ACCT_INFO);
};

watch(shouldUpdateList, async (newShouldUpdateList) => {
  if (newShouldUpdateList) {
    await acctMgmtStore.getAllUserAccounts();
    moveJustCreateUserToFirstRow();
  }
  acctMgmtStore.setShouldUpdateList(false);
});

const onSearchAccountButtonClick = (inputQueryString) => {
  inputQuery.value = inputQueryString;
};

const setIsActiveInput = async (userData, inputIsActiveToSet) => {
  const userDataToReplace = {
    username: userData.username,
    name: userData.name,
    is_active: inputIsActiveToSet,
  };
  await acctMgmtStore.editAccount(userData.username, userDataToReplace);
  acctMgmtStore.updateSingleAccountPiniaState(userDataToReplace);
  toast.success(i18next.t("AcctMgmt.MsgAccountEdited"));
};

const onAdminInputClick = async (userData, inputIsAdminOn) => {
  const ADMIN_ROLE_NAME = "admin";
  switch (inputIsAdminOn) {
    case true:
      await acctMgmtStore.addRoleToUser(userData.username, ADMIN_ROLE_NAME);
      break;
    case false:
      await acctMgmtStore.deleteRoleToUser(userData.username, ADMIN_ROLE_NAME);
      break;
    default:
      break;
  }
  const userDataToReplace = {
    username: userData.username,
    name: userData.name,
    is_admin: inputIsAdminOn,
  };

  acctMgmtStore.updateSingleAccountPiniaState(userDataToReplace);
  toast.success(i18next.t("AcctMgmt.MsgAccountEdited"));
};

/**
 * Loads more account data when the user scrolls near the bottom.
 * @param {Event} event - The scroll event from the data grid.
 */
const handleScroll = (event) => {
  const container = event.target;
  const smallValue = 3;

  const isOverScrollHeight =
    container.scrollTop + container.clientHeight >=
    container.scrollHeight - smallValue;
  if (isOverScrollHeight) {
    fetchMoreDataVue3();
  }
};

const fetchMoreDataVue3 = () => {
  if (infiniteAcctData.value.length < acctMgmtStore.allUserAccountList.length) {
    infiniteStart.value += ONCE_RENDER_NUM_OF_DATA;
  }
};

onMounted(async () => {
  loadingStore.setIsLoading(false);
  await fetchLoginUserData();
  await acctMgmtStore.getAllUserAccounts();
});
</script>
<style>
/* Center column text so that radio buttons are also centered */
.header-center .p-column-header-content {
  justify-content: center;
}
</style>
