const database = require('../config/database');
const crypto = require('crypto');

class PaymentService {
  /**
   * 创建支付订单
   * @param {Object} paymentData - 支付数据
   * @returns {Promise<Object>} 支付订单信息
   */
  async createPayment(paymentData) {
    try {
      const {
        order_id,
        user_id,
        amount,
        payment_method,
        payment_channel = 'wechat'
      } = paymentData;

      // 生成支付订单号
      const payment_no = this.generatePaymentNo();

      const query = `
        INSERT INTO payments (
          payment_no, order_id, user_id, amount, 
          payment_method, payment_channel, status
        ) VALUES (?, ?, ?, ?, ?, ?, 'pending')
      `;

      const params = [
        payment_no, order_id, user_id, amount,
        payment_method, payment_channel
      ];

      const result = await database.query(query, params);
      
      // 获取创建的支付订单
      const payment = await this.getPaymentById(result.insertId);
      
      // 根据支付方式生成支付参数
      const paymentParams = await this.generatePaymentParams(payment);
      
      return {
        ...payment,
        ...paymentParams
      };
    } catch (error) {
      console.error('创建支付订单失败:', error);
      throw new Error('创建支付订单失败');
    }
  }

  /**
   * 获取支付订单详情
   * @param {number} paymentId - 支付ID
   * @returns {Promise<Object>} 支付订单信息
   */
  async getPaymentById(paymentId) {
    try {
      const query = `
        SELECT 
          p.*,
          o.order_number,
          o.total_amount as order_amount,
          u.username
        FROM payments p
        LEFT JOIN orders o ON p.order_id = o.id
        LEFT JOIN users u ON p.user_id = u.id
        WHERE p.id = ? AND p.is_deleted = 0
      `;

      const [payments] = await database.query(query, [paymentId]);
      
      if (payments.length === 0) {
        throw new Error('支付订单不存在');
      }

      return payments[0];
    } catch (error) {
      console.error('获取支付订单失败:', error);
      throw error;
    }
  }

  /**
   * 根据支付号获取支付订单
   * @param {string} paymentNo - 支付订单号
   * @returns {Promise<Object>} 支付订单信息
   */
  async getPaymentByNo(paymentNo) {
    try {
      const query = `
        SELECT 
          p.*,
          o.order_number,
          o.total_amount as order_amount,
          u.username
        FROM payments p
        LEFT JOIN orders o ON p.order_id = o.id
        LEFT JOIN users u ON p.user_id = u.id
        WHERE p.payment_no = ? AND p.is_deleted = 0
      `;

      const [payments] = await database.query(query, [paymentNo]);
      
      if (payments.length === 0) {
        throw new Error('支付订单不存在');
      }

      return payments[0];
    } catch (error) {
      console.error('获取支付订单失败:', error);
      throw error;
    }
  }

  /**
   * 更新支付状态
   * @param {string} paymentNo - 支付订单号
   * @param {string} status - 支付状态
   * @param {Object} extraData - 额外数据
   * @returns {Promise<Object>} 更新后的支付订单
   */
  async updatePaymentStatus(paymentNo, status, extraData = {}) {
    try {
      const {
        transaction_id,
        paid_at,
        failure_reason
      } = extraData;

      let query = `
        UPDATE payments 
        SET status = ?, updated_at = CURRENT_TIMESTAMP
      `;
      const params = [status];

      if (transaction_id) {
        query += ', transaction_id = ?';
        params.push(transaction_id);
      }

      if (paid_at) {
        query += ', paid_at = ?';
        params.push(paid_at);
      }

      if (failure_reason) {
        query += ', failure_reason = ?';
        params.push(failure_reason);
      }

      query += ' WHERE payment_no = ? AND is_deleted = 0';
      params.push(paymentNo);

      const result = await database.query(query, params);
      
      if (result.affectedRows === 0) {
        throw new Error('支付订单不存在');
      }

      return await this.getPaymentByNo(paymentNo);
    } catch (error) {
      console.error('更新支付状态失败:', error);
      throw error;
    }
  }

  /**
   * 处理支付回调
   * @param {Object} callbackData - 回调数据
   * @returns {Promise<Object>} 处理结果
   */
  async handlePaymentCallback(callbackData) {
    try {
      const {
        payment_no,
        transaction_id,
        status,
        paid_amount,
        paid_at
      } = callbackData;

      // 获取支付订单
      const payment = await this.getPaymentByNo(payment_no);

      // 验证金额
      if (status === 'paid' && parseFloat(paid_amount) !== parseFloat(payment.amount)) {
        throw new Error('支付金额不匹配');
      }

      // 更新支付状态
      const updatedPayment = await this.updatePaymentStatus(payment_no, status, {
        transaction_id,
        paid_at: paid_at || new Date()
      });

      // 如果支付成功，更新订单状态
      if (status === 'paid') {
        await this.updateOrderAfterPayment(payment.order_id);
      }

      return updatedPayment;
    } catch (error) {
      console.error('处理支付回调失败:', error);
      throw error;
    }
  }

  /**
   * 支付成功后更新订单状态
   * @param {number} orderId - 订单ID
   * @returns {Promise<void>}
   */
  async updateOrderAfterPayment(orderId) {
    try {
      const query = `
        UPDATE orders 
        SET 
          payment_status = 'paid',
          order_status = 'confirmed',
          paid_at = CURRENT_TIMESTAMP,
          updated_at = CURRENT_TIMESTAMP
        WHERE id = ? AND is_deleted = 0
      `;

      await database.query(query, [orderId]);
    } catch (error) {
      console.error('更新订单支付状态失败:', error);
      throw error;
    }
  }

  /**
   * 申请退款
   * @param {Object} refundData - 退款数据
   * @returns {Promise<Object>} 退款申请结果
   */
  async createRefund(refundData) {
    try {
      const {
        payment_id,
        refund_amount,
        refund_reason,
        user_id
      } = refundData;

      // 获取支付订单
      const payment = await this.getPaymentById(payment_id);

      // 验证退款金额
      if (parseFloat(refund_amount) > parseFloat(payment.amount)) {
        throw new Error('退款金额不能超过支付金额');
      }

      // 生成退款订单号
      const refund_no = this.generateRefundNo();

      const query = `
        INSERT INTO refunds (
          refund_no, payment_id, order_id, user_id,
          refund_amount, refund_reason, status
        ) VALUES (?, ?, ?, ?, ?, ?, 'pending')
      `;

      const params = [
        refund_no, payment_id, payment.order_id, user_id,
        refund_amount, refund_reason
      ];

      const result = await database.query(query, params);
      
      return await this.getRefundById(result.insertId);
    } catch (error) {
      console.error('创建退款申请失败:', error);
      throw error;
    }
  }

  /**
   * 获取退款详情
   * @param {number} refundId - 退款ID
   * @returns {Promise<Object>} 退款信息
   */
  async getRefundById(refundId) {
    try {
      const query = `
        SELECT 
          r.*,
          p.payment_no,
          p.amount as payment_amount,
          o.order_number,
          u.username
        FROM refunds r
        LEFT JOIN payments p ON r.payment_id = p.id
        LEFT JOIN orders o ON r.order_id = o.id
        LEFT JOIN users u ON r.user_id = u.id
        WHERE r.id = ? AND r.is_deleted = 0
      `;

      const [refunds] = await database.query(query, [refundId]);
      
      if (refunds.length === 0) {
        throw new Error('退款记录不存在');
      }

      return refunds[0];
    } catch (error) {
      console.error('获取退款详情失败:', error);
      throw error;
    }
  }

  /**
   * 处理退款
   * @param {number} refundId - 退款ID
   * @param {string} status - 退款状态
   * @param {Object} extraData - 额外数据
   * @returns {Promise<Object>} 处理结果
   */
  async processRefund(refundId, status, extraData = {}) {
    try {
      const {
        refund_transaction_id,
        processed_by,
        process_remark
      } = extraData;

      let query = `
        UPDATE refunds 
        SET 
          status = ?,
          processed_at = CURRENT_TIMESTAMP,
          updated_at = CURRENT_TIMESTAMP
      `;
      const params = [status];

      if (refund_transaction_id) {
        query += ', refund_transaction_id = ?';
        params.push(refund_transaction_id);
      }

      if (processed_by) {
        query += ', processed_by = ?';
        params.push(processed_by);
      }

      if (process_remark) {
        query += ', process_remark = ?';
        params.push(process_remark);
      }

      query += ' WHERE id = ? AND is_deleted = 0';
      params.push(refundId);

      const result = await database.query(query, params);
      
      if (result.affectedRows === 0) {
        throw new Error('退款记录不存在');
      }

      // 如果退款成功，更新支付和订单状态
      if (status === 'completed') {
        const refund = await this.getRefundById(refundId);
        await this.updatePaymentStatus(refund.payment_no, 'refunded');
        await this.updateOrderAfterRefund(refund.order_id);
      }

      return await this.getRefundById(refundId);
    } catch (error) {
      console.error('处理退款失败:', error);
      throw error;
    }
  }

  /**
   * 退款成功后更新订单状态
   * @param {number} orderId - 订单ID
   * @returns {Promise<void>}
   */
  async updateOrderAfterRefund(orderId) {
    try {
      const query = `
        UPDATE orders 
        SET 
          payment_status = 'refunded',
          order_status = 'cancelled',
          updated_at = CURRENT_TIMESTAMP
        WHERE id = ? AND is_deleted = 0
      `;

      await database.query(query, [orderId]);
    } catch (error) {
      console.error('更新订单退款状态失败:', error);
      throw error;
    }
  }

  /**
   * 生成支付订单号
   * @returns {string} 支付订单号
   */
  generatePaymentNo() {
    const timestamp = Date.now();
    const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
    return `PAY${timestamp}${random}`;
  }

  /**
   * 生成退款订单号
   * @returns {string} 退款订单号
   */
  generateRefundNo() {
    const timestamp = Date.now();
    const random = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
    return `REF${timestamp}${random}`;
  }

  /**
   * 生成支付参数（模拟）
   * @param {Object} payment - 支付订单
   * @returns {Promise<Object>} 支付参数
   */
  async generatePaymentParams(payment) {
    try {
      const timestamp = Math.floor(Date.now() / 1000).toString();
      const nonceStr = crypto.randomBytes(16).toString('hex');

      // 模拟微信支付参数
      if (payment.payment_channel === 'wechat') {
        return {
          timeStamp: timestamp,
          nonceStr: nonceStr,
          package: `prepay_id=wx${timestamp}${nonceStr}`,
          signType: 'MD5',
          paySign: this.generateSign({
            timeStamp: timestamp,
            nonceStr: nonceStr,
            package: `prepay_id=wx${timestamp}${nonceStr}`,
            signType: 'MD5'
          })
        };
      }

      // 模拟支付宝参数
      if (payment.payment_channel === 'alipay') {
        return {
          orderString: `app_id=2021000000000000&method=alipay.trade.app.pay&charset=utf-8&sign_type=RSA2&timestamp=${timestamp}&version=1.0&notify_url=https://api.jiebanke.com/payment/alipay/notify&biz_content={"out_trade_no":"${payment.payment_no}","total_amount":"${payment.amount}","subject":"订单支付","product_code":"QUICK_MSECURITY_PAY"}`
        };
      }

      return {};
    } catch (error) {
      console.error('生成支付参数失败:', error);
      throw error;
    }
  }

  /**
   * 生成签名（模拟）
   * @param {Object} params - 参数
   * @returns {string} 签名
   */
  generateSign(params) {
    const sortedParams = Object.keys(params)
      .sort()
      .map(key => `${key}=${params[key]}`)
      .join('&');
    
    return crypto
      .createHash('md5')
      .update(sortedParams + '&key=your_secret_key')
      .digest('hex')
      .toUpperCase();
  }

  /**
   * 获取支付统计信息
   * @param {Object} filters - 筛选条件
   * @returns {Promise<Object>} 统计信息
   */
  async getPaymentStatistics(filters = {}) {
    try {
      const { start_date, end_date, payment_method } = filters;

      let whereClause = 'WHERE p.is_deleted = 0';
      const params = [];

      if (start_date) {
        whereClause += ' AND p.created_at >= ?';
        params.push(start_date);
      }

      if (end_date) {
        whereClause += ' AND p.created_at <= ?';
        params.push(end_date);
      }

      if (payment_method) {
        whereClause += ' AND p.payment_method = ?';
        params.push(payment_method);
      }

      const query = `
        SELECT 
          COUNT(*) as total_payments,
          SUM(CASE WHEN status = 'paid' THEN 1 ELSE 0 END) as successful_payments,
          SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed_payments,
          SUM(CASE WHEN status = 'refunded' THEN 1 ELSE 0 END) as refunded_payments,
          SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) as total_amount,
          AVG(CASE WHEN status = 'paid' THEN amount ELSE NULL END) as average_amount,
          payment_method,
          payment_channel
        FROM payments p
        ${whereClause}
        GROUP BY payment_method, payment_channel
      `;

      const [statistics] = await database.query(query, params);
      
      return statistics;
    } catch (error) {
      console.error('获取支付统计失败:', error);
      throw error;
    }
  }
}

module.exports = new PaymentService();