import { DataSource } from 'typeorm';
import { UserEntityMt } from '@d8d/user-module-mt';
import { MerchantMt } from '@d8d/merchant-module-mt';
import { SupplierMt } from '@d8d/supplier-module-mt';
import { DeliveryAddressMt } from '@d8d/delivery-address-module-mt';
import { OrderMt } from '@d8d/orders-module-mt';
import { AreaEntityMt } from '@d8d/geo-areas-mt';
import { PaymentMtEntity } from '../../src/entities/payment.mt.entity.js';
import { PaymentStatus } from '../../src/entities/payment.types.js';

/**
 * 支付测试数据工厂
 */
export class PaymentTestFactory {
  constructor(private dataSource: DataSource) {}

  /**
   * 创建测试用户
   */
  async createTestUser(tenantId: number = 1, options: Partial<UserEntityMt> = {}): Promise<UserEntityMt> {
    const userRepository = this.dataSource.getRepository(UserEntityMt);
    const timestamp = Date.now();

    const user = userRepository.create({
      username: `test_user_${timestamp}`,
      password: 'test_password',
      nickname: '测试用户',
      openid: 'oJy1-16IIG18XZLl7G32k1hHMUFg',
      tenantId,
      ...options
    });

    return await userRepository.save(user);
  }

  /**
   * 创建测试商户
   */
  async createTestMerchant(tenantId: number = 1, userId: number, options: Partial<MerchantMt> = {}): Promise<MerchantMt> {
    const merchantRepository = this.dataSource.getRepository(MerchantMt);
    const timestamp = Date.now();

    const merchant = merchantRepository.create({
      tenantId,
      name: '测试商户',
      username: `m${timestamp}`.slice(-19), // 确保不超过20字符
      password: 'test_password',
      state: 1,
      createdBy: userId,
      updatedBy: userId,
      ...options
    });

    return await merchantRepository.save(merchant);
  }

  /**
   * 创建测试供货商
   */
  async createTestSupplier(tenantId: number = 1, userId: number, options: Partial<SupplierMt> = {}): Promise<SupplierMt> {
    const supplierRepository = this.dataSource.getRepository(SupplierMt);
    const timestamp = Date.now();

    const supplier = supplierRepository.create({
      tenantId,
      name: '测试供货商',
      username: `s${timestamp}`.slice(-49), // 确保不超过50字符
      password: 'test_password',
      state: 1,
      createdBy: userId,
      updatedBy: userId,
      ...options
    });

    return await supplierRepository.save(supplier);
  }

  /**
   * 创建测试地区记录
   */
  async createTestArea(id: number, name: string, level: number, tenantId: number = 1, parentId: number | null = null): Promise<AreaEntityMt> {
    const areaRepository = this.dataSource.getRepository(AreaEntityMt);

    const area = areaRepository.create({
      id,
      tenantId,
      name,
      level,
      code: id.toString(),
      parentId,
      isDisabled: 0,
      isDeleted: 0,
      createdBy: 1,
      updatedBy: 1
    });

    return await areaRepository.save(area);
  }

  /**
   * 创建测试配送地址
   */
  async createTestDeliveryAddress(tenantId: number = 1, userId: number, options: Partial<DeliveryAddressMt> = {}): Promise<DeliveryAddressMt> {
    const addressRepository = this.dataSource.getRepository(DeliveryAddressMt);

    // 创建地区记录 - 先创建父级，再创建子级
    const province = await this.createTestArea(110000, '北京市', 1, tenantId, null);
    const city = await this.createTestArea(110100, '北京市', 2, tenantId, province.id);
    const district = await this.createTestArea(110101, '东城区', 3, tenantId, city.id);
    const town = await this.createTestArea(110101001, '东华门街道', 4, tenantId, district.id);

    const address = addressRepository.create({
      tenantId,
      userId,
      name: '测试收货人',
      phone: '13800138000',
      receiverProvince: province.id,
      receiverCity: city.id,
      receiverDistrict: district.id,
      receiverTown: town.id,
      address: '测试地址',
      isDefault: 1,
      state: 1,
      createdBy: userId,
      updatedBy: userId,
      ...options
    });

    return await addressRepository.save(address);
  }

  /**
   * 创建测试订单
   */
  async createTestOrder(
    tenantId: number = 1,
    userId: number,
    merchantId: number,
    supplierId: number,
    addressId: number,
    options: Partial<OrderMt> = {}
  ): Promise<OrderMt> {
    const orderRepository = this.dataSource.getRepository(OrderMt);
    const timestamp = Date.now();

    const order = orderRepository.create({
      tenantId,
      orderNo: `ORD${timestamp}`,
      userId,
      amount: 1,
      costAmount: 0.5,
      payAmount: 1,
      orderType: 1,
      payType: 2,
      payState: 0, // 未支付
      state: 0,
      addressId,
      merchantId,
      supplierId,
      createdBy: userId,
      updatedBy: userId,
      ...options
    });

    return await orderRepository.save(order);
  }

  /**
   * 创建测试支付记录
   */
  async createTestPayment(
    externalOrderId: number,
    userId: number,
    tenantId: number = 1,
    options: Partial<PaymentMtEntity> = {}
  ): Promise<PaymentMtEntity> {
    const paymentRepository = this.dataSource.getRepository(PaymentMtEntity);
    const timestamp = Date.now();

    const payment = paymentRepository.create({
      externalOrderId,
      userId,
      tenantId,
      totalAmount: 1,
      description: '测试支付',
      paymentStatus: PaymentStatus.PROCESSING,
      openid: 'oJy1-16IIG18XZLl7G32k1hHMUFg',
      outTradeNo: `ORDER_${externalOrderId}_${timestamp}`,
      ...options
    });

    return await paymentRepository.save(payment);
  }

  /**
   * 创建完整的测试环境数据
   */
  async createCompleteTestData(tenantId: number = 1, userOptions: Partial<UserEntityMt> = {}): Promise<{
    user: UserEntityMt;
    merchant: MerchantMt;
    supplier: SupplierMt;
    address: DeliveryAddressMt;
    order: OrderMt;
    payment: PaymentMtEntity;
  }> {
    const user = await this.createTestUser(tenantId, userOptions);
    const merchant = await this.createTestMerchant(tenantId, user.id);
    const supplier = await this.createTestSupplier(tenantId, user.id);
    const address = await this.createTestDeliveryAddress(tenantId, user.id);
    const order = await this.createTestOrder(tenantId, user.id, merchant.id, supplier.id, address.id);
    const payment = await this.createTestPayment(order.id, user.id, tenantId);

    return {
      user,
      merchant,
      supplier,
      address,
      order,
      payment
    };
  }

  /**
   * 创建多租户测试数据
   */
  async createMultiTenantTestData(): Promise<{
    tenant1: {
      user: UserEntityMt;
      merchant: MerchantMt;
      supplier: SupplierMt;
      address: DeliveryAddressMt;
      order: OrderMt;
      payment: PaymentMtEntity;
    };
    tenant2: {
      user: UserEntityMt;
      merchant: MerchantMt;
      supplier: SupplierMt;
      address: DeliveryAddressMt;
      order: OrderMt;
      payment: PaymentMtEntity;
    };
  }> {
    const timestamp = Date.now();
    const tenant1 = await this.createCompleteTestData(1, {
      username: `tenant1_user_${timestamp}`,
      openid: `tenant1_openid_${timestamp}`
    });
    const tenant2 = await this.createCompleteTestData(2, {
      username: `tenant2_user_${timestamp}`,
      openid: `tenant2_openid_${timestamp}`
    });

    return {
      tenant1,
      tenant2
    };
  }
}