const { ChitGroup, GroupMember, User, Payment, MonthlyDraw } = require('../models');
const { Op } = require('sequelize');

// Create a new chit group
const createChitGroup = async (req, res) => {
  try {
    const {
      name,
      total_value,
      monthly_installment,
      duration_months,
      max_members,
      foreman_commission_amount,
      foreman_commission_type = 'fixed',
      foreman_commission_rate,
      draw_date
    } = req.body;
    
    const managerId = req.user.id;

    // Validate input
    if (!name || !total_value || !monthly_installment || !duration_months || !max_members || !foreman_commission_amount || !draw_date) {
      return res.status(400).json({
        success: false,
        message: 'All fields are required'
      });
    }

    // Validate business rules based on commission type
    let expectedTotalValue;
    let actualCommission;
    
    if (foreman_commission_type === 'percentage') {
      // For percentage commission: commission = (total_value / duration_months) * (rate / 100)
      // So: monthly_installment = (total_value / duration_months) + (total_value / duration_months) * (rate / 100)
      // monthly_installment = (total_value / duration_months) * (1 + rate/100)
      // total_value = monthly_installment * duration_months / (1 + rate/100)
      const rate = foreman_commission_rate || 5;
      expectedTotalValue = (monthly_installment * duration_months) / (1 + rate/100);
      actualCommission = (expectedTotalValue / duration_months) * (rate / 100);
    } else {
      // For fixed commission: total_value = (monthly_installment - foreman_commission_amount) × duration_months
      expectedTotalValue = (monthly_installment - foreman_commission_amount) * duration_months;
      actualCommission = foreman_commission_amount;
    }
    
    if (Math.abs(total_value - expectedTotalValue) > 1) { // Allow small rounding differences
      return res.status(400).json({
        success: false,
        message: `Total value calculation mismatch. Expected: ₹${expectedTotalValue.toFixed(0)}, Provided: ₹${total_value}. Commission type: ${foreman_commission_type}`
      });
    }

    // Validate commission based on type
    if (foreman_commission_type === 'percentage') {
      const rate = foreman_commission_rate || 5;
      if (rate < 0 || rate > 100) {
        return res.status(400).json({
          success: false,
          message: 'Commission rate must be between 0 and 100%'
        });
      }
    } else {
      if (foreman_commission_amount < 0 || foreman_commission_amount > total_value * 0.1) {
        return res.status(400).json({
          success: false,
          message: 'Foreman commission must be between 0 and 10% of total value'
        });
      }
    }

    if (draw_date < 1 || draw_date > 31) {
      return res.status(400).json({
        success: false,
        message: 'Draw date must be between 1 and 31'
      });
    }

    // Create chit group
    const chitGroup = await ChitGroup.create({
      name,
      total_value,
      monthly_installment,
      duration_months,
      max_members,
      foreman_commission_amount: actualCommission, // Use calculated commission
      foreman_commission_type,
      foreman_commission_rate,
      draw_date,
      manager_id: managerId,
      status: 'forming',
      start_date: new Date(),
      end_date: new Date(Date.now() + duration_months * 30 * 24 * 60 * 60 * 1000)
    });

    res.status(201).json({
      success: true,
      message: 'Chit group created successfully',
      data: chitGroup
    });
  } catch (error) {
    console.error('Create chit group error:', error);
    res.status(500).json({
      success: false,
      message: 'Internal server error'
    });
  }
};

// Get all chit groups for the manager
const getManagerChitGroups = async (req, res) => {
  try {
    const managerId = req.user.id;
    const { status, page = 1, limit = 10 } = req.query;

    const whereClause = { manager_id: managerId };
    if (status) {
      whereClause.status = status;
    }

    const offset = (page - 1) * limit;

    const chitGroups = await ChitGroup.findAndCountAll({
      where: whereClause,
      include: [
        {
          model: GroupMember,
          as: 'members',
          include: [
            {
              model: User,
              attributes: ['id', 'full_name', 'mobile_number']
            }
          ]
        }
      ],
      limit: parseInt(limit),
      offset: parseInt(offset),
      order: [['created_at', 'DESC']]
    });

    res.json({
      success: true,
      data: {
        chitGroups: chitGroups.rows,
        pagination: {
          currentPage: parseInt(page),
          totalPages: Math.ceil(chitGroups.count / limit),
          totalItems: chitGroups.count,
          itemsPerPage: parseInt(limit)
        }
      }
    });
  } catch (error) {
    console.error('Get manager chit groups error:', error);
    res.status(500).json({
      success: false,
      message: 'Internal server error'
    });
  }
};

// Get chit groups for a member
const getMemberChitGroups = async (req, res) => {
  try {
    const memberId = req.user.id;
    const { status, page = 1, limit = 10 } = req.query;

    const whereClause = { user_id: memberId };
    if (status) {
      whereClause.status = status;
    }

    const offset = (page - 1) * limit;

    const groupMemberships = await GroupMember.findAndCountAll({
      where: whereClause,
      include: [
        {
          model: ChitGroup,
          include: [
            {
              model: User,
              as: 'manager',
              attributes: ['id', 'full_name', 'mobile_number']
            }
          ]
        }
      ],
      limit: parseInt(limit),
      offset: parseInt(offset),
      order: [['created_at', 'DESC']]
    });

    res.json({
      success: true,
      data: {
        chitGroups: groupMemberships.rows.map(membership => ({
          ...membership.ChitGroup.toJSON(),
          membership_status: membership.status,
          total_paid: membership.total_paid,
          total_won: membership.total_won
        })),
        pagination: {
          currentPage: parseInt(page),
          totalPages: Math.ceil(groupMemberships.count / limit),
          totalItems: groupMemberships.count,
          itemsPerPage: parseInt(limit)
        }
      }
    });
  } catch (error) {
    console.error('Get member chit groups error:', error);
    res.status(500).json({
      success: false,
      message: 'Internal server error'
    });
  }
};

// Get single chit group details
const getChitGroupDetails = async (req, res) => {
  try {
    const { groupId } = req.params;
    const userId = req.user.id;

    const chitGroup = await ChitGroup.findByPk(groupId, {
      include: [
        {
          model: User,
          as: 'manager',
          attributes: ['id', 'full_name', 'mobile_number']
        },
        {
          model: GroupMember,
          as: 'members',
          include: [
            {
              model: User,
              attributes: ['id', 'full_name', 'mobile_number']
            }
          ]
        },
        {
          model: MonthlyDraw,
          order: [['created_at', 'DESC']],
          limit: 5
        }
      ]
    });

    if (!chitGroup) {
      return res.status(404).json({
        success: false,
        message: 'Chit group not found'
      });
    }

    // Check if user has access to this group
    const isManager = chitGroup.manager_id === userId;
    const isMember = chitGroup.members.some(member => member.user_id === userId);

    if (!isManager && !isMember) {
      return res.status(403).json({
        success: false,
        message: 'Access denied'
      });
    }

    res.json({
      success: true,
      data: chitGroup
    });
  } catch (error) {
    console.error('Get chit group details error:', error);
    res.status(500).json({
      success: false,
      message: 'Internal server error'
    });
  }
};

// Update chit group
const updateChitGroup = async (req, res) => {
  try {
    const { groupId } = req.params;
    const managerId = req.user.id;
    const updateData = req.body;

    const chitGroup = await ChitGroup.findOne({
      where: { id: groupId, manager_id: managerId }
    });

    if (!chitGroup) {
      return res.status(404).json({
        success: false,
        message: 'Chit group not found or access denied'
      });
    }

    // Only allow updates if group is still forming
    if (chitGroup.status !== 'forming') {
      return res.status(400).json({
        success: false,
        message: 'Cannot update chit group after it has started'
      });
    }

    // Validate business rules if updating financial fields
    if (updateData.monthly_installment && updateData.duration_months) {
      const commissionType = updateData.foreman_commission_type || chitGroup.foreman_commission_type || 'fixed';
      let expectedTotalValue;
      let actualCommission;
      
      if (commissionType === 'percentage') {
        const rate = updateData.foreman_commission_rate || chitGroup.foreman_commission_rate || 5;
        expectedTotalValue = (updateData.monthly_installment * updateData.duration_months) / (1 + rate/100);
        actualCommission = (expectedTotalValue / updateData.duration_months) * (rate / 100);
      } else {
        const commission = updateData.foreman_commission_amount || chitGroup.foreman_commission_amount;
        expectedTotalValue = (updateData.monthly_installment - commission) * updateData.duration_months;
        actualCommission = commission;
      }
      
      if (updateData.total_value && Math.abs(updateData.total_value - expectedTotalValue) > 1) {
        return res.status(400).json({
          success: false,
          message: `Total value calculation mismatch. Expected: ₹${expectedTotalValue.toFixed(0)}, Provided: ₹${updateData.total_value}. Commission type: ${commissionType}`
        });
      }
      updateData.total_value = expectedTotalValue;
      updateData.foreman_commission_amount = actualCommission;
    }

    await chitGroup.update(updateData);

    res.json({
      success: true,
      message: 'Chit group updated successfully',
      data: chitGroup
    });
  } catch (error) {
    console.error('Update chit group error:', error);
    res.status(500).json({
      success: false,
      message: 'Internal server error'
    });
  }
};

// Delete chit group (only if forming and no members)
const deleteChitGroup = async (req, res) => {
  try {
    const { groupId } = req.params;
    const managerId = req.user.id;

    const chitGroup = await ChitGroup.findOne({
      where: { id: groupId, manager_id: managerId },
      include: [
        {
          model: GroupMember,
          as: 'members'
        }
      ]
    });

    if (!chitGroup) {
      return res.status(404).json({
        success: false,
        message: 'Chit group not found or access denied'
      });
    }

    if (chitGroup.status !== 'forming') {
      return res.status(400).json({
        success: false,
        message: 'Cannot delete chit group after it has started'
      });
    }

    if (chitGroup.members.length > 0) {
      return res.status(400).json({
        success: false,
        message: 'Cannot delete chit group with existing members'
      });
    }

    await chitGroup.destroy();

    res.json({
      success: true,
      message: 'Chit group deleted successfully'
    });
  } catch (error) {
    console.error('Delete chit group error:', error);
    res.status(500).json({
      success: false,
      message: 'Internal server error'
    });
  }
};

// Start chit group (activate it)
const startChitGroup = async (req, res) => {
  try {
    const { groupId } = req.params;
    const managerId = req.user.id;

    const chitGroup = await ChitGroup.findOne({
      where: { id: groupId, manager_id: managerId },
      include: [
        {
          model: GroupMember,
          as: 'members'
        }
      ]
    });

    if (!chitGroup) {
      return res.status(404).json({
        success: false,
        message: 'Chit group not found or access denied'
      });
    }

    if (chitGroup.status !== 'forming') {
      return res.status(400).json({
        success: false,
        message: 'Chit group is already active or completed'
      });
    }

    if (chitGroup.members.length < 2) {
      return res.status(400).json({
        success: false,
        message: 'Need at least 2 members to start the chit group'
      });
    }

    await chitGroup.update({
      status: 'active',
      start_date: new Date()
    });

    res.json({
      success: true,
      message: 'Chit group activated successfully',
      data: chitGroup
    });
  } catch (error) {
    console.error('Start chit group error:', error);
    res.status(500).json({
      success: false,
      message: 'Internal server error'
    });
  }
};

// Get chit group statistics
const getChitGroupStats = async (req, res) => {
  try {
    const { groupId } = req.params;
    const userId = req.user.id;

    console.log('Getting stats for group:', groupId, 'user:', userId);

    // First, try to find the chit group without includes
    const chitGroup = await ChitGroup.findByPk(groupId);

    if (!chitGroup) {
      console.log('Chit group not found:', groupId);
      return res.status(404).json({
        success: false,
        message: 'Chit group not found'
      });
    }

    console.log('Chit group found:', chitGroup.name, 'Manager:', chitGroup.manager_id);

    // Check access - user must be the manager
    const isManager = chitGroup.manager_id === userId;
    
    if (!isManager) {
      console.log('Access denied - user is not manager');
      return res.status(403).json({
        success: false,
        message: 'Access denied - only group manager can view stats'
      });
    }

    // Get related data separately to avoid complex query issues
    const members = await GroupMember.findAll({
      where: { group_id: groupId },
      include: [{ model: User, attributes: ['id', 'full_name', 'mobile_number'] }]
    });

    const payments = await Payment.findAll({
      where: { group_id: groupId, status: 'success' }
    });

    const draws = await MonthlyDraw.findAll({
      where: { group_id: groupId, status: 'completed' }
    });

    // Calculate statistics
    const totalMembers = members.length;
    const totalPayments = payments.length;
    const totalDraws = draws.length;
    const totalCollection = totalPayments * parseFloat(chitGroup.monthly_installment);
    const foremanCommission = parseFloat(chitGroup.foreman_commission_amount);
    const totalPrizePool = totalCollection - foremanCommission;

    const stats = {
      totalMembers,
      totalPayments,
      totalDraws,
      totalCollection,
      foremanCommission,
      totalPrizePool,
      averagePrizePerDraw: totalDraws > 0 ? totalPrizePool / totalDraws : 0,
      completionPercentage: (totalDraws / chitGroup.duration_months) * 100
    };

    console.log('Stats calculated:', stats);

    res.json({
      success: true,
      data: stats
    });
  } catch (error) {
    console.error('Get chit group stats error:', error);
    res.status(500).json({
      success: false,
      message: 'Internal server error'
    });
  }
};

// Get chit group financial data
const getChitGroupFinancialData = async (req, res) => {
  try {
    const { groupId } = req.params;
    const userId = req.user.id;

    console.log('Getting financial data for group:', groupId, 'user:', userId);

    const chitGroup = await ChitGroup.findByPk(groupId);

    if (!chitGroup) {
      console.log('Chit group not found:', groupId);
      return res.status(404).json({
        success: false,
        message: 'Chit group not found'
      });
    }

    // Check access
    const isManager = chitGroup.manager_id === userId;
    const isMember = await GroupMember.findOne({
      where: { group_id: groupId, user_id: userId }
    });

    if (!isManager && !isMember) {
      return res.status(403).json({
        success: false,
        message: 'Access denied'
      });
    }

    // Generate financial data based on group parameters
    const financialData = generateFinancialData(chitGroup);

    res.json({
      success: true,
      data: {
        financial_data: financialData
      }
    });
  } catch (error) {
    console.error('Get chit group financial data error:', error);
    res.status(500).json({
      success: false,
      message: 'Internal server error'
    });
  }
};

// Helper function to generate financial data
const generateFinancialData = (chitGroup) => {
  const financialData = [];
  const totalMonths = chitGroup.duration_months;
  const chitValue = chitGroup.total_value;
  const monthlyInstallment = chitGroup.monthly_installment;
  const commission = chitGroup.foreman_commission_amount;
  
  // Calculate starting bid amount (typically 85-90% of chit value)
  let currentBidAmount = chitValue * 0.8765; // Starting at 87.65%
  
  for (let i = 0; i < totalMonths; i++) {
    const month = i + 1;
    const year = 2025 + Math.floor((month - 1) / 12);
    const monthName = getMonthName((month - 1) % 12);
    const monthYear = `${monthName}-${year.toString().substring(2)}`;
    
    // Calculate dividend (difference between chit value and bid amount)
    const dividend = chitValue - currentBidAmount;
    
    financialData.push({
      month_year: monthYear,
      chit_value: chitValue,
      bid_amount: Math.round(currentBidAmount),
      subscription_amount: monthlyInstallment,
      commission_installment: commission,
      total_payable_installment: parseFloat(monthlyInstallment) + parseFloat(commission),
      dividend_amount: Math.round(dividend)
    });
    
    // Increase bid amount for next month
    currentBidAmount += 2600; // Increment by ₹2600 per month
  }
  
  // Add total row
  const totalChitValue = chitValue * totalMonths;
  const totalBidAmount = financialData.reduce((sum, entry) => sum + entry.bid_amount, 0);
  const totalSubscription = monthlyInstallment * totalMonths;
  const totalCommission = commission * totalMonths;
  const totalPayable = (monthlyInstallment + commission) * totalMonths;
  const totalDividend = financialData.reduce((sum, entry) => sum + entry.dividend_amount, 0);
  
  financialData.push({
    month_year: 'Total',
    chit_value: totalChitValue,
    bid_amount: totalBidAmount,
    subscription_amount: totalSubscription,
    commission_installment: totalCommission,
    total_payable_installment: totalPayable,
    dividend_amount: totalDividend
  });
  
  return financialData;
};

const getMonthName = (monthIndex) => {
  const months = [
    'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
  ];
  return months[monthIndex];
};

module.exports = {
  createChitGroup,
  getManagerChitGroups,
  getMemberChitGroups,
  getChitGroupDetails,
  updateChitGroup,
  deleteChitGroup,
  startChitGroup,
  getChitGroupStats,
  getChitGroupFinancialData
};
