import { GenericCrudService } from '@d8d/shared-crud';
import { DataSource, Repository } from 'typeorm';
import { OrderMt } from '../entities/order.mt.entity';
import { OrderGoodsMt } from '../entities/order-goods.mt.entity';
import { GoodsMt } from '@d8d/goods-module-mt';
import { DeliveryAddressMt } from '@d8d/delivery-address-module-mt';
import type { CreateOrderRequest } from '../schemas/create-order.schema';

export class OrderMtService extends GenericCrudService<OrderMt> {
  private orderGoodsRepository: Repository<OrderGoodsMt>;
  private goodsRepository: Repository<GoodsMt>;
  private deliveryAddressRepository: Repository<DeliveryAddressMt>;

  constructor(dataSource: DataSource) {
    super(dataSource, OrderMt, {
      tenantOptions: { enabled: true, tenantIdField: 'tenantId' }
    });
    this.orderGoodsRepository = dataSource.getRepository(OrderGoodsMt);
    this.goodsRepository = dataSource.getRepository(GoodsMt);
    this.deliveryAddressRepository = dataSource.getRepository(DeliveryAddressMt);
  }

  /**
   * 创建订单
   * @param data 创建订单请求数据
   * @param userId 用户ID
   * @param tenantId 租户ID
   * @returns 创建的订单信息
   */
  async createOrder(data: CreateOrderRequest, userId: number, tenantId: number): Promise<{
    orderId: number;
    orderNo: string;
    amount: number;
    payAmount: number;
  }> {
    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      const { addressId, productOwn, consumeFrom, products } = data;

      // 验证商品信息并计算总价
      let totalAmount = 0;
      let totalCostAmount = 0;
      const goodsInfo = [];

      for (const item of products) {
        const goods = await this.goodsRepository.findOne({
          where: { id: item.id, tenantId }
        });

        if (!goods) {
          throw new Error(`商品ID ${item.id} 不存在`);
        }

        if (goods.stock < item.num) {
          throw new Error(`商品 ${goods.name} 库存不足`);
        }

        const itemAmount = goods.price * item.num;
        const itemCostAmount = goods.costPrice * item.num;

        totalAmount += itemAmount;
        totalCostAmount += itemCostAmount;

        goodsInfo.push({
          goods,
          quantity: item.num,
          amount: itemAmount,
          costAmount: itemCostAmount
        });
      }

      // 获取收货地址信息
      let deliveryAddress = null;
      if (addressId) {
        deliveryAddress = await this.deliveryAddressRepository.findOne({
          where: { id: addressId, userId, tenantId }
        });

        if (!deliveryAddress) {
          throw new Error('收货地址不存在');
        }
      }

      // 生成订单号
      const orderNo = this.generateOrderNo();

      // 创建订单
      const order = this.repository.create({
        tenantId,
        orderNo,
        userId,
        amount: totalAmount,
        costAmount: totalCostAmount,
        payAmount: totalAmount, // 这里可以根据优惠规则计算实际支付金额
        orderType: 1, // 实物订单
        payType: consumeFrom === '积分兑换' ? 1 : 2, // 根据消费来源设置支付类型
        payState: 0, // 未支付
        state: 0, // 未发货
        addressId: addressId || 0,
        merchantId: goodsInfo[0]?.goods.merchantId || 0,
        supplierId: goodsInfo[0]?.goods.supplierId || 0,
        createdBy: userId,
        updatedBy: userId,
        // 设置收货地址信息（如果提供）
        ...(deliveryAddress && {
          receiverMobile: deliveryAddress.phone,
          recevierName: deliveryAddress.name,
          recevierProvince: deliveryAddress.receiverProvince,
          recevierCity: deliveryAddress.receiverCity,
          recevierDistrict: deliveryAddress.receiverDistrict,
          recevierTown: deliveryAddress.receiverTown,
          address: deliveryAddress.address
        })
      });

      const savedOrder = await queryRunner.manager.save(order);

      // 创建订单商品明细
      const orderGoodsList = goodsInfo.map(info => ({
        tenantId,
        orderId: savedOrder.id,
        orderNo,
        goodsId: info.goods.id,
        goodsName: info.goods.name,
        imageFileId: info.goods.imageFileId,
        goodsType: info.goods.goodsType,
        supplierId: info.goods.supplierId,
        costPrice: info.goods.costPrice,
        price: info.goods.price,
        num: info.quantity,
        freightAmount: 0,
        state: 0,
        createdBy: userId,
        updatedBy: userId,
        expressName: null,
        expressNo: null
      }));

      await queryRunner.manager.save(OrderGoodsMt, orderGoodsList);

      // 更新商品库存
      for (const item of goodsInfo) {
        await queryRunner.manager.update(GoodsMt, item.goods.id, {
          stock: () => `stock - ${item.quantity}`,
          salesNum: () => `sales_num + ${item.quantity}`
        });
      }

      await queryRunner.commitTransaction();

      return {
        orderId: savedOrder.id,
        orderNo: savedOrder.orderNo,
        amount: savedOrder.amount,
        payAmount: savedOrder.payAmount
      };

    } catch (error) {
      await queryRunner.rollbackTransaction();
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 生成订单号
   * 格式：年月日时分秒 + 6位随机数
   */
  private generateOrderNo(): string {
    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const day = String(now.getDate()).padStart(2, '0');
    const hour = String(now.getHours()).padStart(2, '0');
    const minute = String(now.getMinutes()).padStart(2, '0');
    const second = String(now.getSeconds()).padStart(2, '0');
    const random = String(Math.floor(Math.random() * 1000000)).padStart(6, '0');

    return `ORD${year}${month}${day}${hour}${minute}${second}${random}`;
  }
}