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

export default defineSchema({
  // ─── Customers ─────────────────────────────────────────────────────────
  users: defineTable({
    externalId: v.string(),
    email: v.string(),
    name: v.string(),
    firstName: v.optional(v.string()),
    lastName: v.optional(v.string()),
    role: v.union(
      v.literal("customer"),
      v.literal("admin"),
      v.literal("super_admin"),
    ),
    avatarUrl: v.optional(v.string()),
    phone: v.optional(v.string()),
    stripeCustomerId: v.optional(v.string()),
    createdAt: v.optional(v.number()),
    lastLoginAt: v.optional(v.number()),
  })
    .index("by_external_id", ["externalId"])
    .index("by_email", ["email"])
    .index("by_role", ["role"]),

  addresses: defineTable({
    userId: v.id("users"),
    type: v.union(v.literal("shipping"), v.literal("billing")),
    fullName: v.string(),
    firstName: v.string(),
    lastName: v.string(),
    phone: v.string(),
    addressLine1: v.string(),
    additionalInformation: v.optional(v.string()),
    city: v.string(),
    postalCode: v.string(),
    country: v.string(),
    isDefault: v.boolean(),
    isValidated: v.optional(v.boolean()),
  })
    .index("by_user", ["userId"])
    .index("by_user_and_type", ["userId", "type"]),

  // ─── Catalog (Categories & Products) ────────────────────────────────────
  categories: defineTable({
    name: v.string(),
    slug: v.string(),
    description: v.optional(v.string()),
    imageUrl: v.optional(v.string()),
    parentId: v.optional(v.id("categories")),
    topCategorySlug: v.optional(v.string()),
    seoTitle: v.optional(v.string()),
    seoDescription: v.optional(v.string()),
  })
    .index("by_slug", ["slug"])
    .index("by_parent", ["parentId"])
    .index("by_parent_slug", ["parentId", "slug"])
    .index("by_top_category_slug", ["topCategorySlug"]),

  products: defineTable({
    name: v.string(),
    slug: v.string(),
    description: v.optional(v.string()),
    shortDescription: v.optional(v.string()),
    status: v.union(
      v.literal("active"),
      v.literal("draft"),
      v.literal("archived"),
    ),
    categoryId: v.id("categories"),
    brand: v.optional(v.string()),
    tags: v.array(v.string()),
    attributes: v.optional(
      v.object({
        petSize: v.optional(v.array(v.string())),
        ageRange: v.optional(v.array(v.string())),
        specialDiet: v.optional(v.array(v.string())),
        material: v.optional(v.string()),
        flavor: v.optional(v.string()),
      }),
    ),
    seoTitle: v.optional(v.string()),
    seoDescription: v.optional(v.string()),
    canonicalSlug: v.optional(v.string()),
    averageRating: v.optional(v.number()),
    reviewCount: v.optional(v.number()),
    createdAt: v.optional(v.number()),
    updatedAt: v.optional(v.number()),
    parentCategorySlug: v.string(),
    childCategorySlug: v.string(),
    topCategorySlug: v.optional(v.string()),
  })
    .index("by_slug", ["slug"])
    .index("by_status", ["status"])
    .index("by_category", ["categoryId"])
    .index("by_status_and_category", ["status", "categoryId"])
    .index("by_brand", ["brand"])
    .index("by_status_and_parent_slug", ["status", "parentCategorySlug"])
    .index("by_status_and_parent_and_child_slug", [
      "status",
      "parentCategorySlug",
      "childCategorySlug",
    ])
    .index("by_status_and_top_category_slug", ["status", "topCategorySlug"])
    .index("by_status_and_top_and_parent_slug", [
      "status",
      "topCategorySlug",
      "parentCategorySlug",
    ])
    .searchIndex("search_products", {
      searchField: "name",
      filterFields: ["status", "categoryId", "brand", "parentCategorySlug"],
    }),

  productImages: defineTable({
    productId: v.id("products"),
    url: v.string(),
    alt: v.optional(v.string()),
    position: v.number(),
  }).index("by_product", ["productId"]),

  productVariants: defineTable({
    productId: v.id("products"),
    name: v.string(),
    sku: v.string(),
    price: v.number(),
    compareAtPrice: v.optional(v.number()),
    stockQuantity: v.number(),
    attributes: v.optional(
      v.object({
        size: v.optional(v.string()),
        flavor: v.optional(v.string()),
        color: v.optional(v.string()),
      }),
    ),
    isActive: v.boolean(),
    weight: v.number(),
    weightUnit: v.union(
      v.literal("g"),
      v.literal("kg"),
      v.literal("lb"),
      v.literal("oz"),
    ),
    length: v.optional(v.number()),
    width: v.optional(v.number()),
    height: v.optional(v.number()),
    dimensionUnit: v.optional(v.union(
      v.literal("cm"),
      v.literal("in"),
    )),
  })
    .index("by_product", ["productId"])
    .index("by_sku", ["sku"])
    .index("by_product_and_active", ["productId", "isActive"]),

  // ─── Orders & Payments ──────────────────────────────────────────────────
  orders: defineTable({
    orderNumber: v.string(),
    userId: v.id("users"),
    email: v.string(),
    status: v.union(
      v.literal("pending"),
      v.literal("confirmed"),
      v.literal("processing"),
      v.literal("shipped"),
      v.literal("delivered"),
      v.literal("cancelled"),
      v.literal("refunded"),
      v.literal("return"),
      v.literal("completed"),
    ),
    paymentStatus: v.union(
      v.literal("pending"),
      v.literal("paid"),
      v.literal("failed"),
      v.literal("refunded"),
    ),
    subtotal: v.number(),
    tax: v.number(),
    shipping: v.number(),
    discount: v.number(),
    total: v.number(),
    currency: v.string(),
    shippingAddressSnapshot: v.object({
      fullName: v.string(),
      firstName: v.string(),
      lastName: v.string(),
      addressLine1: v.string(),
      additionalInformation: v.optional(v.string()),
      city: v.string(),
      postalCode: v.string(),
      country: v.string(),
      phone: v.optional(v.string()),
    }),
    billingAddressSnapshot: v.object({
      firstName: v.string(),
      lastName: v.string(),
      addressLine1: v.string(),
      additionalInformation: v.optional(v.string()),
      city: v.string(),
      postalCode: v.string(),
      country: v.string(),
    }),
    stripePaymentIntentId: v.optional(v.string()),
    stripeCheckoutSessionId: v.optional(v.string()),
    shippoOrderId: v.optional(v.string()),
    shippoShipmentId: v.string(),
    shippingMethod: v.string(),
    shippingServiceCode: v.string(),
    carrier: v.string(),
    trackingNumber: v.optional(v.string()),
    trackingUrl: v.optional(v.string()),
    labelUrl: v.optional(v.string()),
    trackingStatus: v.optional(v.string()),
    estimatedDelivery: v.optional(v.number()),
    actualDelivery: v.optional(v.number()),
    notes: v.optional(v.string()),
    createdAt: v.number(),
    updatedAt: v.number(),
    paidAt: v.optional(v.number()),
    shippedAt: v.optional(v.number()),
    returnRequestedAt: v.optional(v.number()),
    returnReceivedAt: v.optional(v.number()),
    returnLabelUrl: v.optional(v.string()),
    returnTrackingNumber: v.optional(v.string()),
    returnCarrier: v.optional(v.string()),
  })
    .index("by_user", ["userId"])
    .index("by_status", ["status"])
    .index("by_payment_status", ["paymentStatus"])
    .index("by_order_number", ["orderNumber"])
    .index("by_email", ["email"])
    .index("by_created_at", ["createdAt"])
    .index("by_stripe_checkout_session_id", ["stripeCheckoutSessionId"])
    .index("by_tracking_number_and_carrier", ["trackingNumber", "carrier"])
    .index("by_return_tracking_number_and_carrier", ["returnTrackingNumber", "returnCarrier"])
    .index("by_stripe_payment_intent_id", ["stripePaymentIntentId"]),

  orderItems: defineTable({
    orderId: v.id("orders"),
    variantId: v.id("productVariants"),
    productName: v.string(),
    variantName: v.string(),
    sku: v.string(),
    quantity: v.number(),
    unitPrice: v.number(),
    totalPrice: v.number(),
    imageUrl: v.optional(v.string()),
  }).index("by_order", ["orderId"]),

  orderTimelineEvents: defineTable({
    orderId: v.id("orders"),
    eventType: v.string(), // "status_change" | "customer_cancel" | "return_requested" | "return_received" | "refund" | "tracking_update" | "label_created"
    source: v.string(),   // "stripe_webhook" | "fulfillment" | "admin" | "shippo_webhook" | "customer_cancel" | "customer_return"
    fromStatus: v.optional(v.string()),
    toStatus: v.optional(v.string()),
    payload: v.optional(v.string()), // JSON string for Shippo/Stripe payloads
    createdAt: v.number(),
    userId: v.optional(v.id("users")),
  })
    .index("by_order", ["orderId"])
    .index("by_order_and_created_at", ["orderId", "createdAt"]),

  // ─── Reviews ───────────────────────────────────────────────────────────
  reviews: defineTable({
    productId: v.id("products"),
    userId: v.id("users"),
    orderId: v.optional(v.id("orders")),
    rating: v.number(),
    title: v.string(),
    content: v.string(),
    images: v.optional(v.array(v.string())),
    verifiedPurchase: v.boolean(),
    helpfulCount: v.number(),
    createdAt: v.number(),
    updatedAt: v.optional(v.number()),
    isApproved: v.boolean(),
  })
    .index("by_product", ["productId"])
    .index("by_user", ["userId"])
    .index("by_product_approved", ["productId", "isApproved"]),

  // ─── Wishlists ──────────────────────────────────────────────────────────
  wishlists: defineTable({
    userId: v.id("users"),
    productId: v.id("products"),
    variantId: v.optional(v.id("productVariants")),
    addedAt: v.number(),
    notifyOnPriceDrop: v.boolean(),
    notifyOnBackInStock: v.boolean(),
    priceWhenAdded: v.number(),
  })
    .index("by_user", ["userId"])
    .index("by_product", ["productId"])
    .index("by_user_and_product", ["userId", "productId"]),

  // ─── Carts ──────────────────────────────────────────────────────────────
  carts: defineTable({
    userId: v.optional(v.id("users")),
    sessionId: v.optional(v.string()),
    items: v.array(
      v.object({
        productId: v.id("products"),
        variantId: v.optional(v.id("productVariants")),
        quantity: v.number(),
        price: v.number(),
      }),
    ),
    createdAt: v.number(),
    updatedAt: v.number(),
    expiresAt: v.number(),
  })
    .index("by_user", ["userId"])
    .index("by_session", ["sessionId"]),

  // ─── Contact messages ───────────────────────────────────────────────────
  messages: defineTable({
    fullName: v.string(),
    email: v.string(),
    topic: v.union(
      v.literal("products"),
      v.literal("orders"),
      v.literal("support"),
      v.literal("other"),
    ),
    message: v.string(),
    createdAt: v.number(),
    bookmarked: v.optional(v.boolean()),
    updatedAt: v.optional(v.number()),
  })
    .index("by_created_at", ["createdAt"])
    .index("by_topic", ["topic"])
    .index("by_bookmarked", ["bookmarked"]),
});
