const mongoose = require('mongoose');

const newsSourceSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, 'Source name is required'],
        unique: true,
        trim: true,
        maxlength: [100, 'Source name cannot exceed 100 characters']
    },
    
    type: {
        type: String,
        required: [true, 'Source type is required'],
        enum: ['newsapi', 'currents', 'rss'],
        trim: true
    },
    
    apiKey: {
        type: String,
        trim: true,
        select: false // Don't include in queries by default for security
    },
    
    baseUrl: {
        type: String,
        required: [true, 'Base URL is required'],
        trim: true
    },
    
    endpoint: {
        type: String,
        trim: true
    },
    
    // For RSS feeds
    rssUrl: {
        type: String,
        trim: true
    },
    
    // Rate limiting
    rateLimit: {
        requestsPerMinute: {
            type: Number,
            default: 60
        },
        requestsPerHour: {
            type: Number,
            default: 1000
        }
    },
    
    // Request tracking
    lastRequest: {
        type: Date
    },
    
    requestCount: {
        type: Number,
        default: 0
    },
    
    // Status
    isActive: {
        type: Boolean,
        default: true
    },
    
    isHealthy: {
        type: Boolean,
        default: true
    },
    
    lastError: {
        message: String,
        timestamp: Date
    },
    
    // Configuration
    categories: [{
        type: String,
        trim: true
    }],
    
    // Headers for API requests
    headers: {
        type: Map,
        of: String
    },
    
    // Timeout settings
    timeout: {
        type: Number,
        default: 30000 // 30 seconds
    },
    
    // Retry settings
    retryAttempts: {
        type: Number,
        default: 3
    },
    
    retryDelay: {
        type: Number,
        default: 1000 // 1 second
    },
    
    // Statistics
    totalArticles: {
        type: Number,
        default: 0
    },
    
    successRate: {
        type: Number,
        default: 100
    },
    
    averageResponseTime: {
        type: Number,
        default: 0
    }
}, {
    timestamps: true
});

// Index for better query performance
newsSourceSchema.index({ type: 1, isActive: 1 });
newsSourceSchema.index({ name: 1 });

// Pre-save middleware to update lastRequest
newsSourceSchema.pre('save', function(next) {
    if (this.isModified('requestCount')) {
        this.lastRequest = new Date();
    }
    next();
});

// Method to check if source can make request (rate limiting)
newsSourceSchema.methods.canMakeRequest = function() {
    if (!this.isActive || !this.isHealthy) {
        return false;
    }
    
    const now = new Date();
    const oneMinuteAgo = new Date(now.getTime() - 60 * 1000);
    const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
    
    // Simple rate limiting check (in production, use Redis)
    if (this.lastRequest && this.lastRequest > oneMinuteAgo) {
        return this.requestCount < this.rateLimit.requestsPerMinute;
    }
    
    return true;
};

// Method to record successful request
newsSourceSchema.methods.recordSuccess = function(responseTime) {
    this.requestCount += 1;
    this.lastRequest = new Date();
    this.isHealthy = true;
    this.lastError = null;
    
    // Update average response time
    if (this.averageResponseTime === 0) {
        this.averageResponseTime = responseTime;
    } else {
        this.averageResponseTime = (this.averageResponseTime + responseTime) / 2;
    }
    
    // Update success rate
    this.successRate = Math.min(100, this.successRate + 1);
    
    return this.save();
};

// Method to record failed request
newsSourceSchema.methods.recordFailure = function(error) {
    this.isHealthy = false;
    this.lastError = {
        message: error.message,
        timestamp: new Date()
    };
    
    // Update success rate
    this.successRate = Math.max(0, this.successRate - 5);
    
    return this.save();
};

// Static method to get active sources
newsSourceSchema.statics.getActiveSources = function() {
    return this.find({ isActive: true, isHealthy: true });
};

// Static method to get sources by type
newsSourceSchema.statics.getByType = function(type) {
    return this.find({ type: type, isActive: true });
};

// Method to reset rate limiting
newsSourceSchema.methods.resetRateLimit = function() {
    this.requestCount = 0;
    this.lastRequest = null;
    return this.save();
};

// Virtual for health status
newsSourceSchema.virtual('healthStatus').get(function() {
    if (!this.isActive) return 'inactive';
    if (!this.isHealthy) return 'unhealthy';
    if (this.successRate < 50) return 'poor';
    if (this.successRate < 80) return 'fair';
    return 'good';
});

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

module.exports = mongoose.model('NewsSource', newsSourceSchema);
