// controllers/contactController.ts
import { Request, Response, NextFunction } from "express";
import { 
  contactService, 
  ContactMessageCreateData,
  ContactMessageUpdateData,
  ContactMessageReplyData,
  ContactSettingsUpdateData,
  ContactMessageFilters 
} from "./contact.service";
import { catchAsyncError } from "../../middlewares/catchAsyncError";
import ErrorHandler from "../../middlewares/error";
import { AuthRequest } from "../../middlewares/auth";

export const contactController = {
  // Get contact page data
  getContactPageData: catchAsyncError(async (req: Request, res: Response, next: NextFunction) => {
    const data = await contactService.getContactPageData();
    
    res.status(200).json({
      success: true,
      data,
    });
  }),

  // Create new contact message
  createContactMessage: catchAsyncError(async (req: Request, res: Response, next: NextFunction) => {
    const data: ContactMessageCreateData = {
      ...req.body,
      ip_address: req.ip,
      user_agent: req.headers['user-agent'],
      referrer_url: req.headers['referer'],
    };

    // Validation
    if (!data.name || !data.email || !data.subject || !data.message) {
      return next(new ErrorHandler("All required fields must be filled", 400));
    }

    try {
      const message = await contactService.createContactMessage(data);
      
      res.status(201).json({
        success: true,
        message: "Message sent successfully. We'll get back to you soon!",
        data: {
          id: message.id,
          name: message.name,
          email: message.email,
          subject: message.subject,
          created_at: message.created_at,
        },
      });
    } catch (error: any) {
      return next(new ErrorHandler(error.message, 400));
    }
  }),

  // Get all messages (admin only)
  getAllMessages: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const {
      page = 1,
      limit = 20,
      status,
      priority,
      category,
      assigned_to,
      is_read,
      is_replied,
      is_spam = "false",
      needs_follow_up,
      search,
      start_date,
      end_date,
      sort_by = "created_at",
      order = "desc",
    } = req.query;

    const filters: ContactMessageFilters = {
      page: parseInt(page as string),
      limit: parseInt(limit as string),
      status: status as string,
      priority: priority as string,
      category: category as string,
      assigned_to: assigned_to as string,
      is_read: is_read ? is_read === "true" : undefined,
      is_replied: is_replied ? is_replied === "true" : undefined,
      is_spam: is_spam === "true",
      needs_follow_up: needs_follow_up ? needs_follow_up === "true" : undefined,
      search: search as string,
      start_date: start_date as string,
      end_date: end_date as string,
      sort_by: sort_by as string,
      order: order as "asc" | "desc",
    };

    const result = await contactService.getAllMessages(filters);

    res.status(200).json({
      success: true,
      ...result,
    });
  }),

  // Get message by ID
  getMessageById: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const { id } = req.params;

    const message = await contactService.getMessageById(id);
    
    if (!message) {
      return next(new ErrorHandler("Message not found", 404));
    }

    // Mark as read if not already read
    if (!message.is_read && req.user) {
      await contactService.markMessageAsRead(id, req.user.id);
    }

    res.status(200).json({
      success: true,
      data: message,
    });
  }),

  // Update message (admin only)
  updateMessage: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const { id } = req.params;
    const userId = req.user?.id;
    const data: ContactMessageUpdateData = req.body;

    if (!userId) {
      return next(new ErrorHandler("Authentication required", 401));
    }

    try {
      const updatedMessage = await contactService.updateMessage(id, data, userId);

      res.status(200).json({
        success: true,
        message: "Message updated successfully",
        data: updatedMessage,
      });
    } catch (error: any) {
      return next(new ErrorHandler(error.message, 400));
    }
  }),

  // Delete message (admin only)
  deleteMessage: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const { id } = req.params;

    const deletedMessage = await contactService.deleteMessage(id);

    res.status(200).json({
      success: true,
      message: "Message deleted successfully",
      data: deletedMessage,
    });
  }),

  // Delete multiple messages (admin only)
  deleteMultipleMessages: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const { message_ids } = req.body;

    if (!Array.isArray(message_ids) || message_ids.length === 0) {
      return next(new ErrorHandler("Message IDs array is required", 400));
    }

    const deletedMessages = await contactService.deleteMultipleMessages(message_ids);

    res.status(200).json({
      success: true,
      message: `${deletedMessages.length} messages deleted successfully`,
      data: deletedMessages,
    });
  }),

  // Reply to message (admin only)
  replyToMessage: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const userId = req.user?.id;
    const data: ContactMessageReplyData = {
      ...req.body,
      replied_by: userId!,
    };

    if (!userId) {
      return next(new ErrorHandler("Authentication required", 401));
    }

    if (!data.message_id || !data.reply_subject || !data.reply_message) {
      return next(new ErrorHandler("All required fields must be filled", 400));
    }

    try {
      const reply = await contactService.replyToMessage(data);

      res.status(201).json({
        success: true,
        message: "Reply sent successfully",
        data: reply,
      });
    } catch (error: any) {
      return next(new ErrorHandler(error.message, 400));
    }
  }),

  // Get message statistics (admin only)
  getMessageStats: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const stats = await contactService.getMessageStats();

    res.status(200).json({
      success: true,
      data: stats,
    });
  }),

  // Update contact settings (admin only)
  updateContactSettings: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const userId = req.user?.id;
    const data: ContactSettingsUpdateData = req.body;

    if (!userId) {
      return next(new ErrorHandler("Authentication required", 401));
    }

    // Validate email format if provided
    if (data.company_email && !data.company_email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
      return next(new ErrorHandler("Invalid company email format", 400));
    }

    if (data.support_email && !data.support_email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
      return next(new ErrorHandler("Invalid support email format", 400));
    }

    try {
      const updatedSettings = await contactService.updateContactSettings(data);

      res.status(200).json({
        success: true,
        message: "Contact settings updated successfully",
        data: updatedSettings,
      });
    } catch (error: any) {
      return next(new ErrorHandler(error.message, 400));
    }
  }),

  // Mark message as spam (admin only)
  markMessageAsSpam: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const { id } = req.params;
    const { spam_reason } = req.body;

    const message = await contactService.markMessageAsSpam(id, spam_reason);

    res.status(200).json({
      success: true,
      message: "Message marked as spam",
      data: message,
    });
  }),

  // Get messages by email (admin only)
  getMessagesByEmail: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const { email } = req.params;
    const limit = parseInt(req.query.limit as string) || 10;

    if (!email) {
      return next(new ErrorHandler("Email is required", 400));
    }

    const messages = await contactService.getMessagesByEmail(email, limit);

    res.status(200).json({
      success: true,
      data: messages,
    });
  }),

  // Get follow-up messages (admin only)
  getFollowUpMessages: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const messages = await contactService.getFollowUpMessages();

    res.status(200).json({
      success: true,
      data: messages,
    });
  }),

  // Bulk update message status (admin only)
  bulkUpdateMessageStatus: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const userId = req.user?.id;
    const { message_ids, status } = req.body;

    if (!userId) {
      return next(new ErrorHandler("Authentication required", 401));
    }

    if (!Array.isArray(message_ids) || message_ids.length === 0) {
      return next(new ErrorHandler("Message IDs array is required", 400));
    }

    if (!status || !['unread', 'read', 'replied', 'archived', 'spam'].includes(status)) {
      return next(new ErrorHandler("Valid status is required", 400));
    }

    const updatedMessages = await contactService.bulkUpdateMessageStatus(message_ids, status, userId);

    res.status(200).json({
      success: true,
      message: `${updatedMessages.length} messages updated successfully`,
      data: updatedMessages,
    });
  }),

  // Test email sending (admin only)
  testEmailSending: catchAsyncError(async (req: AuthRequest, res: Response, next: NextFunction) => {
    const { email } = req.body;

    if (!email) {
      return next(new ErrorHandler("Email is required", 400));
    }

    try {
      // Get contact settings
      const settings = await contactService.getContactPageData();
      
      const testEmail = {
        email: email,
        subject: "Test Email from Contact System",
        message: `
          <!DOCTYPE html>
          <html>
          <head>
            <style>
              body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
              .container { max-width: 600px; margin: 0 auto; padding: 20px; }
              .header { background: #3b82f6; color: white; padding: 20px; text-align: center; border-radius: 5px 5px 0 0; }
              .content { background: #f9fafb; padding: 20px; border-radius: 0 0 5px 5px; }
            </style>
          </head>
          <body>
            <div class="container">
              <div class="header">
                <h1>Test Email</h1>
              </div>
              <div class="content">
                <p>This is a test email from the ${settings.company_name || 'Toolffy'} contact system.</p>
                <p>If you're receiving this email, it means the email system is working correctly.</p>
                <br>
                <p>Best regards,<br>The ${settings.company_name || 'Toolffy'} Team</p>
              </div>
            </div>
          </body>
          </html>
        `,
      };

      // You'll need to import and use your email sending function here
      // await sendEmail(testEmail);
      
      res.status(200).json({
        success: true,
        message: "Test email would be sent to " + email,
        data: {
          email: email,
          timestamp: new Date().toISOString(),
        },
      });
    } catch (error: any) {
      return next(new ErrorHandler(error.message, 400));
    }
  }),
};