<template>
  <div
    id="modal_account_edit_or_create_new"
    class="w-[640px] bg-[#FFFFFF] rounded shadow-lg flex flex-col"
  >
    <ModalHeader :headerText="modalTitle" />

    <main class="flex row min-h-[96px] my-[32px] flex-col px-6">
      <div
        class="input-row w-full flex py-2 h-[40px] mb-4 items-center justify-between"
      >
        <div
          class="field-label text-sm flex items-center font-medium justify-end"
        >
          <span class="align-right-span flex w-[122px] justify-end">
            {{ i18next.t("AcctMgmt.Account") }}
          </span>
        </div>
        <div class="input-and-error flex flex-col">
          <input
            id="input_account_field"
            class="w-[454px] rounded p-1 border border-[1px] border-[#64748B] flex items-center h-[40px] outline-none"
            v-model="inputUserAccount"
            :class="{
              'text-[#000000]': isAccountUnique,
              'text-[#FF3366]': !isAccountUnique,
              'border-[#FF3366]': !isAccountUnique,
            }"
            :readonly="!isEditable"
            autocomplete="off"
            @dblclick="onInputDoubleClick"
          />
          <div v-show="!isAccountUnique" class="error-wrapper my-2">
            <div class="error-msg-section flex justify-start">
              <img
                src="@/assets/icon-alert.svg"
                alt="!"
                class="exclamation-img flex mr-2"
              />
              <span class="error-msg-text flex text-[#FF3366] h-[24px]">
                {{ i18next.t("AcctMgmt.AccountNotUnique") }}
              </span>
            </div>
          </div>
        </div>
      </div>
      <div
        class="input-row w-full flex py-2 h-[40px] mb-4 items-center justify-between"
      >
        <div
          class="field-label text-sm flex items-center font-medium justify-end"
        >
          <span class="align-right-span flex w-[122px] justify-end">
            {{ i18next.t("AcctMgmt.FullName") }}
          </span>
        </div>
        <input
          id="input_name_field"
          class="w-[454px] rounded p-1 border border-[1px] border-[#64748B] flex items-center h-[40px] outline-none"
          v-model="inputName"
          :readonly="!isEditable"
          @dblclick="onInputDoubleClick"
          @focus="onInputNameFocus"
          autocomplete="off"
        />
      </div>
      <div
        v-show="!isSSO"
        class="input-row w-full flex py-2 mb-4 items-center justify-between"
      >
        <div
          class="field-label text-sm flex flex-col items-start font-medium justify-end"
          :class="{
            'h-[100px]': whichCurrentModal !== MODAL_CREATE_NEW,
          }"
        >
          <!-- Layout of Password field changes depending on whether this is the create or edit modal -->
          <span
            class="align-right-span flex h-full w-[122px] justify-end"
            :class="{
              'pt-[12px]': whichCurrentModal !== MODAL_CREATE_NEW,
              'text-top': whichCurrentModal !== MODAL_CREATE_NEW,
              'h-[40px]': whichCurrentModal === MODAL_CREATE_NEW,
              'items-center': whichCurrentModal === MODAL_CREATE_NEW,
            }"
          >
            {{ i18next.t("AcctMgmt.Password") }}
          </span>
          <span
            v-if="whichCurrentModal === MODAL_CREATE_NEW"
            class="dummy-cell flex w-[122px] h-[40px]"
          >
          </span>
        </div>
        <div
          class="reset-btn-and-input-pwd-and-error flex flex-col"
          :class="{ 'h-[100px]': whichCurrentModal !== MODAL_CREATE_NEW }"
        >
          <div
            v-if="whichCurrentModal !== MODAL_CREATE_NEW"
            class="flex account-edit-section justify-start w-[454px]"
          >
            <button
              class="flex w-[85px] h-[40px] reset-btn rounded-full border-[1px] border-[#666666] cursor-pointer items-center justify-center hover:text-[#0099FF] hover:border-[#0099FF] mb-[20px]"
              @click="onResetPwdButtonClick"
            >
              {{ i18next.t("AcctMgmt.Reset") }}
            </button>
          </div>
          <div
            v-if="
              whichCurrentModal === MODAL_CREATE_NEW || isResetPwdSectionShow
            "
            class="w-[454px] flex flex-col input-and-error-msg"
          >
            <div
              class="input-and-eye flex items-center w-full h-[40px] relative border-[1px] rounded"
              :class="{
                'border-[#FF3366]': !isPwdLengthValid,
                'border-[#64748B]': isPwdLengthValid,
              }"
            >
              <input
                id="input_first_pwd"
                class="outline-none p-1 w-[352px]"
                :type="isPwdEyeOn ? 'text' : 'password'"
                v-model="inputPwd"
                :readonly="!isEditable"
                @dblclick="onInputDoubleClick"
                autocomplete="off"
                :class="{
                  'color-[#FF3366]': !isPwdLengthValid,
                  'color-[#64748B]': isPwdLengthValid,
                }"
              />
              <img
                id="eye_button"
                v-if="isPwdEyeOn"
                src="@/assets/icon-eye-open.svg"
                class="absolute right-[8px] cursor-pointer"
                @mousedown="togglePwdEyeBtn(true)"
                @mouseup="togglePwdEyeBtn(false)"
                alt=""
              />
              <img
                v-else
                src="@/assets/icon-eye-hide.svg"
                class="absolute right-[8px] cursor-pointer"
                @mousedown="togglePwdEyeBtn(true)"
                @mouseup="togglePwdEyeBtn(false)"
                alt="eye"
              />
            </div>
            <div class="error-msg-section flex justify-start mt-4">
              <img
                v-show="!isPwdLengthValid"
                src="@/assets/icon-alert.svg"
                alt="!"
                class="exclamation-img flex mr-2"
              />
              <span class="error-msg-text flex text-[#FF3366] h-[24px]">
                {{
                  isPwdLengthValid
                    ? ""
                    : i18next.t("AcctMgmt.PwdLengthNotEnough")
                }}
              </span>
            </div>
          </div>
        </div>
      </div>
      <div
        v-if="whichCurrentModal === MODAL_CREATE_NEW"
        class="checkbox-row w-full grid-cols-[122px_1fr] gap-x-4 flex py-2 h-[40px] my-4 items-center"
      >
        <div class="dummy field-label flex items-center w-[122px]"></div>
        <!-- A dummy field is also used here to maintain spacing -->
        <section id="account_create_checkboxes_section" class="flex flex-col">
          <div class="checkbox-and-text flex">
            <IconChecked
              :isChecked="isSetAsAdminChecked"
              @click="toggleIsAdmin"
            />
            <span class="flex checkbox-text">
              {{ i18next.t("AcctMgmt.SetAsAdmin") }}
            </span>
          </div>
          <div class="checkbox-and-text flex">
            <IconChecked
              :isChecked="isSetActivedChecked"
              @click="toggleIsActivated"
            />
            <span class="flex checkbox-text">
              {{ i18next.t("AcctMgmt.ActivateNow") }}
            </span>
          </div>
        </section>
      </div>
    </main>
    <footer class="flex row footer justify-end pr-[32px] pb-8">
      <button
        class="cancel-btn rounded-full w-[92px] h-10 px-2.5 py-6 border border-[1px] border-[#64748B] flex justify-center items-center text-[#4E5969] font-medium hover:bg-[#64748B] hover:border-[#CBD5E1] hover:text-[#FFFFFF]"
        @click="onCancelBtnClick"
      >
        {{ i18next.t("Global.Cancel") }}
      </button>
      <button
        class="confirm-btn rounded-full w-[92px] h-10 px-2.5 py-6 flex justify-center items-center text-[#ffffff] font-medium ml-[16px]"
        @click="onConfirmBtnClick"
        :disabled="isConfirmDisabled"
        :class="{
          'bg-[#0099FF]': !isConfirmDisabled,
          'bg-[#E2E8F0]': isConfirmDisabled,
        }"
      >
        {{ i18next.t("Global.Confirm") }}
      </button>
    </footer>
  </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/ModalAccountEditCreate Modal
 *   for creating new accounts or editing existing accounts with
 *   username, name, password fields and validation.
 */

import { computed, ref, watch } from "vue";
import i18next from "@/i18n/i18n.js";
import { useModalStore } from "@/stores/modal";
import { useRouter } from "vue-router";
import { useToast } from "vue-toast-notification";
import { useAcctMgmtStore } from "@/stores/acctMgmt";
import ModalHeader from "./ModalHeader.vue";
import IconChecked from "@/components/icons/IconChecked.vue";
import {
  MODAL_CREATE_NEW,
  MODAL_ACCT_EDIT,
  PWD_VALID_LENGTH,
} from "@/constants/constants.js";

const acctMgmtStore = useAcctMgmtStore();
const modalStore = useModalStore();

const router = useRouter();
const toast = useToast();

const currentViewingUser = computed(() => acctMgmtStore.currentViewingUser);
const isPwdEyeOn = ref(false);
const isConfirmDisabled = ref(true);
const isPwdLengthValid = ref(true);
const isResetPwdSectionShow = ref(false);

const isSetAsAdminChecked = ref(false);
const isSetActivedChecked = ref(true);

const whichCurrentModal = computed(() => modalStore.whichModal);

const isSSO = computed(() => acctMgmtStore.currentViewingUser.is_sso);
const username = computed(() => acctMgmtStore.currentViewingUser.username);
const name = computed(() => acctMgmtStore.currentViewingUser.name);

const inputUserAccount = ref(
  whichCurrentModal.value === MODAL_CREATE_NEW
    ? ""
    : currentViewingUser.value.username,
);
const inputName = ref(
  whichCurrentModal.value === MODAL_CREATE_NEW
    ? ""
    : currentViewingUser.value.name,
);
const inputPwd = ref("");
const isAccountUnique = ref(true);
const isEditable = ref(true);

// Since adding this watch, filling in the password field no longer clears the account or full name fields.
watch(whichCurrentModal, (newVal) => {
  if (newVal === MODAL_CREATE_NEW) {
    inputUserAccount.value = "";
    inputName.value = "";
  } else {
    inputUserAccount.value = currentViewingUser.value.username;
    inputName.value = currentViewingUser.value.name;
  }
});

const modalTitle = computed(() => {
  return modalStore.whichModal === MODAL_CREATE_NEW
    ? i18next.t("AcctMgmt.CreateNew")
    : i18next.t("AcctMgmt.AccountEdit");
});

const togglePwdEyeBtn = (toBeOpen) => {
  isPwdEyeOn.value = toBeOpen;
};

const validatePwdLength = () => {
  isPwdLengthValid.value =
    !isResetPwdSectionShow.value || inputPwd.value.length >= PWD_VALID_LENGTH;
};

const onInputDoubleClick = () => {
  // Enable edit mode
  isEditable.value = true;
};

const onConfirmBtnClick = async () => {
  // rule for minimum length
  validatePwdLength();
  if (!isPwdLengthValid.value) {
    return;
  }

  // rule for account uniqueness
  switch (whichCurrentModal.value) {
    case MODAL_CREATE_NEW:
      await checkAccountIsUnique();
      if (!isAccountUnique.value) {
        return;
      }
      await acctMgmtStore.createNewAccount({
        username: inputUserAccount.value,
        password: inputPwd.value === undefined ? "" : inputPwd.value,
        name: inputName.value,
        is_admin: isSetAsAdminChecked.value,
        is_active: isSetActivedChecked.value,
      });
      toast.success(i18next.t("AcctMgmt.MsgAccountAdded"));
      modalStore.closeModal();
      acctMgmtStore.setShouldUpdateList(true);
      await router.push("/account-admin");
      break;
    case MODAL_ACCT_EDIT:
      await checkAccountIsUnique();
      if (!isAccountUnique.value) {
        return;
      }
      // Note that the old username and new username can be different
      // Distinguish between cases with and without a password
      if (isResetPwdSectionShow.value) {
        await acctMgmtStore.editAccount(currentViewingUser.value.username, {
          newUsername: inputUserAccount.value,
          password: inputPwd.value,
          name: inputName.value === undefined ? "" : inputName.value,
          is_active: true,
        });
      } else {
        await acctMgmtStore.editAccount(currentViewingUser.value.username, {
          newUsername: inputUserAccount.value,
          name: inputName.value === undefined ? "" : inputName.value,
          is_active: true,
        });
      }
      toast.success(i18next.t("AcctMgmt.MsgAccountEdited"));
      isEditable.value = false;
      break;
    default:
      break;
  }
};

const checkAccountIsUnique = async () => {
  // If the user has not modified the field, no backend API call is needed
  if (inputUserAccount.value === username.value) {
    return true;
  }
  const isAccountAlreadyExistAPISuccess = await acctMgmtStore.getUserDetail(
    inputUserAccount.value,
  );
  isAccountUnique.value = !isAccountAlreadyExistAPISuccess;
  return isAccountUnique.value;
};

const toggleIsAdmin = () => {
  if (isEditable.value) {
    isSetAsAdminChecked.value = !isSetAsAdminChecked.value;
  }
};

const toggleIsActivated = () => {
  if (isEditable.value) {
    isSetActivedChecked.value = !isSetActivedChecked.value;
  }
};

const onInputNameFocus = () => {
  if (isConfirmDisabled.value) {
    isConfirmDisabled.value = false;
  }
};

const onResetPwdButtonClick = () => {
  isResetPwdSectionShow.value = !isResetPwdSectionShow.value;
  // Must clear the password input field
  inputPwd.value = "";
};

watch(
  [inputPwd, inputUserAccount, inputName],
  ([newPwd, newAccount, newName]) => {
    // Enable the confirm button when all fields are non-empty
    if (newAccount.length > 0 && newName.length > 0) {
      isConfirmDisabled.value = false;
    }
    if (whichCurrentModal.value !== MODAL_CREATE_NEW) {
      if (isResetPwdSectionShow.value && newPwd.length < PWD_VALID_LENGTH) {
        isConfirmDisabled.value = true;
      }
    } else {
      if (newPwd.length < PWD_VALID_LENGTH) {
        isConfirmDisabled.value = true;
      }
    }
  },
);

function onCancelBtnClick() {
  modalStore.closeModal();
}
</script>
<style>
#modal_account_edit {
  background-color: #ffffff;
  backdrop-filter: opacity(
    1
  ); /* Prevent child elements from inheriting parent's opacity */
}
</style>
