import { ConfigService } from '@nestjs/config';
import { Expense, ExpenseStatus } from '@/entities/expense.entity';
import { GroupMember, GroupRole } from '@/entities/group-member.entity';
import { User } from '@/entities/user.entity';
import { TripClosingMailService } from './trip-closing-mail.service';
import { Trip } from '@/entities/trip.entity';

describe('TripClosingMailService', () => {
  const user = (id: string, name: string) => ({ id, name } as User);
  const member = (account: User, role = GroupRole.MEMBER) =>
    ({ user: account, role } as GroupMember);

  it('tính số tiền mỗi người nhận lại hoặc chuyển cho trưởng nhóm', () => {
    const service = new TripClosingMailService(new ConfigService());
    const leader = user('leader', 'Trưởng nhóm');
    const an = user('an', 'An');
    const binh = user('binh', 'Bình');
    const members = [
      member(leader, GroupRole.OWNER),
      member(an),
      member(binh),
    ];
    const expense = {
      amount: 300_000,
      status: ExpenseStatus.APPROVED,
      paidBy: leader,
      participants: [
        { user: leader, amount: 100_000 },
        { user: an, amount: 100_000 },
        { user: binh, amount: 100_000 },
      ],
    } as Expense;

    const balances = service.calculateBalances(members, [expense]);

    expect(
      Object.fromEntries(
        balances.map((item) => [item.member.user.id, item.balance]),
      ),
    ).toEqual({ leader: 200_000, an: -100_000, binh: -100_000 });
  });

  it('cộng nhiều khoản chi và chuyển decimal từ database sang number', () => {
    const service = new TripClosingMailService(new ConfigService());
    const leader = user('leader', 'Trưởng nhóm');
    const an = user('an', 'An');
    const members = [member(leader, GroupRole.OWNER), member(an)];
    const expenses = [
      {
        amount: '100000.50',
        paidBy: leader,
        participants: [{ user: an, amount: '100000.50' }],
      },
      {
        amount: '25000.25',
        paidBy: an,
        participants: [{ user: leader, amount: '25000.25' }],
      },
    ] as unknown as Expense[];

    const balances = service.calculateBalances(members, expenses);

    expect(balances.find((item) => item.member.user.id === leader.id)?.balance)
      .toBe(75_000.25);
    expect(balances.find((item) => item.member.user.id === an.id)?.balance)
      .toBe(-75_000.25);
  });

  it('tạo PDF tiếng Việt hợp lệ', async () => {
    const service = new TripClosingMailService(new ConfigService());
    const leader = user('leader', 'Trưởng nhóm');
    const leaderMember = member(leader, GroupRole.OWNER);
    const trip = {
      name: 'Đà Nẵng',
      location: 'Hội An',
      startDate: new Date('2026-07-01'),
      endDate: new Date('2026-07-03'),
      expenses: [],
    } as Trip;
    const balances = service.calculateBalances([leaderMember], []);

    const pdf = await (service as any).createPdf(
      trip,
      balances,
      leaderMember,
    );

    expect(pdf.subarray(0, 5).toString()).toBe('%PDF-');
    expect(pdf.length).toBeGreaterThan(1_000);
  });
});
