<template>
  <ElForm
    ref="signInForm"
    :model="signInForm"
    :rules="rules"
    name="auth-form"
    label-position="top"
    class="auth-form sign-in"
    data-test="sign-in form"
    @submit.native.prevent
  >
    <AuthPageHeader title="Sign In to ThreeFlow" />
    <div class="inputs-container">
      <ElFormItem
        v-if="!hideEmail"
        for="app-sign-in-email"
        prop="email"
        class="email-container"
        label="Company email"
        size="medium"
      >
        <!-- Changing `autofilledPassword` for both inputs is required for disabling the button -->
        <ElInput
          id="app-sign-in-email"
          v-model="signInForm.email"
          data-test="edit sign in email"
          name="email-input"
          placeholder="Enter email"
          @keydown.native="autofilledPassword = false"
        />
      </ElFormItem>
      <template v-if="!showSsoMethod">
        <ElFormItem
          for="app-sign-in-password"
          prop="password"
          class="password-container"
          label="Password"
          size="medium"
        >
          <ElInput
            id="app-sign-in-password"
            v-model="signInForm.password"
            data-test="edit sign in password"
            :type="signInForm.showPassword ? 'text' : 'password'"
            name="password-input"
            placeholder="Enter password"
            @animationstart.native="checkAnimation($event)"
            @keydown.native="autofilledPassword = false"
          >
            <AppButton
              slot="append"
              icon="fa-solid fa-eye"
              size="icon-small"
              class="toggle-password"
              no-branding
              :data-test="`${signInForm.showPassword ? 'hide' : 'show'} password`"
              @click="signInForm.showPassword = !signInForm.showPassword"
            />
          </ElInput>
        </ElFormItem>
        <!-- Checkbox row -->
        <div class="remember-me">
          <TfCheckbox
            v-model="signInForm.rememberMe"
            name="remember-user"
            label="Remember me"
            data-test="toggle remember me"
          />
        </div>
        <!-- Submit Btn -->
        <slot name="ctaSubmit">
          <AppButton
            :is-disabled="!validFields && !autofilledPassword"
            data-test="submit sign in"
            name="submit-button"
            type="primary"
            native-type="submit"
            text="Sign in"
            no-branding
            is-block
          />
        </slot>
        <!-- terms -->
        <p
          v-if="linkTerms"
          class="terms-of-use"
        >
          By signing in, you agree to
          <RouterLink
            :to="linkTerms"
            target="_blank"
            data-test="to terms of use"
            v-text="'Terms of use'"
          />.
        </p>
        <!-- Extra CTAs -->
        <RouterLink
          v-if="linkForgot"
          :to="linkForgot"
        >
          <AppButton
            id="link-forgot-password"
            type="secondary"
            data-test="to forgot password form"
            text="Forgot password?"
            no-branding
            is-block
          />
        </RouterLink>
        <RouterLink
          v-if="linkRegister"
          :to="linkRegister"
        >
          <AppButton
            type="secondary"
            data-test="to create account form"
            text="Create an account"
            no-branding
            is-block
          />
        </RouterLink>
      </template>
      <div
        v-if="showSsoMethod && $slots.ctaSsoSubmit"
      >
        <slot name="ctaSsoSubmit" />
      </div>
    </div>
    <AuthPageFooter />
  </ElForm>
</template>

<script>
  /**
   * Shared sign in component with functionality to slot in secondary sign-in methods.
   *
   * @exports AppSignIn
   * @category Components
   */
  export default {
    name: 'AppSignIn',
    props: {
      /**
       * URL for the forgot password link
       */
      linkForgot: {
        type: [String, Object],
        default: '',
      },
      /**
       * URL for the account registration link
       */
      linkRegister: {
        type: [String, Object],
        default: '',
      },
      /**
       * URL for the terms & conditions link
       */
      linkTerms: {
        type: [String, Object],
        default: '',
      },
      /**
       * userInfo object from a store to show current email (if needed)
       */
      userInfo: {
        type: Object,
        default: () => ({}),
      },
      /**
       * Determine whether or not to hide the password field and show the SSO method slot
       */
      showSsoMethod: {
        type: Boolean,
        default: false,
      },
      /**
       * Determine if email field is hidden or not (this is used for use cases where the SSO method is the only sign in method allowed.)
       */
      hideEmail: {
        type: Boolean,
        default: false,
      },
    },
    data: (vm) => ({
      autofilledPassword: false,
      signInForm: {
        email: '',
        password: '',
        rememberMe: false,
        showPassword: false,
      },
      rules: {
        email: [
          {
            required: true,
            type: 'email',
            message: 'Please enter your company email.',
            trigger: 'blur',
          },
          {
            validator: vm.clearError,
            trigger: 'change',
          },
        ],
        password: [
          {
            required: true,
            message: 'Please input your password.',
            trigger: 'none',
          },
        ],
      },
    }),
    computed: {
      /**
       * If the user has provided both their email and password
       *
       * @returns {boolean}
       */
      validFields() {
        return Boolean(this.signInForm.email && this.signInForm.password);
      },
    },
    watch: {
      /**
       * Watching to see if we need show the inactivity message
       *
       * @param {boolean} inactivity
       */
      /**
       * Watch the "email" field to emit synced values,
       *
       * @param {string} email
       */
      'signInForm.email': function (email) {
        this.$emit('update:email', email);
      },
      /**
       * Watch the "password" field to emit synced values,
       *
       * @param {string} password
       */
      'signInForm.password': function (password) {
        this.$emit('update:password', password);
      },
      /**
       * Watch the "remember me" checkbox to emit synced values.
       *
       * @param {string} value
       */
      'signInForm.rememberMe': function (value) {
        this.$emit('update:rememberMe', value);
      },
    },
    created() {
      const { email, pw } = this.$route.query;

      if (email && pw) {
        this.signInForm.email = email;
        this.signInForm.password = pw;
        this.signInForm.showPassword = true;

        return;
      }

      // We want the email address to persist across all sign in/forgotPW/registration forms
      this.signInForm.email = this.userInfo.email;
      const savedEmail = window.localStorage.getItem('email');

      if (savedEmail) {
        this.signInForm.rememberMe = true;
      }
      // if we don't have an email already check if we "remembered one"
      if (!this.signInForm.email && savedEmail) {
        this.signInForm.email = savedEmail;
      }
    },
    methods: {
      /**
       * there is a chrome bug that doesn't fire a change event when a field is auto filled
       * we can however check the animation change from being auto filled
       * however we still can't access the value of the password field
       * but since we know it was autofilled lets just enable the button
       *
       * @param {event} e
       */
      checkAnimation(e) {
        if (e.animationName === 'onAutoFillStart') {
          this.autofilledPassword = true;
        }
      },

      /* eslint-disable-next-line jsdoc/require-param */
      /**
       * Clear out any displayed errors
       */
      clearError(rule, value, callback) {
        callback();
      },
    },
  };
</script>

<style lang="scss" scoped>
  .auth-form {
    .el-form-item {
      margin-bottom: 16px;
    }
  }

  #link-forgot-password {
    margin-bottom: 30px;
  }

  .remember-me {
    display: flex;
    margin: 8px 0 24px;
  }

  .terms-of-use {
    margin: 24px 0;
  }

  .toggle-password {
    padding: {
      top: 5px !important; // stylelint-disable-line
      bottom: 5px !important; // stylelint-disable-line
    }
  }
</style>

<style>
  .forgot-pw-message {
    max-width: 690px;
  }

  :-webkit-autofill {
    animation-name: onAutoFillStart;
  }

  :not(:-webkit-autofill) {
    animation-name: onAutoFillCancel;
  }

  /* stylelint-disable block-no-empty  */
  @keyframes onAutoFillStart {
  }
  @keyframes onAutoFillCancel {
  }
  /* stylelint-enable block-no-empty  */
</style>
