const mongoose = require("mongoose");

const therapyPlanSchema = new mongoose.Schema({
  // Client and Therapist Information
  client: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
    required: true,
    index: true
  },
  therapist: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
    required: true,
    index: true
  },
  
  // Plan Details
  title: {
    type: String,
    required: true,
    maxlength: 200
  },
  
  // Goals for the therapy plan
  goals: [{
    type: String,
    required: true,
    enum: [
      "Reduce Symptoms of Anxiety",
      "Increase Self-Esteem and Self-worth",
      "Strengthen Family Dynamics",
      "Improve Coping Skills",
      "Reduce Symptoms of Anxiety",
      "Increase Healthy Relationships",
      "Decrease Healthy Relationships",
      "Promote Emotional Regulation",
      "Enhance Stress Skills",
      "Other"
    ]
  }],
  
  customGoals: [{
    type: String,
    maxlength: 500
  }],
  
  // Therapeutic Approaches
  approaches: [{
    type: String,
    required: true,
    enum: [
      "Humanistic Therapy",
      "Gestalt Therapy",
      "Family Therapy",
      "Cognitive Behavioral Therapy",
      "Client-Centered Therapy",
      "Interpersonal Therapy",
      "Humanistic Therapy",
      "Other"
    ]
  }],
  
  customApproaches: [{
    type: String,
    maxlength: 500
  }],
  
  // Session Planning
  numberOfSessions: {
    type: Number,
    required: true,
    min: 1,
    max: 50
  },
  
  timeline: {
    type: String,
    required: true,
    enum: ["Weekly", "Bi-weekly", "Monthly", "Custom"]
  },
  
  customTimeline: {
    type: String,
    maxlength: 200
  },
  
  // Plan Status Tracking
  planStatus: {
    type: String,
    enum: [
      "Plan Not Sent",
      "Draft Created", 
      "Plan Sent",
      "Plan Accepted- Individual",
      "Plan Accepted- Package",
      "No Response (7+ Days)",
      "Client Didn't Show"
    ],
    default: "Plan Not Sent"
  },
  
  // Client Response
  clientResponse: {
    type: String,
    enum: [
      "Accepted",
      "Rejected", 
      "No Response",
      "Currently Under Discussion",
      "Didn't Attend Session (prevents plan acceptance)"
    ],
    default: "No Response"
  },
  
  // Plan Content
  description: {
    type: String,
    maxlength: 2000
  },
  
  // Session tracking
  sessionsCompleted: {
    type: Number,
    default: 0,
    min: 0
  },
  
  // Dates
  planSentDate: {
    type: Date,
    default: null
  },
  
  clientResponseDate: {
    type: Date,
    default: null
  },
  
  planAcceptedDate: {
    type: Date,
    default: null
  },
  
  // Auto-archive after 7 days of no response
  autoArchiveDate: {
    type: Date,
    default: null
  },
  
  // Notes and additional information
  therapistNotes: {
    type: String,
    maxlength: 1000
  },
  
  clientNotes: {
    type: String,
    maxlength: 1000
  },
  
  // Plan modifications history
  modifications: [{
    modifiedBy: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "User",
      required: true
    },
    modificationDate: {
      type: Date,
      default: Date.now
    },
    changes: {
      type: mongoose.Schema.Types.Mixed
    },
    reason: {
      type: String,
      maxlength: 500
    }
  }],
  
  // Active status
  isActive: {
    type: Boolean,
    default: true
  },
  
  // Archive status
  isArchived: {
    type: Boolean,
    default: false
  },
  
  archivedDate: {
    type: Date,
    default: null
  },
  
  archivedReason: {
    type: String,
    maxlength: 500
  }
  
}, { 
  timestamps: true,
  toJSON: { virtuals: true },
  toObject: { virtuals: true }
});

// Indexes for better performance
therapyPlanSchema.index({ client: 1, therapist: 1 });
therapyPlanSchema.index({ planStatus: 1 });
therapyPlanSchema.index({ clientResponse: 1 });
therapyPlanSchema.index({ isActive: 1, isArchived: 1 });
therapyPlanSchema.index({ createdAt: -1 });

// Virtual for plan progress percentage
therapyPlanSchema.virtual('progressPercentage').get(function() {
  if (this.numberOfSessions === 0) return 0;
  return Math.round((this.sessionsCompleted / this.numberOfSessions) * 100);
});

// Virtual for days since plan sent
therapyPlanSchema.virtual('daysSincePlanSent').get(function() {
  if (!this.planSentDate) return null;
  const now = new Date();
  const diffTime = Math.abs(now - this.planSentDate);
  return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
});

// Pre-save middleware to handle status changes and auto-archive logic
therapyPlanSchema.pre('save', function(next) {
  // Set plan sent date when status changes to "Plan Sent"
  if (this.isModified('planStatus') && this.planStatus === 'Plan Sent' && !this.planSentDate) {
    this.planSentDate = new Date();
    // Set auto-archive date to 7 days from now
    this.autoArchiveDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
  }
  
  // Set client response date when client responds
  if (this.isModified('clientResponse') && this.clientResponse !== 'No Response' && !this.clientResponseDate) {
    this.clientResponseDate = new Date();
  }
  
  // Set plan accepted date and update status when client accepts
  if (this.isModified('clientResponse') && 
      (this.clientResponse === 'Accepted') && 
      !this.planAcceptedDate) {
    this.planAcceptedDate = new Date();
    // Update plan status based on acceptance type (this would be set by the controller)
  }
  
  // Auto-archive logic for no response after 7 days
  if (this.planStatus === 'Plan Sent' && 
      this.clientResponse === 'No Response' && 
      this.autoArchiveDate && 
      new Date() > this.autoArchiveDate) {
    this.planStatus = 'No Response (7+ Days)';
  }
  
  next();
});

// Method to check if plan can be modified
therapyPlanSchema.methods.canBeModified = function() {
  return ['Plan Not Sent', 'Draft Created'].includes(this.planStatus);
};

// Method to check if plan is overdue for response
therapyPlanSchema.methods.isOverdueForResponse = function() {
  if (this.planStatus !== 'Plan Sent' || this.clientResponse !== 'No Response') {
    return false;
  }
  return this.autoArchiveDate && new Date() > this.autoArchiveDate;
};

// Method to send plan to client
therapyPlanSchema.methods.sendToClient = function() {
  if (!this.canBeModified()) {
    throw new Error('Plan cannot be sent in current status');
  }
  this.planStatus = 'Plan Sent';
  this.planSentDate = new Date();
  this.autoArchiveDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
  return this.save();
};

// Method to handle client acceptance
therapyPlanSchema.methods.acceptPlan = function(acceptanceType = 'Individual') {
  if (this.planStatus !== 'Plan Sent') {
    throw new Error('Plan must be sent before it can be accepted');
  }
  
  this.clientResponse = 'Accepted';
  this.clientResponseDate = new Date();
  this.planAcceptedDate = new Date();
  this.planStatus = acceptanceType === 'Package' ? 'Plan Accepted- Package' : 'Plan Accepted- Individual';
  
  return this.save();
};

// Method to handle client rejection
therapyPlanSchema.methods.rejectPlan = function(reason = '') {
  if (this.planStatus !== 'Plan Sent') {
    throw new Error('Plan must be sent before it can be rejected');
  }
  
  this.clientResponse = 'Rejected';
  this.clientResponseDate = new Date();
  if (reason) {
    this.clientNotes = reason;
  }
  
  return this.save();
};

// Method to archive plan
therapyPlanSchema.methods.archivePlan = function(reason = '') {
  this.isArchived = true;
  this.archivedDate = new Date();
  this.archivedReason = reason;
  this.isActive = false;
  
  return this.save();
};

// Static method to get plans by status
therapyPlanSchema.statics.findByStatus = function(status) {
  return this.find({ planStatus: status, isActive: true, isArchived: false });
};

// Static method to get overdue plans
therapyPlanSchema.statics.findOverduePlans = function() {
  const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
  return this.find({
    planStatus: 'Plan Sent',
    clientResponse: 'No Response',
    planSentDate: { $lte: sevenDaysAgo },
    isActive: true,
    isArchived: false
  });
};

module.exports = mongoose.model("TherapyPlan", therapyPlanSchema);
