const { DataTypes } = require('sequelize');
const { sequelize } = require('../config/database');

const Notification = sequelize.define('Notification', {
  id: {
    type: DataTypes.UUID,
    defaultValue: DataTypes.UUIDV4,
    primaryKey: true
  },
  
  type: {
    type: DataTypes.ENUM(
      'payment_reminder',
      'payment_confirmation',
      'payment_overdue',
      'draw_result',
      'group_invite',
      'member_joined',
      'member_removed',
      'group_started',
      'group_completed',
      'welcome_message',
      'manager_notification',
      'system_alert'
    ),
    allowNull: false
  },
  
  user_id: {
    type: DataTypes.UUID,
    allowNull: false,
    references: {
      model: 'Users',
      key: 'id'
    }
  },
  
  group_id: {
    type: DataTypes.UUID,
    allowNull: true,
    references: {
      model: 'ChitGroups',
      key: 'id'
    }
  },
  
  payment_id: {
    type: DataTypes.UUID,
    allowNull: true,
    references: {
      model: 'Payments',
      key: 'id'
    }
  },
  
  draw_id: {
    type: DataTypes.UUID,
    allowNull: true,
    references: {
      model: 'MonthlyDraws',
      key: 'id'
    }
  },
  
  channel: {
    type: DataTypes.ENUM('email', 'sms', 'whatsapp', 'push', 'in_app'),
    allowNull: false
  },
  
  title: {
    type: DataTypes.STRING(255),
    allowNull: true
  },
  
  message: {
    type: DataTypes.TEXT,
    allowNull: false
  },
  
  status: {
    type: DataTypes.ENUM('pending', 'sent', 'delivered', 'failed', 'read'),
    defaultValue: 'pending'
  },
  
  days_before_due: {
    type: DataTypes.INTEGER,
    allowNull: true
  },
  
  priority: {
    type: DataTypes.ENUM('low', 'medium', 'high', 'urgent'),
    defaultValue: 'medium'
  },
  
  sent_at: {
    type: DataTypes.DATE,
    allowNull: true
  },
  
  read_at: {
    type: DataTypes.DATE,
    allowNull: true
  },
  
  failure_reason: {
    type: DataTypes.TEXT,
    allowNull: true
  },
  
  external_id: {
    type: DataTypes.STRING(255),
    allowNull: true
  },
  
  metadata: {
    type: DataTypes.JSONB,
    allowNull: true
  },
  
  retry_count: {
    type: DataTypes.INTEGER,
    defaultValue: 0
  },
  
  last_retry_at: {
    type: DataTypes.DATE,
    allowNull: true
  },
  
  scheduled_for: {
    type: DataTypes.DATE,
    allowNull: true
  }
}, {
  tableName: 'notifications',
  timestamps: true,
  indexes: [
    {
      fields: ['user_id', 'createdAt']
    },
    {
      fields: ['type', 'status']
    },
    {
      fields: ['group_id', 'createdAt']
    },
    {
      fields: ['status', 'scheduled_for']
    }
  ]
});

// Instance methods
Notification.prototype.markAsRead = async function() {
  this.read_at = new Date();
  this.status = 'read';
  return await this.save();
};

Notification.prototype.markAsSent = async function(externalId = null) {
  this.status = 'sent';
  this.sent_at = new Date();
  if (externalId) {
    this.external_id = externalId;
  }
  return await this.save();
};

Notification.prototype.markAsFailed = async function(reason) {
  this.status = 'failed';
  this.failure_reason = reason;
  this.retry_count += 1;
  this.last_retry_at = new Date();
  return await this.save();
};

Notification.prototype.generateTitle = function() {
  const titles = {
    'payment_reminder': 'Payment Reminder',
    'payment_confirmation': 'Payment Successful',
    'payment_overdue': 'Payment Overdue',
    'draw_result': 'Draw Results',
    'group_invite': 'Group Invitation',
    'member_joined': 'New Member Joined',
    'member_removed': 'Member Removed',
    'group_started': 'Group Started',
    'group_completed': 'Group Completed',
    'welcome_message': 'Welcome!',
    'manager_notification': 'Manager Update',
    'system_alert': 'System Alert'
  };
  
  return titles[this.type] || 'Notification';
};

// Static methods
Notification.getUnreadCount = async function(userId) {
  return await this.count({
    where: {
      user_id: userId,
      status: 'sent',
      read_at: null
    }
  });
};

Notification.getRecent = async function(userId, limit = 20) {
  const ChitGroup = require('./ChitGroup');
  
  return await this.findAll({
    where: { user_id: userId },
    order: [['createdAt', 'DESC']],
    limit: limit,
    include: [
      {
        model: ChitGroup,
        as: 'group',
        attributes: ['name']
      }
    ]
  });
};

Notification.markAllAsRead = async function(userId) {
  return await this.update(
    { read_at: new Date(), status: 'read' },
    { 
      where: { 
        user_id: userId, 
        read_at: null 
      } 
    }
  );
};

// Hooks
Notification.beforeCreate(async (notification) => {
  // Set priority based on type
  const urgentTypes = ['payment_overdue', 'system_alert'];
  const highTypes = ['payment_reminder', 'draw_result'];
  
  if (urgentTypes.includes(notification.type)) {
    notification.priority = 'urgent';
  } else if (highTypes.includes(notification.type)) {
    notification.priority = 'high';
  }
  
  // Set title if not provided
  if (!notification.title) {
    notification.title = notification.generateTitle();
  }
});

module.exports = Notification;
