/**
 * 交易控制器
 * @file transactionController.js
 * @description 处理银行交易相关的请求
 */
const { Transaction, Account, User } = require('../models');
const { validationResult } = require('express-validator');
const { Op } = require('sequelize');

/**
 * 获取交易记录列表
 * @param {Object} req 请求对象
 * @param {Object} res 响应对象
 */
exports.getTransactions = async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 20;
    const offset = (page - 1) * limit;
    const { 
      account_id, 
      transaction_type, 
      status, 
      start_date, 
      end_date,
      amount_min,
      amount_max
    } = req.query;

    const whereClause = {};

    // 普通用户只能查看自己账户的交易记录
    if (req.user.role.name !== 'admin') {
      const userAccounts = await Account.findAll({
        where: { user_id: req.user.id },
        attributes: ['id']
      });
      const accountIds = userAccounts.map(account => account.id);
      whereClause.account_id = { [Op.in]: accountIds };
    } else if (account_id) {
      whereClause.account_id = account_id;
    }

    if (transaction_type) {
      whereClause.transaction_type = transaction_type;
    }

    if (status) {
      whereClause.status = status;
    }

    if (start_date || end_date) {
      whereClause.created_at = {};
      if (start_date) {
        whereClause.created_at[Op.gte] = new Date(start_date);
      }
      if (end_date) {
        whereClause.created_at[Op.lte] = new Date(end_date);
      }
    }

    if (amount_min || amount_max) {
      whereClause.amount = {};
      if (amount_min) {
        whereClause.amount[Op.gte] = Math.round(parseFloat(amount_min) * 100);
      }
      if (amount_max) {
        whereClause.amount[Op.lte] = Math.round(parseFloat(amount_max) * 100);
      }
    }

    const { count, rows } = await Transaction.findAndCountAll({
      where: whereClause,
      include: [{
        model: Account,
        as: 'account',
        include: [{
          model: User,
          as: 'user',
          attributes: ['id', 'username', 'real_name']
        }]
      }],
      limit,
      offset,
      order: [['created_at', 'DESC']]
    });

    res.json({
      success: true,
      data: {
        transactions: rows.map(transaction => ({
          ...transaction.getSafeInfo(),
          amount_formatted: transaction.getAmountFormatted(),
          balance_after_formatted: transaction.getBalanceAfterFormatted(),
          type_description: transaction.getTypeDescription(),
          status_description: transaction.getStatusDescription(),
          is_income: transaction.isIncome(),
          is_expense: transaction.isExpense()
        })),
        pagination: {
          page,
          limit,
          total: count,
          pages: Math.ceil(count / limit)
        }
      }
    });
  } catch (error) {
    console.error('获取交易记录错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
};

/**
 * 获取交易详情
 * @param {Object} req 请求对象
 * @param {Object} res 响应对象
 */
exports.getTransactionDetail = async (req, res) => {
  try {
    const { transactionId } = req.params;

    const transaction = await Transaction.findByPk(transactionId, {
      include: [{
        model: Account,
        as: 'account',
        include: [{
          model: User,
          as: 'user',
          attributes: ['id', 'username', 'real_name']
        }]
      }]
    });

    if (!transaction) {
      return res.status(404).json({
        success: false,
        message: '交易记录不存在'
      });
    }

    // 检查权限
    if (req.user.role.name !== 'admin' && transaction.account.user_id !== req.user.id) {
      return res.status(403).json({
        success: false,
        message: '无权访问该交易记录'
      });
    }

    res.json({
      success: true,
      data: {
        ...transaction.getSafeInfo(),
        amount_formatted: transaction.getAmountFormatted(),
        balance_after_formatted: transaction.getBalanceAfterFormatted(),
        type_description: transaction.getTypeDescription(),
        status_description: transaction.getStatusDescription(),
        is_income: transaction.isIncome(),
        is_expense: transaction.isExpense(),
        can_reverse: transaction.canReverse()
      }
    });
  } catch (error) {
    console.error('获取交易详情错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
};

/**
 * 转账
 * @param {Object} req 请求对象
 * @param {Object} res 响应对象
 */
exports.transfer = async (req, res) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({
        success: false,
        message: '输入数据验证失败',
        errors: errors.array()
      });
    }

    const { from_account_id, to_account_number, amount, description } = req.body;

    // 查找转出账户
    const fromAccount = await Account.findByPk(from_account_id);
    if (!fromAccount) {
      return res.status(404).json({
        success: false,
        message: '转出账户不存在'
      });
    }

    // 检查转出账户权限
    if (req.user.role.name !== 'admin' && fromAccount.user_id !== req.user.id) {
      return res.status(403).json({
        success: false,
        message: '无权操作该账户'
      });
    }

    // 查找转入账户
    const toAccount = await Account.findOne({
      where: { account_number: to_account_number },
      include: [{
        model: User,
        as: 'user',
        attributes: ['id', 'username', 'real_name']
      }]
    });

    if (!toAccount) {
      return res.status(404).json({
        success: false,
        message: '转入账户不存在'
      });
    }

    // 检查账户状态
    if (!fromAccount.isActive() || !toAccount.isActive()) {
      return res.status(400).json({
        success: false,
        message: '账户状态异常，无法进行转账操作'
      });
    }

    const amountInCents = Math.round(amount * 100);

    // 检查余额是否充足
    if (!fromAccount.hasSufficientBalance(amountInCents)) {
      return res.status(400).json({
        success: false,
        message: '账户余额不足'
      });
    }

    // 开始事务
    const transaction = await sequelize.transaction();

    try {
      // 更新转出账户余额
      await fromAccount.update({
        balance: fromAccount.balance - amountInCents,
        available_balance: fromAccount.available_balance - amountInCents
      }, { transaction });

      // 更新转入账户余额
      await toAccount.update({
        balance: toAccount.balance + amountInCents,
        available_balance: toAccount.available_balance + amountInCents
      }, { transaction });

      const transactionNumber = await generateTransactionNumber();

      // 创建转出交易记录
      await Transaction.create({
        transaction_number: transactionNumber,
        account_id: fromAccount.id,
        transaction_type: 'transfer_out',
        amount: amountInCents,
        balance_before: fromAccount.balance + amountInCents,
        balance_after: fromAccount.balance,
        counterparty_account: toAccount.account_number,
        counterparty_name: toAccount.user.real_name,
        description: description || `转账给${toAccount.user.real_name}`,
        status: 'completed',
        processed_at: new Date()
      }, { transaction });

      // 创建转入交易记录
      await Transaction.create({
        transaction_number: transactionNumber,
        account_id: toAccount.id,
        transaction_type: 'transfer_in',
        amount: amountInCents,
        balance_before: toAccount.balance - amountInCents,
        balance_after: toAccount.balance,
        counterparty_account: fromAccount.account_number,
        counterparty_name: fromAccount.user.real_name,
        description: description || `来自${fromAccount.user.real_name}的转账`,
        status: 'completed',
        processed_at: new Date()
      }, { transaction });

      await transaction.commit();

      res.json({
        success: true,
        message: '转账成功',
        data: {
          transaction_number: transactionNumber,
          amount: amount,
          from_account: fromAccount.account_number,
          to_account: toAccount.account_number,
          to_account_holder: toAccount.user.real_name
        }
      });
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  } catch (error) {
    console.error('转账错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
};

/**
 * 撤销交易
 * @param {Object} req 请求对象
 * @param {Object} res 响应对象
 */
exports.reverseTransaction = async (req, res) => {
  try {
    const { transactionId } = req.params;

    const transaction = await Transaction.findByPk(transactionId, {
      include: [{
        model: Account,
        as: 'account'
      }]
    });

    if (!transaction) {
      return res.status(404).json({
        success: false,
        message: '交易记录不存在'
      });
    }

    // 检查权限
    if (req.user.role.name !== 'admin' && transaction.account.user_id !== req.user.id) {
      return res.status(403).json({
        success: false,
        message: '无权操作该交易'
      });
    }

    // 检查是否可以撤销
    if (!transaction.canReverse()) {
      return res.status(400).json({
        success: false,
        message: '该交易无法撤销'
      });
    }

    const result = await transaction.reverse();
    if (result) {
      res.json({
        success: true,
        message: '交易撤销成功'
      });
    } else {
      res.status(400).json({
        success: false,
        message: '交易撤销失败'
      });
    }
  } catch (error) {
    console.error('撤销交易错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
};

/**
 * 获取交易统计
 * @param {Object} req 请求对象
 * @param {Object} res 响应对象
 */
exports.getTransactionStats = async (req, res) => {
  try {
    const { start_date, end_date, account_id } = req.query;

    const whereClause = {};

    // 普通用户只能查看自己账户的统计
    if (req.user.role.name !== 'admin') {
      const userAccounts = await Account.findAll({
        where: { user_id: req.user.id },
        attributes: ['id']
      });
      const accountIds = userAccounts.map(account => account.id);
      whereClause.account_id = { [Op.in]: accountIds };
    } else if (account_id) {
      whereClause.account_id = account_id;
    }

    if (start_date || end_date) {
      whereClause.created_at = {};
      if (start_date) {
        whereClause.created_at[Op.gte] = new Date(start_date);
      }
      if (end_date) {
        whereClause.created_at[Op.lte] = new Date(end_date);
      }
    }

    // 获取交易统计
    const stats = await Transaction.findAll({
      where: whereClause,
      attributes: [
        'transaction_type',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count'],
        [sequelize.fn('SUM', sequelize.col('amount')), 'total_amount']
      ],
      group: ['transaction_type'],
      raw: true
    });

    // 获取总交易数
    const totalCount = await Transaction.count({ where: whereClause });

    // 获取总交易金额
    const totalAmount = await Transaction.sum('amount', { where: whereClause });

    res.json({
      success: true,
      data: {
        total_count: totalCount,
        total_amount: totalAmount ? (totalAmount / 100).toFixed(2) : '0.00',
        by_type: stats.map(stat => ({
          type: stat.transaction_type,
          count: parseInt(stat.count),
          total_amount: (parseInt(stat.total_amount) / 100).toFixed(2)
        }))
      }
    });
  } catch (error) {
    console.error('获取交易统计错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
};

/**
 * 生成交易流水号
 * @returns {String} 交易流水号
 */
async function generateTransactionNumber() {
  const timestamp = Date.now().toString();
  const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
  return `TXN${timestamp}${random}`;
}