import { Request, Response } from 'express';
import Message from '../models/Message.js';
import OrganizationMember from '../models/OrganizationMember.js';

// Send a message
export const sendMessage = async (req: Request, res: Response) => {
    try {
        const { toUserId, message } = req.body;
        const fromUserId = req.appUser?.clerkId;
        const organizationId = req.headers['x-organization-id'] as string;

        if (!organizationId) {
            return res.status(400).json({ error: 'Organização não selecionada.' });
        }

        if (!fromUserId) {
            return res.status(401).json({ error: 'Usuário não autenticado.' });
        }

        if (!toUserId || !message) {
            return res.status(400).json({ error: 'Destinatário e mensagem são obrigatórios.' });
        }

        if (message.length > 255) {
            return res.status(400).json({ error: 'Mensagem muito longa (máximo 255 caracteres).' });
        }

        // Check if there's already a pending (unread) message from this user to that user
        const existingMessage = await Message.findOne({
            organizationId,
            fromUserId,
            toUserId,
            isRead: false,
        });

        if (existingMessage) {
            // Update existing message instead of creating a new one
            existingMessage.message = message;
            existingMessage.updatedAt = new Date();
            await existingMessage.save();
            return res.json(existingMessage);
        }

        // Create new message
        const newMessage = new Message({
            organizationId,
            fromUserId,
            toUserId,
            message,
        });

        await newMessage.save();
        res.status(201).json(newMessage);
    } catch (error) {
        console.error('Error sending message:', error);
        res.status(500).json({ error: 'Erro ao enviar mensagem.' });
    }
};

// Get unread messages for current user
export const getUnreadMessages = async (req: Request, res: Response) => {
    try {
        const toUserId = req.appUser?.clerkId;
        const organizationId = req.headers['x-organization-id'] as string;

        if (!organizationId) {
            return res.status(400).json({ error: 'Organização não selecionada.' });
        }

        if (!toUserId) {
            return res.status(401).json({ error: 'Usuário não autenticado.' });
        }

        const messages = await Message.find({
            organizationId,
            toUserId,
            isRead: false,
            isArchived: false,
            isDeletedByRecipient: false,
        }).sort({ createdAt: -1 });

        // Populate sender info
        const messagesWithSender = await Promise.all(
            messages.map(async (msg) => {
                const sender = await OrganizationMember.findOne({ clerkUserId: msg.fromUserId });
                return {
                    ...msg.toObject(),
                    fromUser: sender ? { name: sender.name, email: sender.email } : null,
                };
            })
        );

        res.json(messagesWithSender);
    } catch (error) {
        console.error('Error getting unread messages:', error);
        res.status(500).json({ error: 'Erro ao buscar mensagens.' });
    }
};

// Mark message as read
export const markMessageAsRead = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;
        const userId = req.appUser?.clerkId;
        const organizationId = req.headers['x-organization-id'] as string;

        if (!organizationId) {
            return res.status(400).json({ error: 'Organização não selecionada.' });
        }

        if (!userId) {
            return res.status(401).json({ error: 'Usuário não autenticado.' });
        }

        const message = await Message.findOne({
            _id: id,
            organizationId,
            toUserId: userId,
        });

        if (!message) {
            return res.status(404).json({ error: 'Mensagem não encontrada.' });
        }

        message.isRead = true;
        message.readAt = new Date();
        await message.save();

        res.json(message);
    } catch (error) {
        console.error('Error marking message as read:', error);
        res.status(500).json({ error: 'Erro ao marcar mensagem como lida.' });
    }
};

// Get my pending (unread) sent messages
export const getMyPendingMessages = async (req: Request, res: Response) => {
    try {
        const fromUserId = req.appUser?.clerkId;
        const organizationId = req.headers['x-organization-id'] as string;

        if (!organizationId) {
            return res.status(400).json({ error: 'Organização não selecionada.' });
        }

        if (!fromUserId) {
            return res.status(401).json({ error: 'Usuário não autenticado.' });
        }

        const messages = await Message.find({
            organizationId,
            fromUserId,
            isRead: false,
        }).sort({ createdAt: -1 });

        // Populate recipient info
        const messagesWithRecipient = await Promise.all(
            messages.map(async (msg) => {
                const recipient = await OrganizationMember.findOne({ clerkUserId: msg.toUserId });
                return {
                    ...msg.toObject(),
                    toUser: recipient ? { name: recipient.name, email: recipient.email } : null,
                };
            })
        );

        res.json(messagesWithRecipient);
    } catch (error) {
        console.error('Error getting pending messages:', error);
        res.status(500).json({ error: 'Erro ao buscar mensagens pendentes.' });
    }
};

// Delete a message (only if unread and sender is the current user)
export const deleteMessage = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;
        const userId = req.appUser?.clerkId;
        const organizationId = req.headers['x-organization-id'] as string;

        if (!organizationId) {
            return res.status(400).json({ error: 'Organização não selecionada.' });
        }

        if (!userId) {
            return res.status(401).json({ error: 'Usuário não autenticado.' });
        }

        const message = await Message.findOne({
            _id: id,
            organizationId,
            fromUserId: userId,
            isRead: false, // Can only delete unread messages
        });

        if (!message) {
            return res.status(404).json({ error: 'Mensagem não encontrada ou já foi lida.' });
        }

        await message.deleteOne();
        res.json({ message: 'Mensagem deletada com sucesso.' });
    } catch (error) {
        console.error('Error deleting message:', error);
        res.status(500).json({ error: 'Erro ao deletar mensagem.' });
    }
};

// Recipient deletes/archives a message
export const archiveMessage = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;
        const userId = req.appUser?.clerkId;
        const organizationId = req.headers['x-organization-id'] as string;

        const message = await Message.findOne({ _id: id, toUserId: userId, organizationId });
        if (!message) return res.status(404).json({ error: 'Mensagem não encontrada.' });

        message.isArchived = true;
        message.isRead = true; // Arquivar implica ler
        await message.save();
        res.json(message);
    } catch (error) {
        console.error('Error archiving message:', error);
        res.status(500).json({ error: 'Erro ao arquivar mensagem.' });
    }
};

export const recipientDeleteMessage = async (req: Request, res: Response) => {
    try {
        const { id } = req.params;
        const userId = req.appUser?.clerkId;
        const organizationId = req.headers['x-organization-id'] as string;

        const message = await Message.findOne({ _id: id, toUserId: userId, organizationId });
        if (!message) return res.status(404).json({ error: 'Mensagem não encontrada.' });

        message.isDeletedByRecipient = true;
        await message.save();
        res.json({ message: 'Mensagem excluída com sucesso.' });
    } catch (error) {
        console.error('Error deleting message:', error);
        res.status(500).json({ error: 'Erro ao excluir mensagem.' });
    }
};
