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

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

    const { user_id, account_type, initial_balance = 0 } = req.body;

    // 检查用户是否存在
    const user = await User.findByPk(user_id);
    if (!user) {
      return res.status(404).json({
        success: false,
        message: '用户不存在'
      });
    }

    // 生成账户号码
    const accountNumber = await generateAccountNumber();

    // 创建账户
    const account = await Account.create({
      account_number: accountNumber,
      user_id,
      account_type,
      balance: initial_balance * 100, // 转换为分
      available_balance: initial_balance * 100,
      frozen_amount: 0
    });

    // 如果有初始余额，创建存款交易记录
    if (initial_balance > 0) {
      await Transaction.create({
        transaction_number: await generateTransactionNumber(),
        account_id: account.id,
        transaction_type: 'deposit',
        amount: initial_balance * 100,
        balance_before: 0,
        balance_after: initial_balance * 100,
        description: '开户存款',
        status: 'completed',
        processed_at: new Date()
      });
    }

    res.status(201).json({
      success: true,
      message: '账户创建成功',
      data: {
        ...account.getSafeInfo(),
        balance_formatted: account.getBalanceFormatted(),
        available_balance_formatted: account.getAvailableBalanceFormatted()
      }
    });
  } catch (error) {
    console.error('创建账户错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
};

/**
 * 获取账户列表
 * @param {Object} req 请求对象
 * @param {Object} res 响应对象
 */
exports.getAccounts = async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 10;
    const offset = (page - 1) * limit;
    const { user_id, account_type, status } = req.query;

    const whereClause = {};
    
    // 普通用户只能查看自己的账户
    if (req.user.role.name !== 'admin') {
      whereClause.user_id = req.user.id;
    } else if (user_id) {
      whereClause.user_id = user_id;
    }

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

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

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

    res.json({
      success: true,
      data: {
        accounts: rows.map(account => ({
          ...account.getSafeInfo(),
          balance_formatted: account.getBalanceFormatted(),
          available_balance_formatted: account.getAvailableBalanceFormatted(),
          frozen_amount_formatted: account.getFrozenAmountFormatted()
        })),
        pagination: {
          page,
          limit,
          total: count,
          pages: Math.ceil(count / limit)
        }
      }
    });
  } catch (error) {
    console.error('获取账户列表错误:', error);
    console.error('错误堆栈:', error.stack);
    res.status(500).json({
      success: false,
      message: '服务器内部错误',
      error: process.env.NODE_ENV === 'development' ? error.message : undefined
    });
  }
};

/**
 * 获取账户详情
 * @param {Object} req 请求对象
 * @param {Object} res 响应对象
 */
exports.getAccountDetail = async (req, res) => {
  try {
    const { accountId } = req.params;

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

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

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

    res.json({
      success: true,
      data: {
        ...account.getSafeInfo(),
        balance_formatted: account.getBalanceFormatted(),
        available_balance_formatted: account.getAvailableBalanceFormatted(),
        frozen_amount_formatted: account.getFrozenAmountFormatted()
      }
    });
  } catch (error) {
    console.error('获取账户详情错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
};

/**
 * 更新账户状态
 * @param {Object} req 请求对象
 * @param {Object} res 响应对象
 */
exports.updateAccountStatus = async (req, res) => {
  try {
    const { accountId } = req.params;
    const { status } = req.body;

    const account = await Account.findByPk(accountId);
    if (!account) {
      return res.status(404).json({
        success: false,
        message: '账户不存在'
      });
    }

    await account.update({ status });

    res.json({
      success: true,
      message: '账户状态更新成功',
      data: account.getSafeInfo()
    });
  } catch (error) {
    console.error('更新账户状态错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
};

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

    const { accountId } = req.params;
    const { amount, description } = req.body;

    const account = await Account.findByPk(accountId);
    if (!account) {
      return res.status(404).json({
        success: false,
        message: '账户不存在'
      });
    }

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

    const amountInCents = Math.round(amount * 100);
    const balanceBefore = account.balance;
    const balanceAfter = balanceBefore + amountInCents;

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

    try {
      // 更新账户余额
      await account.update({
        balance: balanceAfter,
        available_balance: account.available_balance + amountInCents
      }, { transaction });

      // 创建交易记录
      await Transaction.create({
        transaction_number: await generateTransactionNumber(),
        account_id: account.id,
        transaction_type: 'deposit',
        amount: amountInCents,
        balance_before: balanceBefore,
        balance_after: balanceAfter,
        description: description || '存款',
        status: 'completed',
        processed_at: new Date()
      }, { transaction });

      await transaction.commit();

      res.json({
        success: true,
        message: '存款成功',
        data: {
          amount: amount,
          balance_after: account.formatAmount(balanceAfter),
          transaction_number: await generateTransactionNumber()
        }
      });
    } 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.withdraw = async (req, res) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({
        success: false,
        message: '输入数据验证失败',
        errors: errors.array()
      });
    }

    const { accountId } = req.params;
    const { amount, description } = req.body;

    const account = await Account.findByPk(accountId);
    if (!account) {
      return res.status(404).json({
        success: false,
        message: '账户不存在'
      });
    }

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

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

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

    const balanceBefore = account.balance;
    const balanceAfter = balanceBefore - amountInCents;

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

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

      // 创建交易记录
      await Transaction.create({
        transaction_number: await generateTransactionNumber(),
        account_id: account.id,
        transaction_type: 'withdrawal',
        amount: amountInCents,
        balance_before: balanceBefore,
        balance_after: balanceAfter,
        description: description || '取款',
        status: 'completed',
        processed_at: new Date()
      }, { transaction });

      await transaction.commit();

      res.json({
        success: true,
        message: '取款成功',
        data: {
          amount: amount,
          balance_after: account.formatAmount(balanceAfter),
          transaction_number: await generateTransactionNumber()
        }
      });
    } catch (error) {
      await transaction.rollback();
      throw error;
    }
  } catch (error) {
    console.error('取款错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
};

/**
 * 生成账户号码
 * @returns {String} 账户号码
 */
async function generateAccountNumber() {
  const bankCode = process.env.BANK_CODE || '001';
  const timestamp = Date.now().toString().slice(-8);
  const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
  return `${bankCode}${timestamp}${random}`;
}

/**
 * 生成交易流水号
 * @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}`;
}