/**
 * Voice Agents Dashboard API
 *
 * GET /api/dashboard/voice-agents - Get all voice agent info and stats
 *
 * Returns:
 * - Voice agent configuration
 * - Call statistics
 * - Recent call history
 * - Health 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 { getDataSource } from "@/lib/data-source";

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

interface VoiceAgentStats {
  totalCalls: number;
  todayCalls: number;
  weekCalls: number;
  appointmentsBooked: number;
  avgCallDuration: number; // in seconds
}

interface RecentCall {
  id: string;
  customerPhone: string | null;
  customerName: string | null;
  duration: number;
  outcome: string;
  appointmentBooked: boolean;
  timestamp: string;
}

interface VoiceAgentOverview {
  agent: {
    id: string | null;
    configured: boolean;
    config: Record<string, unknown> | null;
    status: string;
    healthStatus: string;
  };
  stats: VoiceAgentStats;
  recentCalls: RecentCall[];
  workflow: {
    id: string | null;
    status: string;
    lastRunAt: string | null;
  } | null;
}

/**
 * GET /api/dashboard/voice-agents
 * Get comprehensive voice agent information
 */
export async function GET(request: NextRequest) {
  try {
    // Authenticate user
    const user = await getAuthenticatedUser(request, auth);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    // ── Convex data-source branch ──────────────────────────────────────
    if (getDataSource("voice_agents") === "convex") {
      try {
        const { convexQuery } = await import("@/lib/convex-client");

        // Get user voice agent info
        const cvxUser = (await convexQuery(
          "voice_agents/queries:getUserVoiceAgent",
          {
            userId: user.userId,
          },
        )) as {
          id: string;
          voiceAgentId: string | null;
          voiceAgentConfig: unknown;
        } | null;

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

        // Get conversation logs from Convex
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        const weekAgo = new Date();
        weekAgo.setDate(weekAgo.getDate() - 7);
        weekAgo.setHours(0, 0, 0, 0);

        const allLogsResult = (await convexQuery(
          "voice_agents/queries:getVoiceConversationStats",
          {
            userId: user.userId,
          },
        )) as { count: number; logs: Array<Record<string, unknown>> } | null;

        const allLogs = allLogsResult?.logs || [];
        const totalCalls = allLogsResult?.count || 0;

        const todayTimestamp = today.getTime();
        const weekTimestamp = weekAgo.getTime();
        const todayCalls = allLogs.filter(
          (l) => (l.createdAt as number) >= todayTimestamp,
        ).length;
        const weekCalls = allLogs.filter(
          (l) => (l.createdAt as number) >= weekTimestamp,
        ).length;

        // Transform recent calls (take 10 most recent)
        const recentLogs = allLogs.slice(0, 10);
        const recentCalls: RecentCall[] = recentLogs.map((conv) => {
          const metadata = (conv.metadata as Record<string, unknown>) || {};
          const messages =
            (conv.messages as Array<{ timestamp?: string }>) || [];

          let duration = 0;
          if (messages.length >= 2) {
            const first = messages[0]?.timestamp
              ? new Date(messages[0].timestamp).getTime()
              : 0;
            const last = messages[messages.length - 1]?.timestamp
              ? new Date(messages[messages.length - 1].timestamp).getTime()
              : 0;
            duration = Math.round((last - first) / 1000);
          }

          return {
            id: (conv._id as string) || (conv.prismaId as string) || "",
            customerPhone: (conv.customerPhone as string) || null,
            customerName: (conv.customerName as string) || null,
            duration,
            outcome: (metadata.outcome as string) || "completed",
            appointmentBooked: Boolean(metadata.booking_created),
            timestamp: new Date(conv.createdAt as number).toISOString(),
          };
        });

        const avgCallDuration =
          recentCalls.length > 0
            ? Math.round(
                recentCalls.reduce((sum, call) => sum + call.duration, 0) /
                  recentCalls.length,
              )
            : 0;

        const overview: VoiceAgentOverview = {
          agent: {
            id: cvxUser.voiceAgentId,
            configured: Boolean(cvxUser.voiceAgentId),
            config: cvxUser.voiceAgentConfig as Record<string, unknown> | null,
            status: cvxUser.voiceAgentId ? "active" : "not_configured",
            healthStatus: "unknown",
          },
          stats: {
            totalCalls,
            todayCalls,
            weekCalls,
            appointmentsBooked: 0, // workflow analytics not yet in Convex
            avgCallDuration,
          },
          recentCalls,
          workflow: null, // workflow data not yet in Convex
        };

        scopedLogger.info("Voice agents overview retrieved (Convex)", {
          userId: user.userId,
          hasAgent: overview.agent.configured,
          totalCalls,
        });

        return NextResponse.json({
          success: true,
          voiceAgent: overview,
        });
      } catch (convexError) {
        console.error("[Convex fallback] voice_agents dashboard:", convexError);
        // Fall through to Prisma path
      }
    }

    // ── Prisma path (default) ─────────────────────────────────────────
    // Get user with voice agent data
    const userData = await prisma.users.findUnique({
      where: { id: user.userId },
      select: {
        id: true,
        voiceAgentId: true,
        voiceAgentConfig: true,
      },
    });

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

    // Get voice workflow status
    const voiceWorkflow = await prisma.userWorkflow.findFirst({
      where: {
        userId: user.userId,
        workflowType: "voice_agent",
      },
      select: {
        id: true,
        status: true,
        healthStatus: true,
        lastRunAt: true,
        n8nWorkflowId: true,
      },
    });

    // Get voice conversations (calls) stats
    const today = new Date();
    today.setHours(0, 0, 0, 0);

    const weekAgo = new Date();
    weekAgo.setDate(weekAgo.getDate() - 7);
    weekAgo.setHours(0, 0, 0, 0);

    // Get total voice conversations
    const totalCalls = await prisma.conversationLog.count({
      where: {
        userId: user.userId,
        platform: "voice",
      },
    });

    // Get today's calls
    const todayCalls = await prisma.conversationLog.count({
      where: {
        userId: user.userId,
        platform: "voice",
        createdAt: { gte: today },
      },
    });

    // Get week's calls
    const weekCalls = await prisma.conversationLog.count({
      where: {
        userId: user.userId,
        platform: "voice",
        createdAt: { gte: weekAgo },
      },
    });

    // Get appointments booked via voice
    const voiceAnalytics = await prisma.workflowAnalytics.aggregate({
      where: {
        userId: user.userId,
        workflowType: "voice_agent",
      },
      _sum: {
        appointmentsBooked: true,
      },
    });

    // Get recent voice conversations
    const recentConversations = await prisma.conversationLog.findMany({
      where: {
        userId: user.userId,
        platform: "voice",
      },
      orderBy: { createdAt: "desc" },
      take: 10,
      select: {
        id: true,
        customerPhone: true,
        customerName: true,
        messages: true,
        metadata: true,
        createdAt: true,
        updatedAt: true,
      },
    });

    // Transform recent calls
    const recentCalls: RecentCall[] = recentConversations.map((conv) => {
      const metadata = (conv.metadata as Record<string, unknown>) || {};
      const messages = (conv.messages as Array<{ timestamp?: string }>) || [];

      // Calculate duration from first to last message
      let duration = 0;
      if (messages.length >= 2) {
        const first = messages[0]?.timestamp
          ? new Date(messages[0].timestamp).getTime()
          : 0;
        const last = messages[messages.length - 1]?.timestamp
          ? new Date(messages[messages.length - 1].timestamp).getTime()
          : 0;
        duration = Math.round((last - first) / 1000);
      }

      return {
        id: conv.id,
        customerPhone: conv.customerPhone,
        customerName: conv.customerName,
        duration,
        outcome: (metadata.outcome as string) || "completed",
        appointmentBooked: Boolean(metadata.booking_created),
        timestamp: conv.createdAt.toISOString(),
      };
    });

    // Calculate average call duration
    const avgCallDuration =
      recentCalls.length > 0
        ? Math.round(
            recentCalls.reduce((sum, call) => sum + call.duration, 0) /
              recentCalls.length,
          )
        : 0;

    const overview: VoiceAgentOverview = {
      agent: {
        id: userData.voiceAgentId,
        configured: Boolean(userData.voiceAgentId),
        config: userData.voiceAgentConfig as Record<string, unknown> | null,
        status: userData.voiceAgentId ? "active" : "not_configured",
        healthStatus: voiceWorkflow?.healthStatus || "unknown",
      },
      stats: {
        totalCalls,
        todayCalls,
        weekCalls,
        appointmentsBooked: voiceAnalytics._sum.appointmentsBooked || 0,
        avgCallDuration,
      },
      recentCalls,
      workflow: voiceWorkflow
        ? {
            id: voiceWorkflow.n8nWorkflowId,
            status: voiceWorkflow.status,
            lastRunAt: voiceWorkflow.lastRunAt?.toISOString() || null,
          }
        : null,
    };

    scopedLogger.info("Voice agents overview retrieved", {
      userId: user.userId,
      hasAgent: overview.agent.configured,
      totalCalls,
    });

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