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

export interface IExtensionLog {
  extendedBy: mongoose.Types.ObjectId;
  extendedAt: Date;
  previousExpiryDate: Date;
  newExpiryDate: Date;
  reason?: string;
}

export interface IChapterProgress {
  chapterId: mongoose.Types.ObjectId;
  completedAt: Date;
}

export interface ISubscription extends Document {
  student: mongoose.Types.ObjectId;
  course: mongoose.Types.ObjectId;
  lessons: mongoose.Types.ObjectId[];
  order?: mongoose.Types.ObjectId;
  startDate: Date;
  expiryDate: Date;
  status: 'active' | 'expired' | 'manually_extended' | 'revoked';
  manualExtensionLogs: IExtensionLog[];
  completedChapters: IChapterProgress[];
  lastWatchedChapter?: mongoose.Types.ObjectId;
  lastWatchedPositionSeconds: number;
  completedPercent: number;
  createdAt: Date;
  updatedAt: Date;
  isAccessValid(): boolean;
}

const ExtensionLogSchema = new Schema<IExtensionLog>(
  {
    extendedBy: {
      type: Schema.Types.ObjectId,
      ref: 'Admin',
      required: true,
    },
    extendedAt: {
      type: Date,
      default: Date.now,
    },
    previousExpiryDate: {
      type: Date,
      required: true,
    },
    newExpiryDate: {
      type: Date,
      required: true,
    },
    reason: {
      type: String,
      trim: true,
    },
  },
  { _id: false }
);

const ChapterProgressSchema = new Schema<IChapterProgress>(
  {
    chapterId: {
      type: Schema.Types.ObjectId,
      required: true,
    },
    completedAt: {
      type: Date,
      default: Date.now,
    },
  },
  { _id: false }
);

const SubscriptionSchema: Schema<ISubscription> = new Schema(
  {
    student: {
      type: Schema.Types.ObjectId,
      ref: 'Student',
      required: [true, 'Student reference is required'],
      index: true,
    },
    course: {
      type: Schema.Types.ObjectId,
      ref: 'Course',
      required: [true, 'Course reference is required'],
      index: true,
    },
    lessons: [
      {
        type: Schema.Types.ObjectId,
        ref: 'Lesson',
        default: [],
      },
    ],
    order: {
      type: Schema.Types.ObjectId,
      ref: 'Order',
    },
    startDate: {
      type: Date,
      default: Date.now,
    },
    expiryDate: {
      type: Date,
      required: [true, 'Expiry date is required'],
      index: true,
    },
    status: {
      type: String,
      enum: {
        values: ['active', 'expired', 'manually_extended', 'revoked'],
        message: '{VALUE} is not a valid subscription status',
      },
      default: 'active',
      index: true,
    },
    manualExtensionLogs: [ExtensionLogSchema],
    completedChapters: [ChapterProgressSchema],
    lastWatchedChapter: {
      type: Schema.Types.ObjectId,
    },
    lastWatchedPositionSeconds: {
      type: Number,
      default: 0,
    },
    completedPercent: {
      type: Number,
      default: 0,
      min: 0,
      max: 100,
    },
  },
  {
    timestamps: true,
  }
);

// Compound index to quickly find student course access
SubscriptionSchema.index({ student: 1, course: 1 });
SubscriptionSchema.index({ expiryDate: 1, status: 1 });

// Helper to check if subscription is currently valid
SubscriptionSchema.methods.isAccessValid = function (): boolean {
  if (this.status === 'revoked') return false;
  return new Date() < this.expiryDate;
};

// Delete cached model to force Mongoose to register updated schema with all references
if (mongoose.models && mongoose.models.Subscription) {
  delete (mongoose.models as any).Subscription;
}

export const Subscription: Model<ISubscription> =
  mongoose.models.Subscription || mongoose.model<ISubscription>('Subscription', SubscriptionSchema);

export default Subscription;
