import { FundAllocationDomainService } from './fund-allocation.service';
import { PlantingOrder } from '../aggregates/planting-order.aggregate';
import { FundAllocationTargetType } from '../value-objects/fund-allocation-target-type.enum';

describe('FundAllocationDomainService', () => {
  let service: FundAllocationDomainService;

  beforeEach(() => {
    service = new FundAllocationDomainService();
  });

  describe('calculateAllocations', () => {
    it('应该正确计算1棵树的资金分配', () => {
      jest.useFakeTimers();

      const order = PlantingOrder.create(BigInt(1), 1);
      order.selectProvinceCity('440000', '广东省', '440100', '广州市');
      jest.advanceTimersByTime(5000);
      order.confirmProvinceCity();

      const context = {
        referralChain: ['ref1', 'ref2'],
        nearestProvinceAuth: 'province_auth_1',
        nearestCityAuth: 'city_auth_1',
        nearestCommunity: 'community_1',
      };

      const allocations = service.calculateAllocations(order, context);

      expect(allocations.length).toBe(10);

      // 验证各项金额
      const costAlloc = allocations.find(
        (a) => a.targetType === FundAllocationTargetType.COST_ACCOUNT,
      );
      expect(costAlloc?.amount).toBe(400);

      const opAlloc = allocations.find(
        (a) => a.targetType === FundAllocationTargetType.OPERATION_ACCOUNT,
      );
      expect(opAlloc?.amount).toBe(300);

      const hqAlloc = allocations.find(
        (a) => a.targetType === FundAllocationTargetType.HEADQUARTERS_COMMUNITY,
      );
      expect(hqAlloc?.amount).toBe(9);

      const referralAlloc = allocations.find(
        (a) => a.targetType === FundAllocationTargetType.REFERRAL_RIGHTS,
      );
      expect(referralAlloc?.amount).toBe(500);
      expect(referralAlloc?.targetAccountId).toBe('ref1');

      const poolAlloc = allocations.find(
        (a) => a.targetType === FundAllocationTargetType.RWAD_POOL,
      );
      expect(poolAlloc?.amount).toBe(800);

      // 验证总额
      const total = allocations.reduce((sum, a) => sum + a.amount, 0);
      expect(total).toBe(2199);

      jest.useRealTimers();
    });

    it('应该正确计算5棵树的资金分配', () => {
      jest.useFakeTimers();

      const order = PlantingOrder.create(BigInt(1), 5);
      order.selectProvinceCity('440000', '广东省', '440100', '广州市');
      jest.advanceTimersByTime(5000);
      order.confirmProvinceCity();

      const context = {
        referralChain: [],
        nearestProvinceAuth: null,
        nearestCityAuth: null,
        nearestCommunity: null,
      };

      const allocations = service.calculateAllocations(order, context);

      const total = allocations.reduce((sum, a) => sum + a.amount, 0);
      expect(total).toBe(2199 * 5);

      jest.useRealTimers();
    });

    it('应该在没有推荐人时使用总部社区', () => {
      jest.useFakeTimers();

      const order = PlantingOrder.create(BigInt(1), 1);
      order.selectProvinceCity('440000', '广东省', '440100', '广州市');
      jest.advanceTimersByTime(5000);
      order.confirmProvinceCity();

      const context = {
        referralChain: [],
        nearestProvinceAuth: null,
        nearestCityAuth: null,
        nearestCommunity: null,
      };

      const allocations = service.calculateAllocations(order, context);

      const referralAlloc = allocations.find(
        (a) => a.targetType === FundAllocationTargetType.REFERRAL_RIGHTS,
      );
      expect(referralAlloc?.targetAccountId).toBe('SYSTEM_HEADQUARTERS_COMMUNITY');

      jest.useRealTimers();
    });
  });

  describe('getPoolInjectionAmount', () => {
    it('应该返回正确的底池注入金额', () => {
      expect(service.getPoolInjectionAmount(1)).toBe(800);
      expect(service.getPoolInjectionAmount(5)).toBe(4000);
      expect(service.getPoolInjectionAmount(10)).toBe(8000);
    });
  });
});
