import {query} from '../db.js';
import path from 'path';
import fs from 'fs';
import {fileURLToPath} from 'url';
import {fileTypeFromBuffer} from 'file-type';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const AVATAR_DIR = path.join(__dirname, '../avatar');
const DEFAULT_AVATAR = '/avatar/default.png';
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5mb
const ALLOWED_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];

// Verify that the avatar folder already exists
if (!fs.existsSync(AVATAR_DIR))
{
	fs.mkdirSync(AVATAR_DIR, { recursive: true });
}

async function uploadAvatar(userId, file)
{
	try
	{
		// File check (type and size)
		if (!file)
			return ({status: 400, data: {error: 'No file provided'}});

		if (!ALLOWED_TYPES.includes(file.mimetype))
			return ({status: 400, data: { error: 'Invalid file type. Only JPEG, PNG, GIF, and WebP allowed'}});

		const fileType = await fileTypeFromBuffer(file.buffer);
		if (!fileType || !['image/jpeg', 'image/png', 'image/gif', 'image/webp'].includes(fileType.mime))
			return ({status: 400, data: {error: 'Invalid file content. File does not match allowed image types'}});

		if (file.size > MAX_FILE_SIZE)
			return ({status: 400, data: {error: 'File too large. Maximum size is 5MB'}});


		const currentAvatar = await getCurrentAvatar(userId);
		if (currentAvatar === null)
			return ({status: 404, data: {error: 'User not found'}});

		// Create a unique name for the new avatar to avoid duplicates
		const fileExt = path.extname(file.originalname);
		const fileName = `user_${userId}_${Date.now()}${fileExt}`;
		const avatarPath = `/avatar/${fileName}`;

		// Save the new avatar in the folder
		const filePath = path.join(AVATAR_DIR, fileName);
		fs.writeFileSync(filePath, file.buffer);

		await setAvatar(avatarPath, userId);

		deleteNonDefault(currentAvatar);
		return ({status: 200, data: {avatar_url: avatarPath}});
	}
	catch (err)
	{
		console.error('Avatar upload error:', err);
		return { status: 500, data: { error: 'Server error' } };
	}
}

async function deleteAvatar(userId) {
	try
	{
		const currentAvatar = await getCurrentAvatar(userId);
		if (currentAvatar === null)
			return ({status: 404, data: {error: 'User not found'}});

		if (currentAvatar === DEFAULT_AVATAR)
			return ({status: 400, data: {error: 'Cannot delete default avatar'}});

		// Reset the avatar to the default one
		await setAvatar(DEFAULT_AVATAR, userId);

		deleteNonDefault(currentAvatar);
		return ({status: 200, data: {avatar_url: DEFAULT_AVATAR}});
	}
	catch (err)
	{
		console.error('Avatar delete error:', err);
		return ({status: 500, data: {error: 'Server error'}});
	}
}

async function setAvatar(newAvatar, userId)
{
	await query
	(
		'UPDATE users SET avatar_url = $1 WHERE id = $2',
		[newAvatar, userId]
	);
}

async function getCurrentAvatar(userId)
{
	const res = await query
	(
		'SELECT avatar_url FROM users WHERE id = $1',
		[userId]
	);
	if (res.rows.length === 0)
		return (null);
	return (res.rows[0].avatar_url);
}

function deleteNonDefault(curAvatar)
{
	if (curAvatar && curAvatar !== DEFAULT_AVATAR)
	{
		const fileName = path.basename(curAvatar);
		const filePath = path.join(AVATAR_DIR, fileName);

		if (fs.existsSync(filePath))
			fs.unlinkSync(filePath);
	}
}

async function getAvatarUrl(userId)
{
	try 
	{
		const result = await query
		(
			'SELECT avatar_url FROM users WHERE id = $1',
			[userId]
		);

		if (result.rows.length === 0)
			return ({status: 404, data: {error: 'User not found'}});

		const avatarUrl = result.rows[0].avatar_url || DEFAULT_AVATAR;
		return ({status: 200, data: {avatar_url: avatarUrl}});
	}
	catch (err)
	{
		console.error('Get avatar error:', err);
		return ({status: 500, data: {error: 'Server error'}});
	}
}

export default
{
	uploadAvatar,
	deleteAvatar,
	getAvatarUrl,
	AVATAR_DIR,
	DEFAULT_AVATAR
};
