import * as Yup from "yup";

import AppError from "../../errors/AppError";
import ShowUserService from "./ShowUserService";
import User from "../../models/User";

interface UserData {
  email?: string;
  password?: string;
  name?: string;
  profile?: string;
  queueIds?: number[];
}

interface Request {
  userData: UserData;
  userId: string | number;
}

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

const UpdateUserService = async ({
  userData,
  userId
}: Request): Promise<Response | undefined> => {

  try {

    const user = await ShowUserService(userId);

    const schema = Yup.object().shape({
      name: Yup.string().min(2),
      // email: Yup.string().min(2),  
      profile: Yup.string(),
      password: Yup.string(),

      email: Yup.string().trim().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 }, raw: true, attributes: ['email', 'id'] });

          if (emailExists && user.id != emailExists?.id) {

            console.error('The email already exists in another user profile!')
            return !emailExists;
          }

          return true
        }
      ),

    });

    const { email, password, profile, name, queueIds = [] } = userData;

    try {
      await schema.validate({ email, password, profile, name });
    } catch (err: any) {
      throw new AppError(err.message);
    }


    await user.update({
      email,
      password,
      profile,
      name
    });

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

    await user.reload();

    const serializedUser = {
      id: user.id,
      name: user.name,
      email: user.email,
      profile: user.profile,
      queues: user.queues
    };

    return serializedUser;

  } catch (error: any) {
    console.error('===> Error on UpdateUserService.ts file: \n', error)
    throw new AppError(error.message);
  }


};

export default UpdateUserService;