const mongoose = require('mongoose');

const notificationSchema = new mongoose.Schema({
    // User who will receive the notification
    userId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: true,
        index: true
    },
    
    // User who triggered the notification (can be null for system notifications)
    fromUserId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        default: null
    },
    
    // Type of notification
    type: {
        type: String,
        required: true,
        enum: [
            'follow_request',    // Someone sent a follow request
            'follow_accepted',   // Follow request was accepted
            'follow_declined',   // Follow request was declined
            'post_like',         // Someone liked your post
            'post_comment',      // Someone commented on your post
            'cuts_like',         // Someone liked your cut
            'cuts_comment'       // Someone commented on your cut
        ],
        index: true
    },
    
    // Title of the notification
    title: {
        type: String,
        required: true,
        maxlength: [200, 'Title cannot exceed 200 characters']
    },
    
    // Message content of the notification
    message: {
        type: String,
        required: true,
        maxlength: [500, 'Message cannot exceed 500 characters']
    },
    
    // Related data (post ID, cut ID, etc.)
    relatedData: {
        postId: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Post',
            default: null
        },
        cutId: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Cut',
            default: null
        },
        followId: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Follower',
            default: null
        },
        commentId: {
            type: mongoose.Schema.Types.ObjectId,
            default: null
        }
    },
    
    // Notification status
    isRead: {
        type: Boolean,
        default: false,
        index: true
    },
    
    // Notification priority (for sorting)
    priority: {
        type: String,
        enum: ['low', 'medium', 'high'],
        default: 'medium'
    },
    
    // Additional metadata
    metadata: {
        // For follow notifications
        followStatus: {
            type: String,
            enum: ['requested', 'accepted', 'declined'],
            default: null
        },
        
        // For post/cut notifications
        actionCount: {
            type: Number,
            default: 1 // Number of likes/comments if aggregated
        },
        
        // Device/platform info
        platform: {
            type: String,
            enum: ['web', 'mobile', 'api'],
            default: 'api'
        }
    }
}, {
    timestamps: true
});

// Indexes for better performance
notificationSchema.index({ userId: 1, isRead: 1, createdAt: -1 });
notificationSchema.index({ userId: 1, type: 1, createdAt: -1 });
notificationSchema.index({ fromUserId: 1, type: 1 });
notificationSchema.index({ createdAt: -1 });

// Virtual for notification age
notificationSchema.virtual('age').get(function() {
    const now = new Date();
    const created = this.createdAt;
    const diffMs = now - created;
    
    if (diffMs < 60000) return 'just now';
    if (diffMs < 3600000) return `${Math.floor(diffMs / 60000)}m ago`;
    if (diffMs < 86400000) return `${Math.floor(diffMs / 3600000)}h ago`;
    if (diffMs < 604800000) return `${Math.floor(diffMs / 86400000)}d ago`;
    return `${Math.floor(diffMs / 604800000)}w ago`;
});

// Static method to create follow request notification
notificationSchema.statics.createFollowRequestNotification = async function(followerId, followingId, followId) {
    try {
        const User = require('./User');
        const follower = await User.findById(followerId).select('name profileImage');
        
        if (!follower) {
            throw new Error('Follower not found');
        }
        
        const notification = new this({
            userId: followingId,
            fromUserId: followerId,
            type: 'follow_request',
            title: 'New Follow Request',
            message: `${follower.name} wants to follow you`,
            relatedData: { followId },
            priority: 'high',
            metadata: {
                followStatus: 'requested',
                platform: 'api'
            }
        });
        
        await notification.save();
        console.log(`📢 [NOTIFICATION] Follow request notification created for user ${followingId}`);
        return notification;
        
    } catch (error) {
        console.error('❌ [NOTIFICATION] Error creating follow request notification:', error);
        throw error;
    }
};

// Static method to create follow accepted notification
notificationSchema.statics.createFollowAcceptedNotification = async function(followerId, followingId, followId) {
    try {
        const User = require('./User');
        const following = await User.findById(followingId).select('name profileImage');
        
        if (!following) {
            throw new Error('Following user not found');
        }
        
        const notification = new this({
            userId: followerId,
            fromUserId: followingId,
            type: 'follow_accepted',
            title: 'Follow Request Accepted',
            message: `${following.name} accepted your follow request`,
            relatedData: { followId },
            priority: 'high',
            metadata: {
                followStatus: 'accepted',
                platform: 'api'
            }
        });
        
        await notification.save();
        console.log(`📢 [NOTIFICATION] Follow accepted notification created for user ${followerId}`);
        return notification;
        
    } catch (error) {
        console.error('❌ [NOTIFICATION] Error creating follow accepted notification:', error);
        throw error;
    }
};

// Static method to create follow declined notification
notificationSchema.statics.createFollowDeclinedNotification = async function(followerId, followingId, followId) {
    try {
        const User = require('./User');
        const following = await User.findById(followingId).select('name profileImage');
        
        if (!following) {
            throw new Error('Following user not found');
        }
        
        const notification = new this({
            userId: followerId,
            fromUserId: followingId,
            type: 'follow_declined',
            title: 'Follow Request Declined',
            message: `${following.name} declined your follow request`,
            relatedData: { followId },
            priority: 'medium',
            metadata: {
                followStatus: 'declined',
                platform: 'api'
            }
        });
        
        await notification.save();
        console.log(`📢 [NOTIFICATION] Follow declined notification created for user ${followerId}`);
        return notification;
        
    } catch (error) {
        console.error('❌ [NOTIFICATION] Error creating follow declined notification:', error);
        throw error;
    }
};

// Static method to create post like notification
notificationSchema.statics.createPostLikeNotification = async function(userId, postId, likerId) {
    try {
        const User = require('./User');
        const Post = require('./Post');
        
        const [liker, post] = await Promise.all([
            User.findById(likerId).select('name profileImage'),
            Post.findById(postId).select('userId')
        ]);
        
        if (!liker || !post) {
            throw new Error('User or post not found');
        }
        
        // Don't notify if user likes their own post
        if (post.userId.toString() === likerId.toString()) {
            return null;
        }
        
        const notification = new this({
            userId: post.userId,
            fromUserId: likerId,
            type: 'post_like',
            title: 'Post Liked',
            message: `${liker.name} liked your post`,
            relatedData: { postId },
            priority: 'medium',
            metadata: {
                actionCount: 1,
                platform: 'api'
            }
        });
        
        await notification.save();
        console.log(`📢 [NOTIFICATION] Post like notification created for user ${post.userId}`);
        return notification;
        
    } catch (error) {
        console.error('❌ [NOTIFICATION] Error creating post like notification:', error);
        throw error;
    }
};

// Static method to create post comment notification
notificationSchema.statics.createPostCommentNotification = async function(userId, postId, commenterId, commentId) {
    try {
        const User = require('./User');
        const Post = require('./Post');
        
        const [commenter, post] = await Promise.all([
            User.findById(commenterId).select('name profileImage'),
            Post.findById(postId).select('userId')
        ]);
        
        if (!commenter || !post) {
            throw new Error('User or post not found');
        }
        
        // Don't notify if user comments on their own post
        if (post.userId.toString() === commenterId.toString()) {
            return null;
        }
        
        const notification = new this({
            userId: post.userId,
            fromUserId: commenterId,
            type: 'post_comment',
            title: 'New Comment',
            message: `${commenter.name} commented on your post`,
            relatedData: { postId, commentId },
            priority: 'medium',
            metadata: {
                actionCount: 1,
                platform: 'api'
            }
        });
        
        await notification.save();
        console.log(`📢 [NOTIFICATION] Post comment notification created for user ${post.userId}`);
        return notification;
        
    } catch (error) {
        console.error('❌ [NOTIFICATION] Error creating post comment notification:', error);
        throw error;
    }
};

// Static method to create cuts like notification
notificationSchema.statics.createCutsLikeNotification = async function(userId, cutId, likerId) {
    try {
        const User = require('./User');
        const Cut = require('./Cut');
        
        const [liker, cut] = await Promise.all([
            User.findById(likerId).select('name profileImage'),
            Cut.findById(cutId).select('userId')
        ]);
        
        if (!liker || !cut) {
            throw new Error('User or cut not found');
        }
        
        // Don't notify if user likes their own cut
        if (cut.userId.toString() === likerId.toString()) {
            return null;
        }
        
        const notification = new this({
            userId: cut.userId,
            fromUserId: likerId,
            type: 'cuts_like',
            title: 'Cut Liked',
            message: `${liker.name} liked your cut`,
            relatedData: { cutId },
            priority: 'medium',
            metadata: {
                actionCount: 1,
                platform: 'api'
            }
        });
        
        await notification.save();
        console.log(`📢 [NOTIFICATION] Cut like notification created for user ${cut.userId}`);
        return notification;
        
    } catch (error) {
        console.error('❌ [NOTIFICATION] Error creating cut like notification:', error);
        throw error;
    }
};

// Static method to create cuts comment notification
notificationSchema.statics.createCutsCommentNotification = async function(userId, cutId, commenterId, commentId) {
    try {
        const User = require('./User');
        const Cut = require('./Cut');
        
        const [commenter, cut] = await Promise.all([
            User.findById(commenterId).select('name profileImage'),
            Cut.findById(cutId).select('userId')
        ]);
        
        if (!commenter || !cut) {
            throw new Error('User or cut not found');
        }
        
        // Don't notify if user comments on their own cut
        if (cut.userId.toString() === commenterId.toString()) {
            return null;
        }
        
        const notification = new this({
            userId: cut.userId,
            fromUserId: commenterId,
            type: 'cuts_comment',
            title: 'New Comment',
            message: `${commenter.name} commented on your cut`,
            relatedData: { cutId, commentId },
            priority: 'medium',
            metadata: {
                actionCount: 1,
                platform: 'api'
            }
        });
        
        await notification.save();
        console.log(`📢 [NOTIFICATION] Cut comment notification created for user ${cut.userId}`);
        return notification;
        
    } catch (error) {
        console.error('❌ [NOTIFICATION] Error creating cut comment notification:', error);
        throw error;
    }
};

// Method to mark notification as read
notificationSchema.methods.markAsRead = function() {
    this.isRead = true;
    return this.save();
};

// Method to get notification summary
notificationSchema.methods.getSummary = function() {
    return {
        id: this._id,
        type: this.type,
        title: this.title,
        message: this.message,
        isRead: this.isRead,
        priority: this.priority,
        age: this.age,
        createdAt: this.createdAt
    };
};

module.exports = mongoose.model('Notification', notificationSchema);
