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; 
  positionId?: string;
  profile?: string;
  queueIds?: number[];
  transferToOtherQueues?: boolean;
}

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

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

const UpdateUserService = async ({
  userData,
  userId,
  ignoreThrow = false
}: Request): Promise<Response | undefined | any> => {
  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, 
      positionId,
      queueIds = [],
      transferToOtherQueues
    } = userData;

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

    await user.update({
      email,
      password,
      profile, 
      positionId: !positionId ? null : positionId,
      name,
      transferToOtherQueues
    });

    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,
    //   positionId: user?.positionId
    // };

    // return serializedUser;

    const _user = await ShowUserService(user.id);

    const serializedUser = {
      id: _user.id,
      name: _user.name,
      email: _user.email,
      profile: _user.profile,
      queues: _user.queues,
      positionId: _user?.positionId,
      position: _user.position,
      transferToOtherQueues: _user.transferToOtherQueues
    };

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

    if (ignoreThrow)
      return {
        error: true,
        msg: err.message,
        status: 500
      };

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

export default UpdateUserService;
