import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
import { authMiddleware } from '@d8d/core-module-mt/auth-module-mt/middleware';
import { AppDataSource, ErrorSchema, parseWithAwait } from '@d8d/shared-utils';
import { AuthContext } from '@d8d/shared-types';
import { CreditBalanceService } from '../services';
import { CreditBalanceSchema, PaymentDto } from '../schemas';
import { OrderMt } from '@d8d/orders-module-mt';
import { PayStatus, PayType } from '@d8d/orders-module-mt';

const paymentRoute = createRoute({
  method: 'post',
  path: '/payment',
  middleware: [authMiddleware],
  request: {
    body: {
      content: {
        'application/json': {
          schema: PaymentDto
        }
      }
    }
  },
  responses: {
    200: {
      description: '额度支付成功',
      content: {
        'application/json': {
          schema: CreditBalanceSchema
        }
      }
    },
    400: {
      description: '请求参数错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    401: {
      description: '认证失败',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    403: {
      description: '权限不足',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    },
    500: {
      description: '服务器内部错误',
      content: {
        'application/json': {
          schema: ErrorSchema
        }
      }
    }
  }
});

const paymentRoutes = new OpenAPIHono<AuthContext>()
  .openapi(paymentRoute, async (c) => {
    const user = c.get('user');
    const data = c.req.valid('json');

    // 验证referenceId是否为有效的订单ID
    if (!data.referenceId) {
      return c.json(
        { code: 400, message: '订单ID不能为空' },
        400
      );
    }

    const orderId = parseInt(data.referenceId);
    if (isNaN(orderId) || orderId <= 0) {
      return c.json(
        { code: 400, message: '订单ID格式无效' },
        400
      );
    }

    const queryRunner = AppDataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 1. 查询订单信息，验证订单状态和金额
      const orderRepository = queryRunner.manager.getRepository(OrderMt);
      const order = await orderRepository.findOne({
        where: { id: orderId, tenantId: user.tenantId, userId: user.id }
      });

      if (!order) {
        await queryRunner.rollbackTransaction();
        return c.json(
          { code: 404, message: `订单不存在或无权访问，订单ID: ${orderId}，用户ID: ${user.id}` },
          404
        );
      }

      // 2. 验证订单支付状态，只允许未支付的订单进行支付
      if (order.payState !== PayStatus.UNPAID) {
        await queryRunner.rollbackTransaction();

        let statusMessage = '';
        switch (order.payState) {
          case PayStatus.PAYING:
            statusMessage = '订单正在支付中';
            break;
          case PayStatus.SUCCESS:
            statusMessage = '订单已支付成功';
            break;
          case PayStatus.REFUNDED:
            statusMessage = '订单已退款';
            break;
          case PayStatus.FAILED:
            statusMessage = '订单支付失败';
            break;
          case PayStatus.CLOSED:
            statusMessage = '订单已关闭';
            break;
          default:
            statusMessage = '订单状态异常';
        }

        return c.json(
          { code: 400, message: `无法支付: ${statusMessage}` },
          400
        );
      }

      // 3. 使用订单的实际支付金额，而不是前端传递的金额
      // 确保paymentAmount是数字类型（TypeORM decimal字段可能返回字符串）
      const paymentAmount = Number(order.payAmount);
      if (isNaN(paymentAmount) || paymentAmount <= 0) {
        await queryRunner.rollbackTransaction();
        return c.json(
          { code: 400, message: '订单支付金额无效' },
          400
        );
      }

      // 4. 在事务中执行额度扣减
      const service = new CreditBalanceService(queryRunner.manager.connection);
      const balance = await service.deductAmount({
        tenantId: user.tenantId,
        userId: user.id,
        amount: paymentAmount, // 使用订单的实际支付金额
        referenceId: orderId.toString(), // 使用订单ID作为referenceId
        operatorId: data.operatorId,
        remark: data.remark || `订单支付 - 订单号: ${order.orderNo}`
      });

      // 5. 更新订单支付状态（添加用户ID检查，防止越权更新）
      const updateResult = await orderRepository.update(
        { id: orderId, tenantId: user.tenantId, userId: user.id },
        {
          payState: PayStatus.SUCCESS,
          payType: PayType.CREDIT,
          updatedAt: new Date()
        }
      );

      if (updateResult.affected === 0) {
        throw new Error(`订单状态更新失败，订单ID: ${orderId}，用户ID: ${user.id}`);
      }

      console.debug(`额度支付成功，订单ID: ${orderId}, 租户ID: ${user.tenantId}, 金额: ${paymentAmount}`);

      await queryRunner.commitTransaction();

      const responseData = await parseWithAwait(CreditBalanceSchema, balance);
      return c.json(responseData, 200);
    } catch (error) {
      await queryRunner.rollbackTransaction();
      console.error('额度支付失败:', error);
      return c.json(
        { code: 500, message: error instanceof Error ? error.message : '额度支付失败' },
        500
      );
    } finally {
      await queryRunner.release();
    }
  });

export default paymentRoutes;