import * as Yup from "yup";

import AppError from "../../errors/AppError";
import { SerializeUser } from "../../helpers/SerializeUser";
import User from "../../models/User";
import ShowUserService from "./ShowUserService";

interface Request {
  email: string;
  password: string;
  name: string; 
  positionId?: string;
  queueIds?: number[];
  profile?: string;
  ignoreThrow?: boolean;
  transferToOtherQueues?: boolean;
}

interface Response {
  email: string;
  name: string; 
  positionId: string;
  id: number;
  profile: string;
  transferToOtherQueues: boolean;
}

const CreateUserService = async ({
  email,
  password,
  name, 
  positionId,
  queueIds = [],
  profile = "master",
  ignoreThrow = false,
  transferToOtherQueues
}: Request): Promise<Response | any> => {
  try {
    const schema = Yup.object().shape({
      name: Yup.string().required().min(2),

      email: Yup.string()
        .required()
        .trim()
        .test(
          "Check-email",
          "An user with this email already exists.",
          async value => {
            if (!value) return false;
            const emailExists = await User.findOne({
              where: { email: value }
            });
            return !emailExists;
          }
        ),

      // email: Yup.string().email().required().test(
      //     "Check-email",
      //     "An user with this email already exists.",
      //     async value => {
      //       if (!value) return false;
      //       const emailExists = await User.findOne({
      //         where: { email: value }
      //       });
      //       return !emailExists;
      //     }
      //   ),

      password: Yup.string().required().min(5)
    });

    try {
      await schema.validate({ email, password, name });
    } catch (err: any) {
      if (ignoreThrow) return { error: true, msg: err.message, status: 400 };

      throw new AppError(err.message);
    }

    const user = await User.create(
      {
        email,
        password,
        name, 
        positionId: !positionId ? null : positionId,
        profile,
        transferToOtherQueues: transferToOtherQueues? transferToOtherQueues : false
      },
      { include: ["queues"] }
    );

    await user.$set("queues", queueIds);

    await user.reload();

    const _user = await ShowUserService(user.id);

    const serializedUser = SerializeUser(_user);

    return serializedUser;
  } catch (error: any) {
    console.error("===> Error on CreateUserService.ts file: \n", error);

    if (ignoreThrow)
      return { error: true, msg: "Create user error", status: 500 };

    throw new AppError(error.message);
  }
};

export default CreateUserService;
