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

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

export const refundStatusValidator = v.union(
  v.literal("pending"),
  v.literal("succeeded"),
  v.literal("failed"),
  v.literal("canceled"),
);

export const refundReasonValidator = v.union(
  v.literal("requested_by_customer"),
  v.literal("duplicate"),
  v.literal("fraudulent"),
);

export const contentStatusValidator = v.union(
  v.literal("DRAFT"),
  v.literal("PUBLISHED"),
);

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

export const billingTables = {
  subscriptions: defineTable({
    prismaId: v.optional(v.string()),
    userId: v.string(),
    stripeCustomerId: v.string(),
    stripeSubscriptionId: v.string(),
    stripePriceId: v.string(),
    tierId: v.string(),
    status: v.string(),
    billingPeriod: v.string(),
    currentPeriodEnd: v.number(),
    trialEndsAt: v.optional(v.number()),
    cancelAtPeriodEnd: v.boolean(),
    cancelledAt: v.optional(v.number()),
    lastPaymentDate: v.optional(v.number()),
    lastPaymentAttempt: v.optional(v.number()),
    paymentFailureCount: v.number(),
    createdAt: v.number(),
    updatedAt: v.number(),
    cardBrand: v.optional(v.string()),
    cardLastFour: v.optional(v.string()),
    paymentMethodId: v.optional(v.string()),
    setupFeeAmount: v.optional(v.number()),
    setupFeePaid: v.boolean(),
    setupFeePaidAt: v.optional(v.number()),
  })
    .index("by_status", ["status"])
    .index("by_stripeCustomerId", ["stripeCustomerId"])
    .index("by_stripeSubscriptionId", ["stripeSubscriptionId"])
    .index("by_userId", ["userId"])
    .index("by_userId_status", ["userId", "status"])
    .index("by_currentPeriodEnd", ["currentPeriodEnd"])
    .index("by_trialEndsAt", ["trialEndsAt"]),

  billing_history: defineTable({
    prismaId: v.optional(v.string()),
    customerId: v.string(),
    subscriptionId: v.optional(v.string()),
    invoiceId: v.optional(v.string()),
    paymentIntentId: v.optional(v.string()),
    dedupeKey: v.optional(v.string()),
    event: v.string(),
    amount: v.number(),
    currency: v.string(),
    metadata: v.optional(v.any()),
    createdAt: v.number(),
  })
    .index("by_createdAt", ["createdAt"])
    .index("by_customerId", ["customerId"])
    .index("by_dedupeKey", ["dedupeKey"])
    .index("by_event", ["event"])
    .index("by_invoiceId", ["invoiceId"])
    .index("by_paymentIntentId", ["paymentIntentId"])
    .index("by_subscriptionId", ["subscriptionId"]),

  payments: defineTable({
    prismaId: v.optional(v.string()),
    stripePaymentIntentId: v.string(),
    stripeSessionId: v.optional(v.string()),
    amount: v.number(),
    currency: v.string(),
    status: v.string(),
    customerId: v.string(),
    customerEmail: v.optional(v.string()),
    succeededAt: v.optional(v.number()),
    failedAt: v.optional(v.number()),
    errorMessage: v.optional(v.string()),
    metadata: v.optional(v.any()),
    createdAt: v.number(),
    updatedAt: v.number(),
  })
    .index("by_customerId", ["customerId"])
    .index("by_status", ["status"])
    .index("by_stripePaymentIntentId", ["stripePaymentIntentId"]),

  refunds: defineTable({
    prismaId: v.optional(v.string()),
    stripeRefundId: v.string(),
    stripePaymentIntentId: v.optional(v.string()),
    stripeChargeId: v.optional(v.string()),
    subscriptionId: v.optional(v.string()),
    customerId: v.string(),
    userId: v.optional(v.string()),
    amount: v.number(),
    currency: v.string(),
    status: refundStatusValidator,
    reason: v.optional(refundReasonValidator),
    stripeReason: v.optional(v.string()),
    staffId: v.optional(v.string()),
    staffNotes: v.optional(v.string()),
    customerReason: v.optional(v.string()),
    failureReason: v.optional(v.string()),
    metadata: v.optional(v.any()),
    createdAt: v.number(),
    updatedAt: v.number(),
    processedAt: v.optional(v.number()),
  })
    .index("by_createdAt", ["createdAt"])
    .index("by_customerId", ["customerId"])
    .index("by_staffId", ["staffId"])
    .index("by_status", ["status"])
    .index("by_stripeChargeId", ["stripeChargeId"])
    .index("by_stripeRefundId", ["stripeRefundId"])
    .index("by_userId", ["userId"]),

  subscription_tiers: defineTable({
    prismaId: v.optional(v.string()),
    tierName: v.string(),
    displayName: v.string(),
    tierLevel: v.number(),
    features: v.any(),
    createdAt: v.number(),
    updatedAt: v.number(),
  }).index("by_tierLevel", ["tierLevel"]),

  pricing_copy: defineTable({
    prismaId: v.optional(v.string()),
    lang: v.string(),
    status: contentStatusValidator,
    version: v.number(),
    title: v.optional(v.string()),
    subtitle: v.optional(v.string()),
    highlight: v.optional(v.string()),
    ctaLabel: v.optional(v.string()),
    ctaHref: v.optional(v.string()),
    faq: v.any(),
    createdBy: v.optional(v.string()),
    updatedBy: v.optional(v.string()),
    publishedBy: v.optional(v.string()),
    createdAt: v.number(),
    updatedAt: v.number(),
    publishedAt: v.optional(v.number()),
  }).index("by_lang_status", ["lang", "status"]),
};
