import { RootState } from "app/store";
import { USER_ROLES } from "components/auth/constants";
import { RoleType, UserView, isLicenseStatusType, isRoleType } from "./types";
import { LICENSE_STATUS } from "./constants";

export const selectInputValidationErrors = (state: RootState) => {
  const { name, email, role, authorId } = state.user.apps.addUser;

  // 必須項目のチェック
  const hasErrorEmptyName = name === "";
  const hasErrorEmptyEmail = email === "";
  const hasErrorEmptyAuthorId = role === USER_ROLES.AUTHOR && authorId === "";

  const hasErrorIncorrectAuthorId = checkErrorIncorrectAuthorId(
    authorId ?? undefined,
    role
  );

  const hasErrorIncorrectEmail = email.match(/^[^@]+@[^@]+$/)?.length !== 1;

  return {
    hasErrorEmptyName,
    hasErrorEmptyEmail,
    hasErrorEmptyAuthorId,
    hasErrorIncorrectEmail,
    hasErrorIncorrectAuthorId,
  };
};
export const checkErrorIncorrectAuthorId = (
  authorId: string | undefined,
  role: string
): boolean => {
  if (!authorId || role !== USER_ROLES.AUTHOR) {
    return false;
  }

  // 半角英数字と_の組み合わせで１６文字まで
  const charaTypePattern = /^[A-Z0-9_]{1,16}$/;
  const charaType = new RegExp(charaTypePattern).test(authorId);

  return !charaType;
};

export const selectName = (state: RootState) => state.user.apps.addUser.name;
export const selectEmail = (state: RootState) => state.user.apps.addUser.email;
export const selectRole = (state: RootState) => state.user.apps.addUser.role;
export const selectAuthorId = (state: RootState) =>
  state.user.apps.addUser.authorId;
export const selectTypistGroupId = (state: RootState) =>
  state.user.apps.addUser.typistGroupId;
export const selectAutoRenew = (state: RootState) =>
  state.user.apps.addUser.autoRenew;
export const selectLicenseAlert = (state: RootState) =>
  state.user.apps.addUser.licenseAlert;
export const selectNtotification = (state: RootState) =>
  state.user.apps.addUser.notification;
// usersからUserViewに変換して返却する
export const selectUserViews = (state: RootState): UserView[] => {
  const { users } = state.user.domain;
  const userViews = users.map((user): UserView => {
    const {
      role,
      authorId,
      encryption,
      prompt,
      typistGroupName,
      licenseStatus,
      expiration,
      remaining,
      ...rest
    } = user;
    // roleの型がstringなので、isRoleTypeで型ガードを行う
    // roleの型がRoleTypeでなければ、何も返さない
    if (!isRoleType(role) || !isLicenseStatusType(licenseStatus)) {
      return {} as UserView;
    }
    const convertedValues = convertValueBasedOnRole(
      role,
      authorId,
      encryption,
      prompt,
      typistGroupName
    );
    // restのid以外をUserViewに追加する
    return {
      typistGroupName: convertedValues.typistGroupName,
      prompt: convertedValues.prompt,
      encryption: convertedValues.encryption,
      authorId: convertedValues.authorId,
      // roleの一文字目を大文字に変換する
      role: role.charAt(0).toUpperCase() + role.slice(1),
      licenseStatus:
        licenseStatus === LICENSE_STATUS.NORMAL ? "-" : licenseStatus,
      expiration: expiration ?? "-",
      remaining: remaining ?? "-",
      ...rest,
    };
  });
  // 空のオブジェクトを除外する
  return userViews.filter((userView) => Object.keys(userView).length !== 0);
};

export const selectIsLoading = (state: RootState) => state.user.apps.isLoading;

// roleに応じて値を変換する
const convertValueBasedOnRole = (
  role: RoleType,
  authorId: string | undefined,
  encryption: boolean,
  prompt: boolean,
  typistGroupName: string[]
): {
  authorId: string;
  encryption: boolean | string;
  prompt: boolean | string;
  typistGroupName: string[] | string;
} => {
  if (role === USER_ROLES.AUTHOR && authorId) {
    return {
      authorId,
      encryption,
      prompt,
      typistGroupName: "-",
    };
  }
  if (role === USER_ROLES.TYPIST) {
    return {
      authorId: "-",
      encryption: "-",
      prompt: "-",
      typistGroupName,
    };
  }
  return {
    authorId: "-",
    encryption: "-",
    prompt: "-",
    typistGroupName: "-",
  };
};
