const mongoose = require('mongoose');

const commentSchema = new mongoose.Schema({
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
  content: {
    type: String,
    required: [true, 'Comment content is required'],
    trim: true,
    maxlength: [500, 'Comment cannot exceed 500 characters']
  },
  likes: [{
    
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User'
  }],
  replies: [{
    user: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User',
      required: true
    },
    content: {
      type: String,
      required: true,
      trim: true,
      maxlength: [300, 'Reply cannot exceed 300 characters']
    },
    createdAt: {
      type: Date,
      default: Date.now
    }
  }]
}, {
  timestamps: true
});

const mediaSchema = new mongoose.Schema({
  type: {
    type: String,
    enum: ['image', 'video'],
    required: true
  },
  // File path on server
  filePath: {
    type: String,
    required: true
  },
  // Public URL for accessing the file
  url: {
    type: String,
    required: true
  },
  // Original file information
  originalName: {
    type: String,
    required: true
  },
  size: {
    type: Number,
    required: true
  },
  mimeType: {
    type: String,
    required: true
  },
  // Image dimensions
  width: {
    type: Number,
    default: null
  },
  height: {
    type: Number,
    default: null
  },
  // Compression info
  compressed: {
    type: Boolean,
    default: false
  },
  originalSize: {
    type: Number,
    default: null
  },
  // Thumbnail for videos
  thumbnail: {
    type: String,
    required: false
  },
  // File hash for integrity
  fileHash: {
    type: String,
    required: false
  }
});

const postSchema = new mongoose.Schema({
  title: {
    type: String,
    required: [true, 'Post title is required'],
    trim: true,
    maxlength: [200, 'Title cannot exceed 200 characters']
  },
  description: {
    type: String,
    required: [true, 'Post description is required'],
    trim: true,
    maxlength: [2000, 'Description cannot exceed 2000 characters']
  },
  author: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
  media: [mediaSchema], // Array of images/videos
  likes: [{
    user: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User',
      required: true
    },
    likedAt: {
      type: Date,
      default: Date.now
    }
  }],
  comments: [commentSchema],
  shares: [{
    user: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User',
      required: true
    },
    sharedAt: {
      type: Date,
      default: Date.now
    },
    platform: {
      type: String,
      enum: ['facebook', 'twitter', 'linkedin', 'whatsapp', 'copy_link'],
      default: 'copy_link'
    }
  }],
  tags: [{
    type: String,
    trim: true,
    lowercase: true
  }],
  hashtags: [{
    type: String,
    trim: true,
    lowercase: true,
    validate: {
      validator: function(v) {
        return /^#[a-zA-Z0-9_]+$/.test(v);
      },
      message: 'Hashtag must start with # and contain only letters, numbers, and underscores'
    }
  }],
  type: {
    type: String,
    enum: ['text', 'image', 'video', 'link', 'poll', 'event', 'announcement'],
    default: 'text'
  },
  category: {
    type: String,
    enum: ['general', 'announcement', 'event', 'news', 'promotion', 'educational'],
    default: 'general'
  },
  visibility: {
    type: String,
    enum: ['public', 'private', 'friends_only'],
    default: 'public'
  },
  interests: [{
    type: String,
    trim: true,
    validate: {
      validator: function(v) {
        // Validate that interest exists in the Interests collection
        return v && v.length > 0;
      },
      message: 'Interest name is required'
    }
  }],
  isActive: {
    type: Boolean,
    default: true
  },
  isPinned: {
    type: Boolean,
    default: false
  },
  viewCount: {
    type: Number,
    default: 0
  },
  engagement: {
    totalLikes: {
      type: Number,
      default: 0
    },
    totalComments: {
      type: Number,
      default: 0
    },
    totalShares: {
      type: Number,
      default: 0
    },
    totalViews: {
      type: Number,
      default: 0
    }
  }
}, {
  timestamps: true
});

// Indexes for better performance
postSchema.index({ author: 1, createdAt: -1 });
postSchema.index({ category: 1, createdAt: -1 });
postSchema.index({ type: 1, createdAt: -1 });
postSchema.index({ tags: 1 });
postSchema.index({ hashtags: 1 });
postSchema.index({ interests: 1 });
postSchema.index({ 'likes.user': 1 });
postSchema.index({ 'comments.user': 1 });
postSchema.index({ isActive: 1, visibility: 1 });

// Virtual for like count
postSchema.virtual('likeCount').get(function() {
  return this.likes.length;
});

// Virtual for comment count
postSchema.virtual('commentCount').get(function() {
  return this.comments.length;
});

// Virtual for share count
postSchema.virtual('shareCount').get(function() {
  return this.shares.length;
});

// Virtual for media count
postSchema.virtual('mediaCount').get(function() {
  return this.media.length;
});

// Method to add like
postSchema.methods.addLike = function(userId) {
  const existingLike = this.likes.find(like => like.user.toString() === userId.toString());
  if (!existingLike) {
    this.likes.push({ user: userId });
    this.engagement.totalLikes = this.likes.length;
    return this.save();
  }
  return Promise.resolve(this);
};

// Method to remove like
postSchema.methods.removeLike = function(userId) {
  this.likes = this.likes.filter(like => like.user.toString() !== userId.toString());
  this.engagement.totalLikes = this.likes.length;
  return this.save();
};

// Method to add comment
postSchema.methods.addComment = function(userId, content) {
  this.comments.push({ user: userId, content });
  this.engagement.totalComments = this.comments.length;
  return this.save();
};

// Method to add share
postSchema.methods.addShare = function(userId, platform = 'copy_link') {
  this.shares.push({ user: userId, platform });
  this.engagement.totalShares = this.shares.length;
  return this.save();
};

// Method to increment view count
postSchema.methods.incrementView = function() {
  this.viewCount += 1;
  this.engagement.totalViews = this.viewCount;
  return this.save();
};

// Pre-save middleware to update engagement metrics
postSchema.pre('save', function(next) {
  this.engagement.totalLikes = this.likes.length;
  this.engagement.totalComments = this.comments.length;
  this.engagement.totalShares = this.shares.length;
  this.engagement.totalViews = this.viewCount;
  next();
});

// Ensure virtual fields are serialized
postSchema.set('toJSON', { virtuals: true });
postSchema.set('toObject', { virtuals: true });

module.exports = mongoose.model('Post', postSchema);
