import mongoose, { Document, Model, Schema } from 'mongoose';
import './Student';
import './Course';
import './Lesson';
import './Admin';

export interface IBankTransferDetails {
  proofOfPaymentUrl?: string;
  paymentScreenshot?: string;
  paymentScreenShot?: string;
  senderAccountName?: string;
  senderBank?: string;
  accountHolder?: string;
  iban?: string;
  bicSwift?: string;
  bankName?: string;
  reference?: string;
  adminConfirmationStatus: 'pending' | 'approved' | 'rejected';
  confirmedBy?: mongoose.Types.ObjectId;
  confirmedAt?: Date;
  adminNotes?: string;
}

export interface IOrder extends Document {
  student: mongoose.Types.ObjectId;
  courseId: mongoose.Types.ObjectId; // Compulsory reference to selected course
  lessons: mongoose.Types.ObjectId[]; // Array of selected Lesson refs (empty if complete course)
  gateway: 'stripe' | 'paypal' | 'bank_transfer' | 'admin_bypass';
  gatewayTransactionId?: string;
  gatewayResponse?: Record<string, any>; // Raw gateway payload for audit and debugging
  amount: number;
  currency: string;
  status: 'initiated' | 'pending' | 'succeeded' | 'failed' | 'refunded';
  paymentRequired?: boolean;
  bankTransferDetails?: IBankTransferDetails;
  initiatedAt: Date;
  confirmedAt?: Date;
  createdAt: Date;
  updatedAt: Date;
}

const BankTransferDetailsSchema = new Schema<IBankTransferDetails>(
  {
    proofOfPaymentUrl: {
      type: String,
      trim: true,
    },
    paymentScreenshot: {
      type: String,
      trim: true,
    },
    paymentScreenShot: {
      type: String,
      trim: true,
    },
    senderAccountName: {
      type: String,
      trim: true,
    },
    senderBank: {
      type: String,
      trim: true,
    },
    accountHolder: {
      type: String,
      trim: true,
    },
    iban: {
      type: String,
      trim: true,
    },
    bicSwift: {
      type: String,
      trim: true,
    },
    bankName: {
      type: String,
      trim: true,
    },
    reference: {
      type: String,
      trim: true,
    },
    adminConfirmationStatus: {
      type: String,
      enum: {
        values: ['pending', 'approved', 'rejected'],
        message: '{VALUE} is not a valid confirmation status',
      },
      default: 'pending',
    },
    confirmedBy: {
      type: Schema.Types.ObjectId,
      ref: 'Admin',
    },
    confirmedAt: {
      type: Date,
    },
    adminNotes: {
      type: String,
      trim: true,
    },
  },
  { _id: false }
);

const OrderSchema: Schema<IOrder> = new Schema(
  {
    student: {
      type: Schema.Types.ObjectId,
      ref: 'Student',
      required: [true, 'Student reference is required'],
      index: true,
    },
    courseId: {
      type: Schema.Types.ObjectId,
      ref: 'Course',
      required: [true, 'Course reference is required'],
      index: true,
    },
    lessons: [
      {
        type: Schema.Types.ObjectId,
        ref: 'Lesson',
        default: [],
      },
    ],
    gateway: {
      type: String,
      enum: {
        values: ['stripe', 'paypal', 'bank_transfer', 'admin_bypass'],
        message: '{VALUE} is not a valid gateway',
      },
      required: [true, 'Payment gateway is required'],
      index: true,
    },
    gatewayTransactionId: {
      type: String,
      trim: true,
      index: true,
    },
    gatewayResponse: {
      type: Schema.Types.Mixed,
      default: {},
    },
    amount: {
      type: Number,
      required: [true, 'Order amount is required'],
      min: [0, 'Amount cannot be negative'],
    },
    currency: {
      type: String,
      default: 'EUR',
      uppercase: true,
    },
    paymentRequired: {
      type: Boolean,
      default: true,
    },
    status: {
      type: String,
      enum: {
        values: ['initiated', 'pending', 'succeeded', 'failed', 'refunded'],
        message: '{VALUE} is not a valid order status',
      },
      default: 'initiated',
      index: true,
    },
    bankTransferDetails: {
      type: BankTransferDetailsSchema,
      default: () => ({
        adminConfirmationStatus: 'pending',
      }),
    },
    initiatedAt: {
      type: Date,
      default: Date.now,
    },
    confirmedAt: {
      type: Date,
    },
  },
  {
    timestamps: true,
  }
);

// Indexes
OrderSchema.index({ gateway: 1, status: 1 });
OrderSchema.index({ 'bankTransferDetails.adminConfirmationStatus': 1 });

// Delete cached model to force Mongoose to register updated schema with courseId and lessons fields
if (mongoose.models && mongoose.models.Order) {
  delete (mongoose.models as any).Order;
}

export const Order: Model<IOrder> = mongoose.model<IOrder>('Order', OrderSchema);

export default Order;
