const mongoose = require('mongoose');

const newsSchema = new mongoose.Schema({
    title: {
        type: String,
        required: [true, 'Title is required'],
        trim: true,
        maxlength: [500, 'Title cannot exceed 500 characters']
    },
    
    description: {
        type: String,
        trim: true,
        maxlength: [2000, 'Description cannot exceed 2000 characters']
    },
    
    content: {
        type: String,
        trim: true
    },
    
    url: {
        type: String,
        required: [true, 'URL is required'],
        trim: true,
        unique: true
    },
    
    imageUrl: {
        type: String,
        trim: true
    },
    
    source: {
        type: String,
        required: [true, 'Source is required'],
        enum: ['newsapi', 'currents', 'rss'],
        trim: true
    },
    
    sourceName: {
        type: String,
        required: [true, 'Source name is required'],
        trim: true
    },
    
    category: {
        type: String,
        required: [true, 'Category is required'],
        enum: [
            'career-and-skills',
            'technology',
            'startups-and-innovation',
            'education',
            'sports',
            'movies-and-entertainment',
            'business-and-economy',
            'politics',
            'astrology',
            'health-and-wellness',
            'environment-and-climate',
            'art-and-culture',
            'knowledge-bytes-and-facts',
            'jobs'
        ],
        trim: true
    },
    
    publishedAt: {
        type: Date,
        required: [true, 'Published date is required']
    },
    
    fetchedAt: {
        type: Date,
        default: Date.now
    },
    
    author: {
        type: String,
        trim: true,
        maxlength: [200, 'Author name cannot exceed 200 characters']
    },
    
    tags: [{
        type: String,
        trim: true,
        lowercase: true
    }],
    
    isActive: {
        type: Boolean,
        default: true
    },
    
    viewCount: {
        type: Number,
        default: 0
    },
    
    // For deduplication
    hash: {
        type: String,
        unique: true,
        required: false
    },
    
    // SEO and metadata
    metaDescription: {
        type: String,
        trim: true,
        maxlength: [160, 'Meta description cannot exceed 160 characters']
    },
    
    // Content quality indicators
    wordCount: {
        type: Number,
        default: 0
    },
    
    readingTime: {
        type: Number, // in minutes
        default: 0
    }
}, {
    timestamps: true
});

// Indexes for better query performance
newsSchema.index({ category: 1, publishedAt: -1 });
newsSchema.index({ source: 1, publishedAt: -1 });
newsSchema.index({ publishedAt: -1 });
newsSchema.index({ isActive: 1, publishedAt: -1 });
newsSchema.index({ hash: 1 });
newsSchema.index({ title: 'text', description: 'text', content: 'text' });

// Pre-save middleware to generate hash for deduplication
newsSchema.pre('save', function(next) {
    if (!this.hash) {
        // Create hash from title + source + publishedAt for deduplication
        const crypto = require('crypto');
        const hashString = `${this.title || ''}-${this.source || ''}-${this.publishedAt || ''}-${this.url || ''}`;
        this.hash = crypto.createHash('md5').update(hashString).digest('hex');
    }
    next();
});

// Method to calculate reading time
newsSchema.methods.calculateReadingTime = function() {
    if (this.content) {
        const wordsPerMinute = 200; // Average reading speed
        const wordCount = this.content.split(/\s+/).length;
        this.wordCount = wordCount;
        this.readingTime = Math.ceil(wordCount / wordsPerMinute);
    }
    return this.readingTime;
};

// Static method to get news by category with pagination
newsSchema.statics.getByCategory = function(category, page = 1, limit = 20) {
    const skip = (page - 1) * limit;
    return this.find({ 
        category: category, 
        isActive: true 
    })
    .sort({ publishedAt: -1 })
    .skip(skip)
    .limit(limit);
};

// Static method to search news
newsSchema.statics.searchNews = function(query, page = 1, limit = 20) {
    const skip = (page - 1) * limit;
    return this.find({
        $and: [
            { isActive: true },
            {
                $or: [
                    { title: { $regex: query, $options: 'i' } },
                    { description: { $regex: query, $options: 'i' } },
                    { content: { $regex: query, $options: 'i' } },
                    { tags: { $in: [new RegExp(query, 'i')] } }
                ]
            }
        ]
    })
    .sort({ publishedAt: -1 })
    .skip(skip)
    .limit(limit);
};

// Virtual for formatted published date
newsSchema.virtual('formattedPublishedAt').get(function() {
    return this.publishedAt.toLocaleDateString('en-US', {
        year: 'numeric',
        month: 'long',
        day: 'numeric',
        hour: '2-digit',
        minute: '2-digit'
    });
});

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

module.exports = mongoose.model('News', newsSchema);
