/**
 * N8N Conversation Webhook Callback
 *
 * Receives conversation updates from N8N workflows:
 * - New messages from WhatsApp/Voice/Social channels
 * - Conversation status updates
 * - AI actions taken
 *
 * Stores data in ConversationLog for dashboard display.
 */

import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import { logger } from "@/lib/logger";
import { systemSettingsService } from "@/lib/services/system-settings.service";
import { z } from "zod";
import { applyRateLimit, rateLimiters, getClientIdentifier } from "@/lib/rate-limiter";

// Request validation schema
const conversationPayloadSchema = z.object({
  auth_token: z.string().min(1),
  user_id: z.string().min(1),
  conversation_id: z.string().optional(),
  platform: z.enum(["whatsapp", "voice", "social"]),
  customer_phone: z.string().optional(),
  customer_name: z.string().optional(),
  message: z.object({
    role: z.enum(["user", "agent", "system"]),
    content: z.string(),
    timestamp: z.string(),
    metadata: z.record(z.unknown()).optional(),
  }),
  status_update: z
    .object({
      status: z.enum(["open", "resolved", "archived"]),
      summary: z.string().optional(),
      booking_id: z.string().optional(),
    })
    .optional(),
  metadata: z
    .object({
      intent: z.string().optional(),
      sentiment: z.enum(["positive", "neutral", "negative"]).optional(),
      escalated: z.boolean().optional(),
      booking_created: z.boolean().optional(),
      booking_id: z.string().optional(),
    })
    .optional(),
});

interface CallbackResponse {
  success: boolean;
  conversation_id: string;
  message_id?: string;
  error?: string;
}

export async function POST(request: NextRequest) {
  // Rate limit webhook requests (100/min per IP)
  const rateLimitResponse = await applyRateLimit(request, rateLimiters.webhookGeneral);
  if (rateLimitResponse) {
    logger.warn("N8N conversation webhook rate limit exceeded", {
      ip: getClientIdentifier(request),
    });
    return rateLimitResponse;
  }

  try {
    // Parse and validate request body
    const body = await request.json();
    const validationResult = conversationPayloadSchema.safeParse(body);

    if (!validationResult.success) {
      logger.warn("N8N conversation callback - invalid payload", {
        errors: validationResult.error.errors,
      });
      return NextResponse.json<CallbackResponse>(
        {
          success: false,
          conversation_id: "",
          error: "Invalid payload: " + validationResult.error.errors[0].message,
        },
        { status: 400 },
      );
    }

    const payload = validationResult.data;

    // Validate auth token (from database or env fallback)
    const isValidToken = await systemSettingsService.validateN8NToken(
      payload.auth_token,
    );
    if (!isValidToken) {
      logger.warn("N8N conversation callback - invalid auth token", {
        user_id: payload.user_id,
      });
      return NextResponse.json<CallbackResponse>(
        {
          success: false,
          conversation_id: "",
          error: "Invalid authentication token",
        },
        { status: 401 },
      );
    }

    // Verify user exists
    const user = await prisma.users.findUnique({
      where: { id: payload.user_id },
      select: { id: true, isActive: true },
    });

    if (!user || !user.isActive) {
      logger.warn("N8N conversation callback - user not found or inactive", {
        user_id: payload.user_id,
      });
      return NextResponse.json<CallbackResponse>(
        {
          success: false,
          conversation_id: "",
          error: "User not found or inactive",
        },
        { status: 404 },
      );
    }

    let conversationId = payload.conversation_id;
    let conversation;

    if (conversationId) {
      // Update existing conversation
      conversation = await prisma.conversationLog.findUnique({
        where: { id: conversationId },
      });

      if (!conversation || conversation.userId !== payload.user_id) {
        logger.warn("N8N conversation callback - conversation not found", {
          conversation_id: conversationId,
          user_id: payload.user_id,
        });
        // Create new conversation instead
        conversationId = undefined;
      }
    }

    if (!conversationId || !conversation) {
      // Create new conversation

      conversationId = conversation.id;

      logger.info("N8N conversation callback - created new conversation", {
        conversation_id: conversationId,
        user_id: payload.user_id,
        platform: payload.platform,
      });
    } else {
      // Append message to existing conversation
      const existingMessages = (conversation.messages as unknown[]) || [];
      const updatedMessages = [...existingMessages, payload.message];

      const updateData: Record<string, unknown> = {
        messages: updatedMessages,
        updatedAt: new Date(),
      };

      // Update customer info if provided
      if (payload.customer_name && !conversation.customerName) {
        updateData.customerName = payload.customer_name;
      }

      // Update status if provided
      if (payload.status_update) {
        updateData.status = payload.status_update.status;
      }

      // Merge metadata
      if (payload.metadata) {
        const existingMetadata =
          (conversation.metadata as Record<string, unknown>) || {};
        updateData.metadata = { ...existingMetadata, ...payload.metadata };
      }

      logger.info("N8N conversation callback - updated conversation", {
        conversation_id: conversationId,
        user_id: payload.user_id,
        message_role: payload.message.role,
      });
    }

    // Also sync to whatsapp_conversations if platform is WhatsApp
    if (payload.platform === "whatsapp" && payload.customer_phone) {
      await syncToWhatsAppConversations(
        payload.user_id,
        payload.customer_phone,
        payload.customer_name,
        payload.message,
        payload.status_update?.status,
      );
    }

    // Update workflow analytics
    await updateConversationAnalytics(
      payload.user_id,
      payload.platform,
      payload.message.role,
    );

    return NextResponse.json<CallbackResponse>({
      success: true,
      conversation_id: conversationId,
      message_id: `msg_${Date.now()}`,
    });
  } catch (error) {
    logger.error("N8N conversation callback error", { error });
    return NextResponse.json<CallbackResponse>(
      { success: false, conversation_id: "", error: "Internal server error" },
      { status: 500 },
    );
  }
}

/**
 * Sync conversation to whatsapp_conversations table for compatibility
 * with existing WhatsApp panel
 */
async function syncToWhatsAppConversations(
  userId: string,
  customerPhone: string,
  customerName: string | undefined,
  message: { role: string; content: string; timestamp: string },
  status?: string,
) {
  try {
    // Find or create WhatsApp conversation
    let waConversation = await prisma.whatsapp_conversations.findFirst({
      where: {
        userId,
        customerPhone,
      },
    });

    if (!waConversation) {
      waConversation = await prisma.whatsapp_conversations.create({
        data: {
          userId,
          customerPhone,
          customerName,
          status: "active",
          unreadCount: message.role === "user" ? 1 : 0,
          lastMessage: message.content.substring(0, 200),
          lastMessageAt: new Date(message.timestamp),
        },
      });
    } else {
      await prisma.whatsapp_conversations.update({
        where: { id: waConversation.id },
        data: {
          lastMessage: message.content.substring(0, 200),
          lastMessageAt: new Date(message.timestamp),
          unreadCount:
            message.role === "user"
              ? { increment: 1 }
              : waConversation.unreadCount,
          status: status === "resolved" ? "resolved" : waConversation.status,
          customerName: customerName || waConversation.customerName,
        },
      });
    }

    // Add message to conversation_messages
    await prisma.conversation_messages.create({
      data: {
        conversationId: waConversation.id,
        sender: message.role === "user" ? "customer" : "ai_agent",
        message: message.content,
        timestamp: new Date(message.timestamp),
        metadata: {},
      },
    });
  } catch (error) {
    logger.error("Failed to sync WhatsApp conversation", {
      error,
      userId,
      customerPhone,
    });
    // Don't fail the main callback
  }
}

/**
 * Update workflow analytics for conversation metrics
 */
async function updateConversationAnalytics(
  userId: string,
  platform: string,
  messageRole: string,
) {
  try {
    const today = new Date();
    today.setHours(0, 0, 0, 0);

    const workflowType = platform === "voice" ? "voice_agent" : "whatsapp";

    await prisma.workflowAnalytics.upsert({
      where: {
        userId_workflowType_date: {
          userId,
          workflowType,
          date: today,
        },
      },
      create: {
        userId,
        workflowType,
        date: today,
        messagesReceived: messageRole === "user" ? 1 : 0,
        messagesSent: messageRole === "agent" ? 1 : 0,
      },
      update: {
        messagesReceived: messageRole === "user" ? { increment: 1 } : undefined,
        messagesSent: messageRole === "agent" ? { increment: 1 } : undefined,
      },
    });
  } catch (error) {
    logger.error("Failed to update conversation analytics", {
      error,
      userId,
      platform,
    });
    // Don't fail the main callback
  }
}

// Only allow POST method
export async function GET() {
  return NextResponse.json({ error: "Method not allowed" }, { status: 405 });
}
