/**
 * N8N Context Lookup API
 *
 * Called by N8N workflows to get user context based on:
 * - WhatsApp number (for incoming WhatsApp messages)
 * - Voice agent ID (for ElevenLabs calls)
 * - User ID (direct lookup)
 * - N8N webhook token (for webhook routing)
 *
 * Returns user settings, workflow config, and optionally knowledge base context.
 */

import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import { convexQuery } from "@/lib/convex-client";
import { logger } from "@/lib/logger";
import { systemSettingsService } from "@/lib/services/system-settings.service";
import { z } from "zod";

// Request validation schema
const contextRequestSchema = z.object({
  auth_token: z.string().min(1, "Auth token is required"),
  lookup_type: z.enum([
    "whatsapp_number",
    "voice_agent_id",
    "user_id",
    "webhook_token",
  ]),
  lookup_value: z.string().min(1, "Lookup value is required"),
  include: z
    .object({
      knowledge_base: z.boolean().optional().default(false),
      credentials: z.boolean().optional().default(false),
      workflow_config: z.boolean().optional().default(false),
      recent_conversations: z.boolean().optional().default(false),
    })
    .optional()
    .default({}),
});

// Response types
interface ContextResponse {
  success: boolean;
  user?: {
    id: string;
    email: string;
    name: string;
    company_name: string | null;
    tier: string | null;
    language: string;
    timezone: string;
    is_active: boolean;
  };
  workflow?: {
    id: string;
    type: string;
    status: string;
    config: Record<string, unknown>;
    n8n_workflow_id: string | null;
  };
  knowledge_base?: {
    is_enabled: boolean;
    welcome_message: string | null;
    custom_instructions: string | null;
    faq_summary: Array<{
      question: string;
      answer: string;
      category: string;
    }>;
    document_count: number;
  };
  credentials?: {
    whatsapp?: {
      phone_number: string | null;
      connected: boolean;
    };
    voice?: {
      elevenlabs_agent_id: string | null;
    };
    has_openai_key: boolean;
    has_anthropic_key: boolean;
  };
  recent_conversations?: Array<{
    id: string;
    customer_phone: string | null;
    customer_name: string | null;
    last_message: string;
    last_message_at: string;
  }>;
  error?: string;
}

export async function POST(request: NextRequest) {
  try {
    // Parse and validate request body
    const body = await request.json();
    const validationResult = contextRequestSchema.safeParse(body);

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

    const { auth_token, lookup_type, lookup_value, include } =
      validationResult.data;

    // Validate auth token (from database or env fallback)
    const isValidToken =
      await systemSettingsService.validateN8NToken(auth_token);
    if (!isValidToken) {
      logger.warn("N8N context lookup with invalid auth token", {
        lookup_type,
        lookup_value: lookup_type === "user_id" ? lookup_value : "[REDACTED]",
      });
      return NextResponse.json(
        { success: false, error: "Invalid authentication token" },
        { status: 401 },
      );
    }

    // Find user based on lookup type
    let user = null;

    switch (lookup_type) {
      case "whatsapp_number":
        user = await prisma.users.findFirst({
          where: {
            whatsappNumber: lookup_value,
            whatsappConnected: true,
            isActive: true,
          },
          include: {
            subscriptions: {
              where: { status: { in: ["active", "trialing"] } },
              orderBy: { createdAt: "desc" },
              take: 1,
            },
            user_preferences: true,
            knowledgeBaseSettings: true,
          },
        });
        break;

      case "voice_agent_id":
        user = await prisma.users.findFirst({
          where: {
            voiceAgentId: lookup_value,
            isActive: true,
          },
          include: {
            subscriptions: {
              where: { status: { in: ["active", "trialing"] } },
              orderBy: { createdAt: "desc" },
              take: 1,
            },
            user_preferences: true,
            knowledgeBaseSettings: true,
          },
        });
        break;

      case "webhook_token":
        user = await prisma.users.findFirst({
          where: {
            n8nWebhookToken: lookup_value,
            isActive: true,
          },
          include: {
            subscriptions: {
              where: { status: { in: ["active", "trialing"] } },
              orderBy: { createdAt: "desc" },
              take: 1,
            },
            user_preferences: true,
            knowledgeBaseSettings: true,
          },
        });
        break;

      case "user_id":
        user = await prisma.users.findUnique({
          where: {
            id: lookup_value,
            isActive: true,
          },
          include: {
            subscriptions: {
              where: { status: { in: ["active", "trialing"] } },
              orderBy: { createdAt: "desc" },
              take: 1,
            },
            user_preferences: true,
            knowledgeBaseSettings: true,
          },
        });
        break;
    }

    if (!user) {
      logger.info("N8N context lookup - user not found", {
        lookup_type,
        lookup_value: lookup_type === "user_id" ? lookup_value : "[REDACTED]",
      });
      return NextResponse.json(
        { success: false, error: "User not found or inactive" },
        { status: 404 },
      );
    }

    // Build response
    const response: ContextResponse = {
      success: true,
      user: {
        id: user.id,
        email: user.email,
        name: user.name,
        company_name: user.companyName,
        tier: user.subscriptions[0]?.tierId || null,
        language: user.user_preferences?.language || "ar",
        timezone: user.user_preferences?.timezone || "Asia/Qatar",
        is_active: user.isActive,
      },
    };

    // Include workflow config if requested
    if (include.workflow_config) {
      // Get primary workflow (AI agent or WhatsApp)
      const workflow = await prisma.userWorkflow.findFirst({
        where: {
          userId: user.id,
          workflowType: { in: ["ai_agent", "whatsapp"] },
          status: "active",
        },
        orderBy: { updatedAt: "desc" },
      });

      if (workflow) {
        response.workflow = {
          id: workflow.id,
          type: workflow.workflowType,
          status: workflow.status,
          config: workflow.config as Record<string, unknown>,
          n8n_workflow_id: workflow.n8nWorkflowId,
        };
      }
    }

    // Include knowledge base context if requested
    if (include.knowledge_base) {
      const kbSettings = user.knowledgeBaseSettings;

      // Get FAQ summary (top 10 active FAQs) via Convex
      const rawFaqs = await convexQuery<Array<{
        questionEn: string;
        questionAr?: string;
        answerEn: string;
        answerAr?: string;
        category: string;
        priority: number;
      }>>("voice_agents/queries:getKBFAQs", {
        userId: user.id,
        isActive: true,
      });
      const faqs = (rawFaqs || [])
        .sort((a: { priority: number }, b: { priority: number }) => b.priority - a.priority)
        .slice(0, 10);

      // Get document count via Convex
      const rawDocs = await convexQuery<Array<{ status: string }>>(
        "voice_agents/queries:getKBDocuments",
        { userId: user.id, status: "COMPLETED" },
      );
      const documentCount = (rawDocs || []).length;

      const preferredLang = user.user_preferences?.language || "ar";

      response.knowledge_base = {
        is_enabled: kbSettings?.isEnabled ?? true,
        welcome_message: kbSettings?.welcomeMessage || null,
        custom_instructions: kbSettings?.customInstructions || null,
        faq_summary: faqs.map((faq) => ({
          question:
            preferredLang === "ar" && faq.questionAr
              ? faq.questionAr
              : faq.questionEn,
          answer:
            preferredLang === "ar" && faq.answerAr
              ? faq.answerAr
              : faq.answerEn,
          category: faq.category,
        })),
        document_count: documentCount,
      };
    }

    // Include credential status if requested (never return actual keys)
    if (include.credentials) {
      // Check for API keys (just existence, not values)
      const apiKeys = await prisma.userAPIKey.findMany({
        where: {
          userId: user.id,
          isActive: true,
        },
        select: { service: true },
      });

      const services = new Set(apiKeys.map((k) => k.service));

      response.credentials = {
        whatsapp: {
          phone_number: user.whatsappNumber,
          connected: user.whatsappConnected,
        },
        voice: {
          elevenlabs_agent_id: user.voiceAgentId,
        },
        has_openai_key: services.has("openai"),
        has_anthropic_key: services.has("anthropic"),
      };
    }

    // Include recent conversations if requested
    if (include.recent_conversations) {
      const conversations = await prisma.conversationLog.findMany({
        where: {
          userId: user.id,
          status: { in: ["open", "resolved"] },
        },
        orderBy: { updatedAt: "desc" },
        take: 5,
        select: {
          id: true,
          customerPhone: true,
          customerName: true,
          messages: true,
          updatedAt: true,
        },
      });

      response.recent_conversations = conversations.map((conv) => {
        const messages = conv.messages as Array<{ content?: string }>;
        const lastMessage = messages[messages.length - 1]?.content || "";
        return {
          id: conv.id,
          customer_phone: conv.customerPhone,
          customer_name: conv.customerName,
          last_message: lastMessage.substring(0, 100),
          last_message_at: conv.updatedAt.toISOString(),
        };
      });
    }

    logger.info("N8N context lookup successful", {
      user_id: user.id,
      lookup_type,
      includes: Object.keys(include).filter(
        (k) => include[k as keyof typeof include],
      ),
    });

    return NextResponse.json(response);
  } catch (error) {
    logger.error("N8N context lookup error", { error });
    return NextResponse.json(
      { success: false, error: "Internal server error" },
      { status: 500 },
    );
  }
}

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