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

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

export const roleValidator = v.union(
  v.literal("CUSTOMER"),
  v.literal("STAFF"),
  v.literal("ADMIN"),
  v.literal("SUPER_ADMIN"),
);

export const otpPurposeValidator = v.union(
  v.literal("SIGNUP"),
  v.literal("LOGIN"),
  v.literal("PASSWORD_RESET"),
);

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

export const authTables = {
  users: defineTable({
    appUserId: v.optional(v.string()),
    prismaId: v.optional(v.string()),
    email: v.string(),
    name: v.string(),
    password: v.optional(v.string()),
    googleId: v.optional(v.string()),
    clerkId: v.optional(v.string()),
    emailVerified: v.optional(v.number()),
    createdAt: v.number(),
    updatedAt: v.number(),
    lastLoginAt: v.optional(v.number()),
    lastLoginIp: v.optional(v.string()),
    failedAttempts: v.number(),
    lockedUntil: v.optional(v.number()),
    address: v.optional(v.string()),
    companyName: v.optional(v.string()),
    companySize: v.optional(v.string()),
    industry: v.optional(v.string()),
    onboardingComplete: v.boolean(),
    phoneNumber: v.optional(v.string()),
    website: v.optional(v.string()),
    country: v.optional(v.string()),
    preferredCurrency: v.optional(v.string()),
    city: v.optional(v.string()),
    selectedPackage: v.optional(v.string()),
    selectedBillingPeriod: v.optional(
      v.union(v.literal("monthly"), v.literal("yearly")),
    ),
    goals: v.optional(v.any()),
    stripeCustomerId: v.optional(v.string()),
    avatar: v.optional(v.string()),
    isActive: v.boolean(),
    isSuspended: v.boolean(),
    lastLoginCity: v.optional(v.string()),
    lastLoginCountry: v.optional(v.string()),
    loginCount: v.number(),
    n8nWebhookUrl: v.optional(v.string()),
    n8nWorkflowId: v.optional(v.string()),
    role: roleValidator,
    suspendedAt: v.optional(v.number()),
    suspendedBy: v.optional(v.string()),
    suspendedReason: v.optional(v.string()),
    username: v.optional(v.string()),
    whatsappConnected: v.boolean(),
    whatsappConnectedAt: v.optional(v.number()),
    whatsappNumber: v.optional(v.string()),
    n8nWebhookToken: v.optional(v.string()),
    onboardingStep: v.number(),
    voiceAgentConfig: v.optional(v.any()),
    voiceAgentId: v.optional(v.string()),
    isTrialOver: v.optional(v.boolean()),
    setupFeePaid: v.optional(v.boolean()),
    setupFeePaidAt: v.optional(v.number()),
  })
    .index("by_appUserId", ["appUserId"])
    .index("by_email", ["email"])
    .index("by_googleId", ["googleId"])
    .index("by_clerkId", ["clerkId"])
    .index("by_createdAt", ["createdAt"])
    .index("by_isActive_isSuspended", ["isActive", "isSuspended"])
    .index("by_lastLoginAt", ["lastLoginAt"])
    .index("by_lastLoginCountry", ["lastLoginCountry"])
    .index("by_n8nWebhookToken", ["n8nWebhookToken"])
    .index("by_n8nWebhookUrl", ["n8nWebhookUrl"])
    .index("by_role", ["role"])
    .index("by_stripeCustomerId", ["stripeCustomerId"])
    .index("by_username", ["username"]),

  otps: defineTable({
    prismaId: v.optional(v.string()),
    email: v.string(),
    otp_code: v.string(),
    purpose: otpPurposeValidator,
    expires_at: v.number(),
    verified: v.boolean(),
    verified_at: v.optional(v.number()),
    ip_address: v.optional(v.string()),
    created_at: v.number(),
    updated_at: v.number(),
  })
    .index("by_email", ["email"])
    .index("by_email_created_at", ["email", "created_at"])
    .index("by_expires_at", ["expires_at"])
    .index("by_purpose", ["purpose"]),

  user_sessions: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    token: v.string(),
    deviceName: v.string(),
    deviceType: v.string(),
    ipAddress: v.string(),
    location: v.optional(v.string()),
    country: v.optional(v.string()),
    city: v.optional(v.string()),
    userAgent: v.string(),
    lastActive: v.number(),
    createdAt: v.number(),
    expiresAt: v.number(),
    loginHistoryId: v.optional(v.string()),
  })
    .index("by_expiresAt", ["expiresAt"])
    .index("by_lastActive", ["lastActive"])
    .index("by_loginHistoryId", ["loginHistoryId"])
    .index("by_token", ["token"])
    .index("by_userId", ["userId"]),

  login_history: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    ipAddress: v.string(),
    userAgent: v.optional(v.string()),
    country: v.optional(v.string()),
    countryCode: v.optional(v.string()),
    city: v.optional(v.string()),
    region: v.optional(v.string()),
    latitude: v.optional(v.number()),
    longitude: v.optional(v.number()),
    timezone: v.optional(v.string()),
    provider: v.string(),
    success: v.boolean(),
    failReason: v.optional(v.string()),
    createdAt: v.number(),
    logoutAt: v.optional(v.number()),
  })
    .index("by_country", ["country"])
    .index("by_ipAddress", ["ipAddress"])
    .index("by_success_createdAt", ["success", "createdAt"])
    .index("by_userId_createdAt", ["userId", "createdAt"]),

  user_preferences: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    language: v.string(),
    timezone: v.string(),
    dateFormat: v.string(),
    theme: v.string(),
    emailNotifications: v.any(),
    smsNotifications: v.any(),
    whatsappNotifications: v.any(),
    emailFrequency: v.string(),
    dashboardPreferences: v.any(),
    createdAt: v.number(),
    updatedAt: v.number(),
  }).index("by_userId", ["userId"]),

  onboarding_progress: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    welcomeCompleted: v.boolean(),
    whatsappCompleted: v.boolean(),
    whatsappMethod: v.optional(v.string()),
    voiceAgentCompleted: v.boolean(),
    knowledgeBaseCompleted: v.boolean(),
    workflowsCompleted: v.boolean(),
    testingCompleted: v.boolean(),
    startedAt: v.number(),
    completedAt: v.optional(v.number()),
    lastStepAt: v.number(),
    dismissedAt: v.optional(v.number()),
    dismissCount: v.number(),
  })
    .index("by_completedAt", ["completedAt"])
    .index("by_userId", ["userId"]),

  audit_logs: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.optional(v.string()),
    type: v.string(),
    action: v.string(),
    success: v.boolean(),
    ip: v.string(),
    userAgent: v.optional(v.string()),
    metadata: v.optional(v.any()),
    createdAt: v.number(),
  })
    .index("by_createdAt", ["createdAt"])
    .index("by_type", ["type"])
    .index("by_userId", ["userId"])
    .index("by_userId_createdAt", ["userId", "createdAt"])
    .index("by_userId_type_createdAt", ["userId", "type", "createdAt"])
    .index("by_type_action", ["type", "action"])
    .index("by_success_createdAt", ["success", "createdAt"]),
};
