/**
 * Single Conversation Detail API
 *
 * GET /api/dashboard/conversations/[id] - Get full conversation with messages
 * PUT /api/dashboard/conversations/[id] - Update conversation status
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { getAuthenticatedUser } from "@/lib/utils/auth-helpers.util";
import { prisma } from "@/lib/db";
import { logger } from "@/lib/logger";
import { z } from "zod";

const scopedLogger = logger.scope("ConversationDetailAPI");

// Update schema
const updateConversationSchema = z.object({
  status: z.enum(["open", "resolved", "archived"]).optional(),
  customerName: z.string().min(1).max(100).optional(),
  notes: z.string().max(1000).optional(),
});

interface ConversationMessage {
  role: "user" | "agent" | "system";
  content: string;
  timestamp: string;
  metadata?: Record<string, unknown>;
}

interface ConversationDetail {
  id: string;
  platform: string;
  customerPhone: string | null;
  customerName: string | null;
  status: string;
  messages: ConversationMessage[];
  metadata: Record<string, unknown>;
  createdAt: string;
  updatedAt: string;
  stats: {
    messageCount: number;
    userMessages: number;
    agentMessages: number;
    durationMinutes: number;
  };
}

/**
 * GET /api/dashboard/conversations/[id]
 * Get full conversation with all messages
 */
export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  try {
    const { id } = await params;

    // Authenticate user
    const user = await getAuthenticatedUser(request, auth);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    // Get conversation
    const conversation = await prisma.conversationLog.findUnique({
      where: { id },
    });

    if (!conversation) {
      return NextResponse.json(
        { success: false, error: "Conversation not found" },
        { status: 404 },
      );
    }

    // Verify ownership
    if (conversation.userId !== user.userId) {
      return NextResponse.json(
        { success: false, error: "Access denied" },
        { status: 403 },
      );
    }

    // Parse messages
    const messages = (conversation.messages as ConversationMessage[]) || [];
    const metadata = (conversation.metadata as Record<string, unknown>) || {};

    // Calculate stats
    const userMessages = messages.filter((m) => m.role === "user").length;
    const agentMessages = messages.filter((m) => m.role === "agent").length;

    let durationMinutes = 0;
    if (messages.length >= 2) {
      const firstTime = new Date(messages[0].timestamp).getTime();
      const lastTime = new Date(
        messages[messages.length - 1].timestamp,
      ).getTime();
      durationMinutes = Math.round((lastTime - firstTime) / 60000);
    }

    const detail: ConversationDetail = {
      id: conversation.id,
      platform: conversation.platform,
      customerPhone: conversation.customerPhone,
      customerName: conversation.customerName,
      status: conversation.status,
      messages,
      metadata,
      createdAt: conversation.createdAt.toISOString(),
      updatedAt: conversation.updatedAt.toISOString(),
      stats: {
        messageCount: messages.length,
        userMessages,
        agentMessages,
        durationMinutes,
      },
    };

    scopedLogger.info("Conversation detail retrieved", {
      userId: user.userId,
      conversationId: id,
      messageCount: messages.length,
    });

    return NextResponse.json({
      success: true,
      conversation: detail,
    });
  } catch (error) {
    scopedLogger.error("Failed to get conversation detail", error);
    return NextResponse.json(
      { success: false, error: "Internal server error" },
      { status: 500 },
    );
  }
}

/**
 * PUT /api/dashboard/conversations/[id]
 * Update conversation status or metadata
 */
export async function PUT(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> },
) {
  try {
    const { id } = await params;

    // Authenticate user
    const user = await getAuthenticatedUser(request, auth);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    // Get conversation
    const conversation = await prisma.conversationLog.findUnique({
      where: { id },
    });

    if (!conversation) {
      return NextResponse.json(
        { success: false, error: "Conversation not found" },
        { status: 404 },
      );
    }

    // Verify ownership
    if (conversation.userId !== user.userId) {
      return NextResponse.json(
        { success: false, error: "Access denied" },
        { status: 403 },
      );
    }

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

    if (!validationResult.success) {
      return NextResponse.json(
        {
          success: false,
          error: "Invalid request: " + validationResult.error.errors[0].message,
        },
        { status: 400 },
      );
    }

    const updates = validationResult.data;

    // Build update data
    const updateData: Record<string, unknown> = {
      updatedAt: new Date(),
    };

    if (updates.status) {
      updateData.status = updates.status;
    }

    if (updates.customerName) {
      updateData.customerName = updates.customerName;
    }

    if (updates.notes !== undefined) {
      const existingMetadata =
        (conversation.metadata as Record<string, unknown>) || {};
      updateData.metadata = {
        ...existingMetadata,
        notes: updates.notes,
      };
    }

    // Update conversation
    const updated = await prisma.conversationLog.update({
      where: { id },
      data: updateData,
    });

    scopedLogger.info("Conversation updated", {
      userId: user.userId,
      conversationId: id,
      updates: Object.keys(updates),
    });

    return NextResponse.json({
      success: true,
      conversation: {
        id: updated.id,
        status: updated.status,
        customerName: updated.customerName,
        updatedAt: updated.updatedAt.toISOString(),
      },
    });
  } catch (error) {
    scopedLogger.error("Failed to update conversation", error);
    return NextResponse.json(
      { success: false, error: "Internal server error" },
      { status: 500 },
    );
  }
}
