const MessageModel = require('../model/message');
const UserModel = require('../model/user');
const ChatModel = require('../model/chat');
const Jimp = require('jimp');
const fs = require('fs').promises;
const path = require('path');
const createFolderIsExist = require('../helpers/create-directory');
require('dotenv').config();

const listMessages = async (req, res, next) => {
	try {
		const userId = req.user.id;
		const messages = await MessageModel.getList(userId, req.query);
		return res.json({
			status: 'success',
			code: 200,
			data: {
				...messages,
			},
		});
	} catch (e) {
		next(e);
	}
};

const listMessagesById = async (req, res, next) => {
	try {
		const userId = req.user.id;
		const companionId = req.params.companionId;
		const messages = await MessageModel.getListById(companionId, userId);
		return res.json({
			status: 'success',
			code: 200,
			data: [...messages],
		});
	} catch (e) {
		next(e);
	}
};

const sentMessage = async (req, res, next) => {
	try {
		const { id, message } = req.body;
		const user = req.user;
		const userId = user.id;
		const companion = await UserModel.findById(id);
		const isChat = await ChatModel.getByField(id, userId);
		const isCompanionChat = await ChatModel.getByField(userId, id);
		const { name, lastName, avatarUrl, color, number } = user;

		if (companion && isChat && isCompanionChat) {
			const newMessage = await MessageModel.add({
				message,
				name,
				lastName,
				avatarUrl,
				color,
				number,
				type: 'text',
				companionId: id,
				owner: userId,
			});
			await MessageModel.add({
				message,
				name,
				lastName,
				avatarUrl,
				color,
				number,
				type: 'text',
				companionId: userId,
				owner: id,
			});
			const { total } = await MessageModel.getList(userId, {});
			await ChatModel.update(isChat._id, { total, seen: total });
			const { total: Total } = await MessageModel.getList(id, {});
			await ChatModel.update(isCompanionChat._id, { total: Total });
			return res.status(201).json({
				status: 'success',
				code: 201,
				data: newMessage,
			});
		}
	} catch (e) {
		next(e);
	}
};

const imageMessage = async (req, res, next) => {
	try {
		const userId = req.user.id;
		const id = req.params.companionId;
		const isChat = await ChatModel.getByField(id, userId);
		const isCompanionChat = await ChatModel.getByField(userId, id);
		const DIR_IMAGES = process.env.DIR_IMAGES;
		const pathToFile = req.file.path;
		const newNameImg = req.file.originalname;
		await Jimp.read(pathToFile);
		await createFolderIsExist(path.join(DIR_IMAGES, userId));
		await fs.rename(pathToFile, path.join(DIR_IMAGES, userId, newNameImg));
		const imgUrl = path.normalize(path.join(userId, newNameImg));
		if (isChat && isCompanionChat && imgUrl) {
			const { name, lastName, avatarUrl, color, number } = req.user;
			const newMessage = await MessageModel.add({
				message: imgUrl,
				name,
				lastName,
				avatarUrl,
				color,
				number,
				type: 'image',
				companionId: id,
				owner: userId,
			});
			await MessageModel.add({
				message: imgUrl,
				name,
				lastName,
				avatarUrl,
				color,
				number,
				type: 'image',
				companionId: userId,
				owner: id,
			});
			const { total } = await MessageModel.getList(userId, {});
			await ChatModel.update(isChat._id, { total, seen: total });
			const { total: Total } = await MessageModel.getList(id, {});
			await ChatModel.update(isCompanionChat._id, { total: Total });
			return res.status(201).json({
				status: 'success',
				code: 201,
				data: newMessage,
			});
		}
	} catch (e) {
		next(e);
	}
};

const audioMessage = async (req, res, next) => {
	try {
		const userId = req.user.id;
		const id = req.params.companionId;
		const isChat = await ChatModel.getByField(id, userId);
		const isCompanionChat = await ChatModel.getByField(userId, id);
		const DIR_AUDIOS = process.env.DIR_AUDIOS;
		const pathToFile = req.file.path;
		const newNameAudio = req.file.originalname;
		await createFolderIsExist(path.join(DIR_AUDIOS, userId));
		await fs.rename(pathToFile, path.join(DIR_AUDIOS, userId, newNameAudio));
		const audioUrl = path.normalize(path.join(userId, newNameAudio));
		if (isChat && isCompanionChat && audioUrl) {
			const { name, lastName, avatarUrl, color, number } = req.user;
			const newMessage = await MessageModel.add({
				message: audioUrl,
				name,
				lastName,
				avatarUrl,
				color,
				number,
				type: 'audio',
				companionId: id,
				owner: userId,
			});
			await MessageModel.add({
				message: audioUrl,
				name,
				lastName,
				avatarUrl,
				color,
				number,
				type: 'audio',
				companionId: userId,
				owner: id,
			});
			const { total } = await MessageModel.getList(userId, {});
			await ChatModel.update(isChat._id, { total, seen: total });
			const { total: Total } = await MessageModel.getList(id, {});
			await ChatModel.update(isCompanionChat._id, { total: Total });
			return res.status(201).json({
				status: 'success',
				code: 201,
				data: newMessage,
			});
		}
	} catch (e) {
		next(e);
	}
};

const videoMessage = async (req, res, next) => {
	try {
		const userId = req.user.id;
		const id = req.params.companionId;
		const isChat = await ChatModel.getByField(id, userId);
		const isCompanionChat = await ChatModel.getByField(userId, id);
		const DIR_VIDEOS = process.env.DIR_VIDEOS;
		const pathToFile = req.file.path;
		const newNameVideo = req.file.originalname;
		await createFolderIsExist(path.join(DIR_VIDEOS, userId));
		await fs.rename(pathToFile, path.join(DIR_VIDEOS, userId, newNameVideo));
		const videoUrl = path.normalize(path.join(userId, newNameVideo));
		if (isChat && isCompanionChat && videoUrl) {
			const { name, lastName, avatarUrl, color, number } = req.user;
			const newMessage = await MessageModel.add({
				message: videoUrl,
				name,
				lastName,
				avatarUrl,
				color,
				number,
				type: 'video',
				companionId: id,
				owner: userId,
			});
			await MessageModel.add({
				message: videoUrl,
				name,
				lastName,
				avatarUrl,
				color,
				number,
				type: 'video',
				companionId: userId,
				owner: id,
			});
			const { total } = await MessageModel.getList(userId, {});
			await ChatModel.update(isChat._id, { total, seen: total });
			const { total: Total } = await MessageModel.getList(id, {});
			await ChatModel.update(isCompanionChat._id, { total: Total });
			return res.status(201).json({
				status: 'success',
				code: 201,
				data: newMessage,
			});
		}
	} catch (e) {
		next(e);
	}
};

const fileMessage = async (req, res, next) => {
	try {
		const userId = req.user.id;
		const id = req.params.companionId;
		const isChat = await ChatModel.getByField(id, userId);
		const isCompanionChat = await ChatModel.getByField(userId, id);
		const DIR_FILES = process.env.DIR_FILES;
		const pathToFile = req.file.path;
		const newNameFile = req.file.originalname;
		await createFolderIsExist(path.join(DIR_FILES, userId));
		await fs.rename(pathToFile, path.join(DIR_FILES, userId, newNameFile));
		const fileUrl = path.normalize(path.join(userId, newNameFile));
		if (isChat && isCompanionChat && fileUrl) {
			const { name, lastName, avatarUrl, color, number } = req.user;
			const newMessage = await MessageModel.add({
				message: fileUrl,
				name,
				lastName,
				avatarUrl,
				color,
				number,
				type: 'file',
				companionId: id,
				owner: userId,
			});
			await MessageModel.add({
				message: fileUrl,
				name,
				lastName,
				avatarUrl,
				color,
				number,
				type: 'file',
				companionId: userId,
				owner: id,
			});
			const { total } = await MessageModel.getList(userId, {});
			await ChatModel.update(isChat._id, { total, seen: total });
			const { total: Total } = await MessageModel.getList(id, {});
			await ChatModel.update(isCompanionChat._id, { total: Total });
			return res.status(201).json({
				status: 'success',
				code: 201,
				data: newMessage,
			});
		}
	} catch (e) {
		next(e);
	}
};

module.exports = {
	listMessages,
	listMessagesById,
	sentMessage,
	imageMessage,
	audioMessage,
	videoMessage,
	fileMessage,
};
