import uniqid from 'uniqid';
import {isValidEmail} from "./utils/validation";
import {hideLoader, showLoader} from "./utils/loader";
import {createEvent} from "./utils/create-event";

const Handlebars = require("hbsfy/runtime");
import memberField from '../../components/account-families/member-field.hbs'
import handlebars from "gulp-compile-handlebars";

Handlebars.registerPartial('form-row', require("../../elements/form-row.hbs"));
Handlebars.registerPartial('input', require("../../elements/input.hbs"));
Handlebars.registerHelper('or', function(a, b) {
  return a || b;
});

var Wick = window.Wick || {};
Wick.AccountMembers = {
  DEFAULT_ERROR: {
    message: 'Please enter a valid TradePro email'
  },
  LIMIT_REACHED_ERROR: {
    message: 'Member limit reached'
  },
  MEMBER_ALREADY_EXIST_ERROR: {
    message: 'Member already exists'
  },
  MEMBERS_LIMIT: null,
  DEFAULT_MEMBERS_LIMIT: 10,
  HIDDEN_CLASS_NAME: 'd-none',
  VERIFY_EMAIL_EVENT: 'verifyEmail',
  VERIFY_EMAILS_EVENT: 'verifyEmails',
  GET_MEMBERS_LIMIT_EVENT: 'getMembersLimit',
  MEMBERS_NAME: 'customersEmails',
  el: {
    newMemberList: '.new-member-list__list',
    newMemberListEmpty: '.new-member-list__empty',
    memberField: '.member-field',
    emailField: '#tp-email',
    emailForm: '.new-member-form',
    errorMsgField: '.form-row__info',
    emailFormErrorClass: 'new-member-form-error',
    addMemberBtn: '.new-member-form__btn-add',
    removeMemberBtn: '.btn-remove',
    loader: '.page_add-members .content .loader-wrapper',
    cancelBtn: '.btn-cancel-adding',
    submitRequestBtn: '.btn-submit-request',
  },
  emailCheckPassed: false,
  checkEmailValue(e) {
    e.preventDefault();

    const error = Wick.AccountMembers.defineErrorType();

    error
      ? Wick.AccountMembers.showFormError(error)
      : Wick.AccountMembers.verifyEmailValue();
  },
  defineErrorType() {
    let error = false;

    if (Wick.AccountMembers.isEmailInvalid()) {
      error = Wick.AccountMembers.DEFAULT_ERROR;
    }

    if (Wick.AccountMembers.isLimitReached()) {
      error = Wick.AccountMembers.LIMIT_REACHED_ERROR;
    }

    if (Wick.AccountMembers.isMemberIsAlreadyInTheList()) {
      error = Wick.AccountMembers.MEMBER_ALREADY_EXIST_ERROR;
    }

    return error;
  },
  getEmailValue() {
    return $(Wick.AccountMembers.el.emailField).val().trim();
  },
  isEmailInvalid() {
    const email = Wick.AccountMembers.getEmailValue();
    return !isValidEmail(email);
  },
  verifyEmailValue() {
    const email = Wick.AccountMembers.getEmailValue() || '';

    showLoader(Wick.AccountMembers.el.loader);
    Wick.AccountMembers.hideFormError();

    return new Promise((resolve, reject) => {
      const payload = {
        email: email,
      }
      const eventDetail = {resolve, reject};
      const event = createEvent(Wick.AccountMembers.VERIFY_EMAIL_EVENT, payload, eventDetail);
      window.dispatchEvent(event);
    })
      .then(() => {
        Wick.AccountMembers.hideFormError();
        Wick.AccountMembers.addMemberToTheList();
      })
      .catch( (e) => {
        Wick.AccountMembers.showFormError(e)
      })
      .finally(() => {
        Wick.AccountMembers.cleanEmailField();
        hideLoader(Wick.AccountMembers.el.loader);
      })
  },
  setMembersLimit(membersLimit) {
    Wick.AccountMembers.MEMBERS_LIMIT = membersLimit;
  },
  isLimitReached() {
    const limitValue = Wick.AccountMembers.MEMBERS_LIMIT;
    const memberFieldAmount = $(Wick.AccountMembers.el.memberField).length;

    return memberFieldAmount >= limitValue;
  },
  cleanEmailField() {
    $(Wick.AccountMembers.el.emailField).val('');
  },
  addMemberToTheList() {
    Wick.AccountMembers.isMembersExist() || Wick.AccountMembers.hideEmptyListComponent();
    Wick.AccountMembers.createMember();
  },
  isMemberIsAlreadyInTheList() {
    const email = Wick.AccountMembers.getEmailValue();
    const members = $(Wick.AccountMembers.el.memberField);
    let isExist = false;

    members.each((_, el) => {
      const existEmail = $(el).find('input').val();
      if (existEmail === email) {
        isExist = true;
      }
    })

    return isExist;
  },
  createMember() {
    const memberInfo = {
      id: uniqid('member-'),
      value: Wick.AccountMembers.getEmailValue(),
      name: Wick.AccountMembers.MEMBERS_NAME
    }
    $(Wick.AccountMembers.el.newMemberList).append(
      memberField({
        id: memberInfo.id,
        value: memberInfo.value,
        name: memberInfo.name,
      })
    );
  },
  isMembersExist() {
    return !!$(Wick.AccountMembers.el.memberField).length
  },
  showEmptyListComponent() {
    $(Wick.AccountMembers.el.newMemberListEmpty).removeClass(Wick.AccountMembers.HIDDEN_CLASS_NAME);
  },
  hideEmptyListComponent() {
    $(Wick.AccountMembers.el.newMemberListEmpty).addClass(Wick.AccountMembers.HIDDEN_CLASS_NAME);
  },
  hideFormError() {
    $(Wick.AccountMembers.el.emailForm).removeClass(Wick.AccountMembers.el.emailFormErrorClass)
  },
  showFormError(error = Wick.AccountMembers.DEFAULT_ERROR) {
    $(Wick.AccountMembers.el.emailForm).addClass(Wick.AccountMembers.el.emailFormErrorClass)
    $(Wick.AccountMembers.el.errorMsgField).text(error.message);
  },
  removeMember() {
    $(this).closest(Wick.AccountMembers.el.memberField).remove();
    Wick.AccountMembers.isMembersExist() || Wick.AccountMembers.showEmptyListComponent();
  },
  checkEmailsBeforeSubmit() {
    const emails = $(Wick.AccountMembers.el.memberField).map((_, el) => $(el).find('input').val());
    new Promise((resolve, reject) => {
      const payload = {
        emails: Array.from(emails),
      }
      const eventDetail = {resolve, reject};
      const event = createEvent(Wick.AccountMembers.VERIFY_EMAILS_EVENT, payload, eventDetail);
      window.dispatchEvent(event);
      showLoader(Wick.AccountMembers.el.loader);
    })
      .then(() => {
        Wick.AccountMembers.emailCheckPassed = true;
        Wick.AccountMembers.hideFormError();
        $(Wick.AccountMembers.el.submitRequestBtn).trigger('click');
      })
      .catch(Wick.AccountMembers.showFormError)
      .finally(() => {
        hideLoader(Wick.AccountMembers.el.loader);
      })
  },
  submitNewMembers(e) {
    if(!Wick.AccountMembers.emailCheckPassed) {
      e.preventDefault();
      Wick.AccountMembers.checkEmailsBeforeSubmit();
      return;
    }

    if (Wick.AccountMembers.isMembersExist()) {
      Wick.ClickDisable.disable(e.target);
      Wick.LeaveEvent.removeLeaveEvent();
    } else {
      e.preventDefault();
      Wick.AccountMembers.showFormError();
    }
  },
  init(payload) {
    Wick.AccountMembers.emailCheckPassed = false;
    hideLoader();
    const membersLimit = payload?.membersLimit || Wick.AccountMembers.DEFAULT_MEMBERS_LIMIT;
    Wick.AccountMembers.setMembersLimit(membersLimit);

    Wick.LeaveEvent.bindEvent(Wick.AccountMembers.el.newMemberList, Wick.AccountMembers.el.cancelBtn);
    $(Wick.AccountMembers.el.emailForm).on('submit', Wick.AccountMembers.checkEmailValue);
    $(Wick.AccountMembers.el.newMemberList).on(
      'click',
      Wick.AccountMembers.el.removeMemberBtn,
      Wick.AccountMembers.removeMember
    );
    $(Wick.AccountMembers.el.submitRequestBtn).on('click', Wick.AccountMembers.submitNewMembers);
  }
};
