import { defineTable } from "convex/server";
import { v } from "convex/values";

// ── Enums ──────────────────────────────────────────────────────────────

export const kbDocumentStatusValidator = v.union(
  v.literal("PENDING"),
  v.literal("PROCESSING"),
  v.literal("COMPLETED"),
  v.literal("FAILED"),
);

export const phoneConnectionTypeValidator = v.union(
  v.literal("twilio_native"),
  v.literal("custom_sip"),
);

export const kbSyncStatusValidator = v.union(
  v.literal("pending"),
  v.literal("synced"),
  v.literal("failed"),
  v.literal("deleted"),
);

// ── Tables ─────────────────────────────────────────────────────────────

export const voiceAgentTables = {
  conversation_logs: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    platform: v.string(),
    customerPhone: v.optional(v.string()),
    customerName: v.optional(v.string()),
    messages: v.any(),
    metadata: v.optional(v.any()),
    status: v.string(),
    lastMessageAt: v.optional(v.number()),
    lastMessagePreview: v.optional(v.string()),
    unreadCount: v.number(),
    messageCount: v.number(),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_status", ["status"])
    .index("by_userId_platform_createdAt", ["userId", "platform", "createdAt"])
    .index("by_userId_platform_status", ["userId", "platform", "status"])
    .index("by_userId_updatedAt", ["userId", "updatedAt"])
    .index("by_userId_lastMessageAt", ["userId", "lastMessageAt"]),

  conversation_log_messages: defineTable({
    prismaId: v.optional(v.string()),
    conversationId: v.string(),
    sender: v.union(
      v.literal("customer"),
      v.literal("ai_agent"),
      v.literal("admin"),
    ),
    content: v.string(),
    timestamp: v.number(),
    metadata: v.optional(v.any()),
    createdAt: v.number(),
  })
    .index("by_conversationId", ["conversationId"])
    .index("by_conversationId_timestamp", ["conversationId", "timestamp"])
    .index("by_timestamp", ["timestamp"]),

  voice_conversation_actions: defineTable({
    prismaId: v.optional(v.string()),
    conversationId: v.string(),
    type: v.string(),
    status: v.string(),
    title: v.string(),
    description: v.optional(v.string()),
    dueAt: v.optional(v.number()),
    assignedTo: v.optional(v.string()),
    completedAt: v.optional(v.number()),
    completedBy: v.optional(v.string()),
    metadata: v.optional(v.any()),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_conversationId", ["conversationId"])
    .index("by_status", ["status"])
    .index("by_assignedTo", ["assignedTo"]),

  voice_agent_phone_config: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    connectionType: phoneConnectionTypeValidator,
    phoneNumber: v.optional(v.string()),
    isActive: v.boolean(),
    elevenlabsPhoneId: v.optional(v.string()),
    twilioPhoneNumber: v.optional(v.string()),
    twilioAccountSid: v.optional(v.string()),
    twilioAuthToken: v.optional(v.string()),
    sipUri: v.optional(v.string()),
    sipUsername: v.optional(v.string()),
    sipPassword: v.optional(v.string()),
    sipRegistrar: v.optional(v.string()),
    sipTransport: v.optional(v.string()),
    metadata: v.optional(v.any()),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_userId", ["userId"])
    .index("by_isActive", ["isActive"]),

  voice_agent_kb_sync: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    documentId: v.string(),
    elevenlabsDocumentId: v.optional(v.string()),
    syncStatus: kbSyncStatusValidator,
    lastSyncAt: v.optional(v.number()),
    syncError: v.optional(v.string()),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_userId", ["userId"])
    .index("by_syncStatus", ["syncStatus"])
    .index("by_documentId", ["documentId"])
    .index("by_userId_documentId", ["userId", "documentId"]),

  voice_agent_settings: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    successEvaluationCriteria: v.optional(v.any()),
    dataCollectionSchema: v.optional(v.any()),
    postCallWebhookUrl: v.optional(v.string()),
    pronunciationDictId: v.optional(v.string()),
    pronunciationRules: v.optional(v.any()),
    domainAllowlist: v.array(v.string()),
    signedUrlEnabled: v.boolean(),
    activeWorkflowId: v.optional(v.string()),
    workflowTemplate: v.optional(v.string()),
    workflowCustomization: v.optional(v.any()),
    createdAt: v.number(),
    updatedAt: v.number(),
  }).index("by_userId", ["userId"]),

  knowledge_base_documents: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    filename: v.string(),
    originalName: v.string(),
    mimeType: v.string(),
    fileSize: v.number(),
    storagePath: v.string(),
    title: v.optional(v.string()),
    description: v.optional(v.string()),
    category: v.string(),
    status: kbDocumentStatusValidator,
    processedAt: v.optional(v.number()),
    processingError: v.optional(v.string()),
    chunkCount: v.number(),
    embeddingModel: v.optional(v.string()),
    createdAt: v.number(),
    updatedAt: v.number(),
    deletedAt: v.optional(v.number()),
    geminiFileName: v.optional(v.string()),
    geminiUploadedAt: v.optional(v.number()),
    mediaType: v.optional(v.string()), // "document" | "image" | "video" | "audio"
    mediaUrl: v.optional(v.string()), // Storage URL for serving
    thumbnailUrl: v.optional(v.string()), // Preview thumbnail
    duration: v.optional(v.number()), // Duration in seconds (video/audio)
    width: v.optional(v.number()), // Image/video width
    height: v.optional(v.number()), // Image/video height
    embeddingId: v.optional(v.string()), // Pinecone vector ID
    aiDescription: v.optional(v.string()), // AI-generated description
    pineconeNamespace: v.optional(v.string()), // Pinecone namespace
  })
    .index("by_createdAt", ["createdAt"])
    .index("by_deletedAt", ["deletedAt"])
    .index("by_userId_category", ["userId", "category"])
    .index("by_userId_status", ["userId", "status"])
    .index("by_user_media_type", ["userId", "mediaType"]),

  knowledge_base_chunks: defineTable({
    prismaId: v.optional(v.string()),
    documentId: v.string(),
    content: v.string(),
    chunkIndex: v.number(),
    embedding: v.optional(v.any()),
    metadata: v.optional(v.any()),
    createdAt: v.number(),
  }).index("by_documentId_chunkIndex", ["documentId", "chunkIndex"]),

  knowledge_base_faqs: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    questionEn: v.string(),
    questionAr: v.optional(v.string()),
    answerEn: v.string(),
    answerAr: v.optional(v.string()),
    category: v.string(),
    priority: v.number(),
    isActive: v.boolean(),
    embedding: v.optional(v.any()),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_userId_category", ["userId", "category"])
    .index("by_userId_isActive", ["userId", "isActive"]),

  knowledge_base_settings: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    isEnabled: v.boolean(),
    onboardingCompleted: v.boolean(),
    maxChunksPerQuery: v.number(),
    similarityThreshold: v.number(),
    welcomeMessage: v.optional(v.string()),
    customInstructions: v.optional(v.string()),
    createdAt: v.number(),
    updatedAt: v.number(),
    geminiFileSearchStoreId: v.optional(v.string()),
    geminiFileSearchStoreName: v.optional(v.string()),
  }).index("by_userId", ["userId"]),
};
