const db         = require('./models');
const SocketUser = db.socket_users;
const axios      = require('axios');
const Chat       = db.chats;
const Company    = db.companies;
const Message    = db.messages;
const Sequelize  = require('sequelize');
const Op         = Sequelize.Op;
var path         = require('path');
const fs         = require('fs');
const baseUrl	 = db.base_url;

console.log(baseUrl);
module.exports = async function (io) {
	//create socket connection
	io.on('connection',socket => {
		console.log("A user connected with id: "+socket.id)

		socket.on('connect_user', async function (data) {

            // 🔹 Join a room unique to this user
            const userRoom = `user_${data.user_id}`;
            socket.join(userRoom);

			io.to(socket.id).emit('connect_user',data)
			console.log("A user connected with id: "+socket.id)
			io.emit('user-online', { user_id:data.user_id });
			//add socket user
			SocketUser.findOne({
				where:{
					user_id:data.user_id,
					user_model:data.user_model
				}
			}).then(async(socketUser)=>{
				if(socketUser) {
					socketUser.socket_id = socket.id;
					socketUser.save();
				} else {
					await SocketUser.create({
						user_id:data.user_id,
						user_model:data.user_model,
						socket_id:socket.id
					});
				}
				console.log('a user connected');
				//socket.emit('connect_user', socket.id);
			}).catch(err => {
				console.log('DB ERROR:',err)
			});

		});

		// socket.on('message', async(data) => {
		// 	console.log('received msg data', data);
		// 	var currentdate = new Date();
		// 	var datetime = currentdate.getFullYear() + "-" +
		// 			String(currentdate.getMonth() + 1).padStart(2, '0') + "-" +
		// 			String(currentdate.getDate()).padStart(2, '0') + " " +
		// 			String(currentdate.getHours()).padStart(2, '0') + ":" +
		// 			String(currentdate.getMinutes()).padStart(2, '0') + ":" +
		// 			String(currentdate.getSeconds()).padStart(2, '0');

		// 	data.created_at = datetime;
		// 	data.updated_at = datetime;

		// 	var company = await Company.findOne({
		// 		where: {
		// 			id: data.receiver_id,
		// 		},
		// 	});
		// 	data.company_id = company.id;
		// 	data.company_name = company.name;
		// 	data.company_logo = company.logo;

		// 	io.to(socket.id).emit('message', data);

		// 	let reciever = await SocketUser.findOne({
		// 		attributes:['id', 'socket_id'],
		// 		where:{
		// 			user_id: data.receiver_id
		// 		}
		// 	});

		// 	if(reciever){
		// 		company = await Company.findOne({
		// 			where: {
		// 				id: data.sender_id,
		// 			},
		// 		});
		// 		data.company_id = company.id;
		// 		data.company_name = company.name;
		// 		data.company_logo = company.logo;
		// 	}

		// 	let constantId = 0;
		// 	Chat.findOne({
		// 		attributes:['id'],
		// 		where:{
		// 			[Op.or]:[
		// 				[{
		// 					user_one:data.sender_id,
		// 					user_two:data.receiver_id
		// 				}],
		// 				[{
		// 					user_two:data.sender_id,
		// 					user_one:data.receiver_id
		// 				}]
		// 			] ,
		// 		},
		// 		// raw:true
		// 	}).then(async(chat_record)=>{
		// 		console.log('chat record found');
		// 		// if(data.hasOwnProperty(message)) {
		// 		if (data.message || data.file_path) {
		// 			Message.create(data).then(async(message)=>{
		// 				console.log('creating message', reciever);
		// 				if(chat_record == null){
		// 					Chat.create({
		// 						user_one:data.sender_id,
		// 						user_two:data.receiver_id,

		// 						// lastMessageId:message.id
		// 					}).then((newChatRecord)=>{
		// 						constantId = newChatRecord.id;
		// 						message.chat_id = newChatRecord.id
		// 						message.save();
		// 					});
		// 				} else {

		// 					constantId = chat_record.id;
		// 					message.chat_id = chat_record.id;
		// 					message.save();
		// 				}

		// 				sendPushNotification(data.sender_id, data.receiver_id);
		// 				if(reciever){
		// 					data.chat_id = constantId;
		// 					io.to(reciever.socket_id).emit('message', data);

		// 					let unreadCount = await Message.count({
		// 						where: {
		// 							receiver_id: data.receiver_id,
		// 							is_seen: 0
		// 						}
		// 					});

		// 					io.to(reciever.socket_id).emit('unread-count', { count: unreadCount });
		// 				}

		// 			}).catch(err => {
		// 				console.log('DB ERROR:',err)
		// 			});
		// 		} else {
		// 			console.log(data.file_path);
		// 		}

		// 	}).catch(err => {
		// 		console.log('DB ERROR:',err)
		// 	});
		// });

        socket.on('message', async(data) => {
			console.log('received msg data', data);
			var currentdate = new Date();
			var datetime = currentdate.getFullYear() + "-" +
					String(currentdate.getMonth() + 1).padStart(2, '0') + "-" +
					String(currentdate.getDate()).padStart(2, '0') + " " +
					String(currentdate.getHours()).padStart(2, '0') + ":" +
					String(currentdate.getMinutes()).padStart(2, '0') + ":" +
					String(currentdate.getSeconds()).padStart(2, '0');

			data.created_at = datetime;
			data.updated_at = datetime;

			var company = await Company.findOne({
				where: {
					id: data.receiver_id,
				},
			});
			data.company_id = company.id;
			data.company_name = company.name;
			data.company_logo = company.logo;


            // io.to(`user_${data.sender_id}`).emit('message', data);

            let receivers = await SocketUser.findAll({
                attributes: ['id', 'socket_id'],
                where: {
                    user_id: data.receiver_id
                }
            });


            if (receivers.length > 0) {
                company = await Company.findOne({
                    where: {
                        id: data.sender_id,
                    },
                });
                data.company_id = company.id;
                data.company_name = company.name;
                data.company_logo = company.logo;
            }

			let constantId = 0;
			Chat.findOne({
				attributes:['id'],
				where:{
					[Op.or]:[
						[{
							user_one:data.sender_id,
							user_two:data.receiver_id
						}],
						[{
							user_two:data.sender_id,
							user_one:data.receiver_id
						}]
					] ,
				},
				// raw:true
			}).then(async(chat_record)=>{
				console.log('chat record found');
				// if(data.hasOwnProperty(message)) {
				if (data.message || data.file_path) {
					Message.create(data).then(async(message)=>{
						console.log('creating message', receivers);
						if(chat_record == null){
							Chat.create({
								user_one:data.sender_id,
								user_two:data.receiver_id,

								// lastMessageId:message.id
							}).then((newChatRecord)=>{
								constantId = newChatRecord.id;
								message.chat_id = newChatRecord.id
								message.save();
							});
						} else {

							constantId = chat_record.id;
							message.chat_id = chat_record.id;
							message.save();
						}
                        data.message_id = message.id;
                        io.to(`user_${data.sender_id}`).emit('message', data);
						sendPushNotification(data.sender_id, data.receiver_id);
						if(receivers.length > 0){
							data.chat_id = constantId;


							let unreadCount = await Message.count({
								where: {
									receiver_id: data.receiver_id,
									is_seen: 0
								}
							});

                            io.to(`user_${data.receiver_id}`).emit('message', data);
                            io.to(`user_${data.receiver_id}`).emit('unread-count', { count: unreadCount });
						}

					}).catch(err => {
						console.log('DB ERROR:',err)
					});
				} else {
					console.log(data.file_path);
				}

			}).catch(err => {
				console.log('DB ERROR:',err)
			});
		});

		socket.on('disconnect',async () => {
			const user = await SocketUser.findOne({ where: { socket_id: socket.id } });

			if (user) {
				await SocketUser.destroy({ where: { socket_id: socket.id } });
				console.log(`User ${user.user_id} disconnected (socket: ${socket.id})`);
				io.emit('user-offline', { user_id: user.user_id });
			} else {
				console.log(`Unknown socket disconnected: ${socket.id}`);
			}
		});

		socket.on('uploadFile', (fileData) => {
			console.log('Uploading...', fileData);

			if (fileData && fileData.content) {
				// Set the uploads directory
				// const uploadsDir = path.join(__dirname, '..', 'uploads', 'chat');
				const uploadsDir = '/var/www/vhosts/web.tradingfmcg.com/public/uploads/chat';
				const filename = `${Date.now()}-${fileData.name}`;
				const fileExtension = path.extname(fileData.name); // Get file extension
				const savePath = path.join(uploadsDir, filename);
				const relativePath = `/uploads/chat/${filename}`;

				// Ensure the 'uploads' directory exists
				fs.mkdir(uploadsDir, { recursive: true }, (err) => {
					if (err) {
						console.error('Error creating directory:', err);
						socket.emit('uploadError', 'Failed to create directory');
						return;
					}

					// Save the file
					fs.writeFile(savePath, Buffer.from(fileData.content), (err) => {
						if (err) {
							console.error('Error saving file:', err);
							socket.emit('uploadError', 'File upload failed');
						} else {
							console.log('File saved successfully:', { path: relativePath, ext: fileExtension, receiverId: fileData.receiverId});
							socket.emit('uploadSuccess', {
								path: baseUrl + relativePath,
								ext: fileExtension,
								receiverId: fileData.receiverId
							});
						}
					});
				});
			} else {
				console.error('Invalid file data received');
				socket.emit('uploadError', 'Invalid file data');
			}
		});

        socket.on('ping', (data) => {
            socket.emit('ping', 'Connected');
        });

		async function sendPushNotification(senderId, receiverId = null, groupId = null) {
			let endPoint =  `${baseUrl}/api/sendMessageNotification?sender_id=${senderId}`;
			if(receiverId)
			  endPoint += `&receiver_id=${receiverId}`;

			await axios.get(endPoint).then((response) => {
			  console.log("chat response: ", response.data);
			}).catch((error) => {
			  console.log("error axios", error);
			});
		}

	});
}
