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

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

export const orgRoleValidator = v.union(
  v.literal("OWNER"),
  v.literal("ADMIN"),
  v.literal("STAFF"),
);

export const invitationStatusValidator = v.union(
  v.literal("PENDING"),
  v.literal("ACCEPTED"),
  v.literal("EXPIRED"),
  v.literal("REVOKED"),
);

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

export const organizationTables = {
  organizations: defineTable({
    prismaId: v.optional(v.string()),
    name: v.string(),
    ownerId: v.string(),
    stripeCustomerId: v.optional(v.string()),
    includedSeats: v.number(),
    purchasedSeats: v.number(),
    createdAt: v.number(),
    updatedAt: v.number(),
    stripeKeysConfiguredAt: v.optional(v.number()),
    stripeKeysConfiguredBy: v.optional(v.string()),
    stripeKeysMode: v.optional(v.string()),
    stripePublishableKey: v.optional(v.string()),
    stripeSecretKeyEncrypted: v.optional(v.string()),
    stripeWebhookSecretEncrypted: v.optional(v.string()),
    industry: v.optional(v.string()),
    sector: v.optional(v.string()),
    subscriptionTier: v.string(),
    whatsappPhoneNumberId: v.optional(v.string()),
    whatsappAccessTokenEncrypted: v.optional(v.string()),
    whatsappAppSecretEncrypted: v.optional(v.string()),
    whatsappDisplayNumber: v.optional(v.string()),
    whatsappVerifyToken: v.optional(v.string()),
    whatsappWebhookVerified: v.boolean(),
    whatsappConfiguredAt: v.optional(v.number()),
    whatsappConfiguredBy: v.optional(v.string()),
    // Meta token rotation: when the long-lived token was last issued (ms since epoch).
    // Used by lib/services/meta-token-refresh.service.ts to refresh tokens before
    // they expire (~60 days from issuance).
    whatsappTokenIssuedAt: v.optional(v.number()),
    // GDPR: per-org conversation retention window (days). Default 365.
    // Used by lib/services/conversation-cleanup.service.ts.
    dataRetentionDays: v.optional(v.number()),
    stripeConnectAccountId: v.optional(v.string()),
    stripeConnectStatus: v.optional(v.string()),
    twilioAccountSid: v.optional(v.string()),
    twilioAuthTokenEncrypted: v.optional(v.string()),
    twilioWhatsappNumber: v.optional(v.string()),
    twilioWhatsappConfigured: v.boolean(),
    twilioWhatsappConfiguredAt: v.optional(v.number()),
    twilioWhatsappConfiguredBy: v.optional(v.string()),
    lastSeatPurchaseSessionId: v.optional(v.string()),
    // AI agent defaults (set during org provisioning)
    aiGreetingEn: v.optional(v.string()),
    aiGreetingAr: v.optional(v.string()),
    aiModel: v.optional(v.string()),
    depositRequired: v.optional(v.boolean()),
    depositPercentage: v.optional(v.number()),
    autoSendPaymentLink: v.optional(v.boolean()),
    // Per-org WhatsApp first-message greeting (sent when a customer messages
    // for the first time). Used by lib/services/whatsapp-greeting.service.ts.
    // When `autoGreetingEnabled === false`, no greeting is sent.
    greetingMessageEn: v.optional(v.string()),
    greetingMessageAr: v.optional(v.string()),
    autoGreetingEnabled: v.optional(v.boolean()),
  })
    .index("by_createdAt", ["createdAt"])
    .index("by_ownerId", ["ownerId"])
    .index("by_stripeConnectAccountId", ["stripeConnectAccountId"])
    .index("by_stripeCustomerId", ["stripeCustomerId"])
    .index("by_subscriptionTier", ["subscriptionTier"])
    .index("by_whatsappPhoneNumberId", ["whatsappPhoneNumberId"])
    .index("by_twilioWhatsappNumber", ["twilioWhatsappNumber"]),

  organization_members: defineTable({
    prismaId: v.optional(v.string()),
    organizationId: v.string(),
    userId: v.string(),
    role: orgRoleValidator,
    joinedAt: v.number(),
    invitedBy: v.optional(v.string()),
    lastActiveAt: v.optional(v.number()),
  })
    .index("by_joinedAt", ["joinedAt"])
    .index("by_organizationId", ["organizationId"])
    .index("by_organizationId_userId", ["organizationId", "userId"])
    .index("by_role", ["role"])
    .index("by_userId", ["userId"]),

  organization_invitations: defineTable({
    prismaId: v.optional(v.string()),
    organizationId: v.string(),
    email: v.string(),
    name: v.optional(v.string()),
    role: orgRoleValidator,
    token: v.string(),
    status: invitationStatusValidator,
    expiresAt: v.number(),
    sentAt: v.number(),
    invitedBy: v.string(),
    acceptedAt: v.optional(v.number()),
  })
    .index("by_email", ["email"])
    .index("by_expiresAt", ["expiresAt"])
    .index("by_invitedBy", ["invitedBy"])
    .index("by_organizationId", ["organizationId"])
    .index("by_organizationId_status", ["organizationId", "status"])
    .index("by_status", ["status"])
    .index("by_token", ["token"]),
};
