import mongoose, { Document, Schema } from 'mongoose';

// Order item interface
export interface IOrderItem {
  product_id: string;
  product_sku: string;
  product_name: string;
  price: number;
  quantity: number;
  subtotal: number;
}

// Delivery address interface
export interface IDeliveryAddress {
  full_name: string;
  phone: string;
  address_line1: string;
  address_line2?: string;
  city: string;
  state: string;
  pincode: string;
  country: string;
}

export interface IBillingAddress {
  full_name: string;
  phone: string;
  address_line1: string;
  address_line2?: string;
  city: string;
  state: string;
  pincode: string;
  country: string;
}

export interface IOrder extends Document {
  order_id: string;
  customer_id?: mongoose.Schema.Types.ObjectId;
  guest_id?: string;
  customer_name: string;
  customer_phone: string;
  customer_email: string;
  items: IOrderItem[];
  delivery_address: IDeliveryAddress;
  billing_address: IBillingAddress;
  payment_status: 'pending' | 'paid' | 'failed' | 'refunded';
  payment_method: 'cod' | 'online' | 'upi';
  payment_id?: string;
  subtotal: number;
  shipping_charge: number;
  discount: number;
  total_amount: number;
  order_status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled';
  shipment_id?: mongoose.Schema.Types.ObjectId;
  device: 'website' | 'mobile' | 'admin';
  order_placed_at: Date;
  createdAt: Date;
  updatedAt: Date;
}

const OrderItemSchema = new Schema({
  product_id: { type: String, required: true },
  product_sku: { type: String, required: true },
  product_name: { type: String, required: true },
  price: { type: Number, required: true, min: 0 },
  quantity: { type: Number, required: true, min: 1 },
  subtotal: { type: Number, required: true, min: 0 },
});

const DeliveryAddressSchema = new Schema({
  full_name: { type: String, required: true, trim: true },
  phone: { type: String, required: true, trim: true },
  address_line1: { type: String, required: true, trim: true },
  address_line2: { type: String, trim: true, default: '' },
  city: { type: String, required: true, trim: true },
  state: { type: String, required: true, trim: true },
  pincode: { type: String, required: true, trim: true },
  country: { type: String, default: 'India', trim: true },
});

const BillingAddressSchema = new Schema({
  full_name: { type: String, required: true, trim: true },
  phone: { type: String, required: true, trim: true },
  address_line1: { type: String, required: true, trim: true },
  address_line2: { type: String, trim: true, default: '' },
  city: { type: String, required: true, trim: true },
  state: { type: String, required: true, trim: true },
  pincode: { type: String, required: true, trim: true },
  country: { type: String, default: 'India', trim: true },
});

const OrderSchema: Schema = new Schema(
  {
    order_id: {
      type: String,
      unique: true,
      trim: true,
      index: true, // Add index here instead of separate index() call
    },
    customer_id: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User',
      default: null,
    },
    guest_id: {
      type: String,
      default: null,
      trim: true,
      index: true, // Add index here
    },
    customer_name: { 
      type: String, 
      required: [true, 'Customer name is required'], 
      trim: true 
    },
    customer_phone: { 
      type: String, 
      required: [true, 'Customer phone is required'], 
      trim: true 
    },
    customer_email: { 
      type: String, 
      required: [true, 'Customer email is required'], 
      trim: true, 
      lowercase: true,
      index: true, // Add index here
    },
    items: {
      type: [OrderItemSchema],
      required: [true, 'Items are required'],
      validate: {
        validator: (v: IOrderItem[]) => v && v.length > 0,
        message: 'Order must have at least one item',
      },
    },
    delivery_address: {
      type: DeliveryAddressSchema,
      required: [true, 'Delivery address is required'],
    },
    billing_address: {
      type: BillingAddressSchema,
      required: [true, 'Billing address is required'],
    },
    payment_status: {
      type: String,
      enum: ['pending', 'paid', 'failed', 'refunded'],
      default: 'pending',
    },
    payment_method: {
      type: String,
      enum: ['cod', 'online', 'upi'],
      required: [true, 'Payment method is required'],
      default: 'cod',
    },
    payment_id: { 
      type: String,
      trim: true 
    },
    subtotal: { 
      type: Number, 
      required: [true, 'Subtotal is required'], 
      min: 0 
    },
    shipping_charge: { 
      type: Number, 
      default: 0,
      min: 0 
    },
    discount: { 
      type: Number, 
      default: 0,
      min: 0 
    },
    total_amount: { 
      type: Number, 
      required: [true, 'Total amount is required'], 
      min: 0 
    },
    order_status: {
      type: String,
      enum: ['pending', 'processing', 'shipped', 'delivered', 'cancelled'],
      default: 'pending',
      index: true, // Add index here
    },
    shipment_id: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Shipment',
    },
    device: {
      type: String,
      enum: ['website', 'mobile', 'admin'],
      default: 'website',
    },
    order_placed_at: {
      type: Date,
      default: Date.now,
      index: true, // Add index here
    },
  },
  { 
    timestamps: true,
    toJSON: { virtuals: true },
    toObject: { virtuals: true }
  }
);

// Remove duplicate index definitions - only keep compound indexes if needed
// Compound index for filtering
OrderSchema.index({ order_status: 1, order_placed_at: -1 });
OrderSchema.index({ customer_id: 1, order_placed_at: -1 });
OrderSchema.index({ guest_id: 1, order_placed_at: -1 });

// Auto-generate Order ID before validation - FIXED: use regular function
OrderSchema.pre('validate', function () {
  if (!this.order_id) {
    const timestamp = Date.now().toString();
    const random = Math.random()
      .toString(36)
      .substring(2, 8)
      .toUpperCase();

    this.order_id = `DS${timestamp}${random}`;
  }
});

// Remove the duplicate index definitions that were below
// The indexes are now defined either in the schema fields or as compound indexes above

export default mongoose.models.Order || mongoose.model<IOrder>('Order', OrderSchema);