import { userDb } from "../db";
import { asyncWrap } from "../helpers/asyncWrap";
import { Request } from "express";
import formidable from "formidable";
import fs from "fs/promises";
import { TypedRequest } from "../types";
import { FileInfo, IUser, User } from "../models";

export interface TypedRequestAuth<T> extends Request {
  auth: T;
}

export const getUsers = asyncWrap(async (req, res) => {
  const users = await userDb.getUsers();
  return res.json(users);
});

export const createUser = asyncWrap(async (req, res) => {
  const user = req.body;
  console.log("user body", user);
  const newUser = await userDb.createUser(user);
  return res.json(newUser);
});

export const getProfile = asyncWrap(async (reqExp, res) => {
  const req = reqExp as TypedRequestAuth<{ userId: string }>; // 앞에서는 토큰으로써 사용하기 때문에 JwtPayload 를 사용하고 여기서는 verify 에서 토큰을 디코딩했기에 ObjectId 타입의 string으로 바뀌게 된다.

  const { userId } = req.auth;
  const profile = await userDb.getProfile(userId);
  res.json(profile);
});

export const updateProfile = asyncWrap(async (reqExp, res) => {
  const req = reqExp as TypedRequest;
  const { userId } = req.auth;
  const { name } = req.body;
  const { avatar }: { avatar: formidable.File } = req.files;

  const duplicate = await FileInfo.findOne({
    originalfilename: avatar.originalFilename,
  }); // 같은 사진이 DB에 있는지 확인

  console.log(duplicate);
  if (!duplicate) {
    //만약 같은 사진이 DB안에 존재하지 않을 경우
    const user = await userDb.updateProfile(userId, name, avatar);

    res.json(user);
  } else {
    // 같은 사진이 DB안에 존재할 경우
    await fs.unlink(avatar.filepath);
    // 덮기 전의 FileInfo 삭제
    // await FileInfo.deleteOne({ _id: user?.avatar });
    const user = await User.findById(userId);
    if (user !== null) {
      user.avatar = duplicate._id;
      await user.save();
    }
  }
});

export const deleteUser = asyncWrap(async (reqExp, res) => {
  const req = reqExp as TypedRequestAuth<{ userId: string }>; // 앞에서는 토큰으로써 사용하기 때문에 JwtPayload 를 사용하고 여기서는 verify 에서 토큰을 디코딩했기에 ObjectId 타입의 string으로 바뀌게 된다.

  const { userId } = req.auth;
  const finish = await userDb.deleteUser(userId);
  if (finish?.deletedCount === 1) {
    res.json(true);
  } else {
    res.status(422).send("삭제에 실패하였습니다.");
  }
});
