const Config = require('../models/Config');
const User = require('../models/User');

/**
 * Commission Config Service
 * Handles commission rate configuration
 */

// Default commission rate (2%)
const DEFAULT_COMMISSION_RATE = 0.02;
const COMMISSION_RATE_KEY = 'commission_rate';

/**
 * Get current commission rate
 * @returns {number} Commission rate (e.g., 0.02 for 2%)
 */
const getCommissionRate = async () => {
  const config = await Config.findOne({
    where: { key: COMMISSION_RATE_KEY },
  });

  if (!config) {
    return DEFAULT_COMMISSION_RATE;
  }

  const rate = parseFloat(config.value);
  if (isNaN(rate) || rate < 0 || rate > 1) {
    return DEFAULT_COMMISSION_RATE;
  }

  return rate;
};

/**
 * Get commission rate for a specific user
 * Returns user's custom rate if set, otherwise returns system default rate
 * @param {string} userId - User ID
 * @returns {number} Commission rate (e.g., 0.02 for 2%)
 */
const getUserCommissionRate = async (userId) => {
  if (!userId) {
    return getCommissionRate();
  }

  const user = await User.findByPk(userId, {
    attributes: ['commissionRate'],
  });

  // If user has custom commission rate, use it
  if (user && user.commissionRate !== null && user.commissionRate !== undefined) {
    const rate = parseFloat(user.commissionRate);
    if (!isNaN(rate) && rate >= 0 && rate <= 1) {
      return rate;
    }
  }

  // Otherwise use system default rate
  return getCommissionRate();
};

/**
 * Set user's custom commission rate
 * @param {string} userId - User ID
 * @param {number|null} rate - Commission rate (null to clear custom rate)
 * @returns {Object} Updated user info
 */
const setUserCommissionRate = async (userId, rate) => {
  const user = await User.findByPk(userId);
  if (!user) {
    throw new Error('User not found');
  }

  // If rate is null, clear custom rate
  if (rate === null || rate === '') {
    user.commissionRate = null;
    await user.save();
    return {
      userId: user.id,
      uid: user.uid,
      nickname: user.nickname,
      commissionRate: null,
      useSystemDefault: true,
    };
  }

  // Validate rate
  const rateValue = parseFloat(rate);
  if (isNaN(rateValue) || rateValue < 0 || rateValue > 1) {
    throw new Error('Invalid commission rate. Must be between 0 and 1.');
  }

  user.commissionRate = rateValue;
  await user.save();

  return {
    userId: user.id,
    uid: user.uid,
    nickname: user.nickname,
    commissionRate: rateValue,
    percentage: `${(rateValue * 100).toFixed(2)}%`,
    useSystemDefault: false,
  };
};

/**
 * Get users with custom commission rates
 * @returns {Array} List of users with custom rates
 */
const getUsersWithCustomRates = async () => {
  const users = await User.findAll({
    where: {
      commissionRate: {
        [require('sequelize').Op.ne]: null,
      },
    },
    attributes: ['id', 'uid', 'nickname', 'commissionRate', 'createdAt'],
    order: [['createdAt', 'DESC']],
  });

  return users.map(user => ({
    userId: user.id,
    uid: user.uid,
    nickname: user.nickname,
    commissionRate: parseFloat(user.commissionRate),
    percentage: `${(parseFloat(user.commissionRate) * 100).toFixed(2)}%`,
  }));
};

/**
 * Set commission rate
 * @param {number} rate - Commission rate (e.g., 0.02 for 2%)
 * @returns {Object} Updated config
 */
const setCommissionRate = async (rate) => {
  // Validate rate
  const rateValue = parseFloat(rate);
  if (isNaN(rateValue) || rateValue < 0 || rateValue > 1) {
    throw new Error('Invalid commission rate. Must be between 0 and 1.');
  }

  // Find or create config
  let config = await Config.findOne({
    where: { key: COMMISSION_RATE_KEY },
  });

  if (config) {
    config.value = rateValue.toString();
    await config.save();
  } else {
    config = await Config.create({
      key: COMMISSION_RATE_KEY,
      value: rateValue.toString(),
      type: 'number',
      category: 'invitation',
      description: '邀请佣金比例（如0.02表示2%）',
    });
  }

  return {
    key: config.key,
    value: rateValue,
    updatedAt: config.updatedAt,
  };
};

/**
 * Get commission rate config details
 * @returns {Object} Config details
 */
const getCommissionRateConfig = async () => {
  const config = await Config.findOne({
    where: { key: COMMISSION_RATE_KEY },
  });

  const rate = config ? parseFloat(config.value) : DEFAULT_COMMISSION_RATE;

  return {
    key: COMMISSION_RATE_KEY,
    value: rate,
    percentage: `${(rate * 100).toFixed(2)}%`,
    isDefault: !config,
    updatedAt: config ? config.updatedAt : null,
  };
};

module.exports = {
  getCommissionRate,
  getUserCommissionRate,
  setCommissionRate,
  setUserCommissionRate,
  getUsersWithCustomRates,
  getCommissionRateConfig,
  DEFAULT_COMMISSION_RATE,
  COMMISSION_RATE_KEY,
};
