import { SubscriptionEntity } from '../entities/subscription.entity';

describe('SubscriptionEntity', () => {
  const makeSub = (_overrides?: Partial<Parameters<typeof SubscriptionEntity.createNew>[0]>) => {
    return SubscriptionEntity.createNew(
      'sub-1',
      'user-1',
      'plan-1',
      'AGENT_PRO',
      new Date('2026-01-01'),
      new Date('2026-02-01'),
    );
  };

  it('creates a new subscription with ACTIVE status', () => {
    const sub = makeSub();
    expect(sub.id).toBe('sub-1');
    expect(sub.userId).toBe('user-1');
    expect(sub.planTier).toBe('AGENT_PRO');
    expect(sub.status).toBe('ACTIVE');
    expect(sub.isActive()).toBe(true);
    expect(sub.cancelledAt).toBeNull();
  });

  it('emits SubscriptionCreatedEvent on creation', () => {
    const sub = makeSub();
    const events = sub.domainEvents;
    expect(events).toHaveLength(1);
    expect(events[0].eventName).toBe('subscription.created');
  });

  it('upgrades plan tier', () => {
    const sub = makeSub();
    sub.clearDomainEvents();

    const result = sub.upgrade('plan-2', 'ENTERPRISE');

    expect(result.isOk).toBe(true);
    expect(sub.planId).toBe('plan-2');
    expect(sub.planTier).toBe('ENTERPRISE');
    const events = sub.domainEvents;
    expect(events).toHaveLength(1);
    expect(events[0].eventName).toBe('subscription.upgraded');
  });

  it('returns error when upgrading non-active subscription', () => {
    const sub = makeSub();
    sub.cancel();

    const result = sub.upgrade('plan-2', 'ENTERPRISE');
    expect(result.isErr).toBe(true);
  });

  it('cancels subscription', () => {
    const sub = makeSub();
    sub.clearDomainEvents();

    const cancelResult = sub.cancel();

    expect(cancelResult.isOk).toBe(true);
    expect(sub.status).toBe('CANCELLED');
    expect(sub.cancelledAt).not.toBeNull();
    const events = sub.domainEvents;
    expect(events).toHaveLength(1);
    expect(events[0].eventName).toBe('subscription.cancelled');
  });

  it('returns error when cancelling already cancelled subscription', () => {
    const sub = makeSub();
    sub.cancel();

    const result = sub.cancel();
    expect(result.isErr).toBe(true);
    expect(result.unwrapErr().message).toContain('Subscription đã bị hủy');
  });

  it('marks past due', () => {
    const sub = makeSub();
    const pdResult = sub.markPastDue();
    expect(pdResult.isOk).toBe(true);
    expect(sub.status).toBe('PAST_DUE');
  });

  it('marks expired and emits SubscriptionExpiredEvent', () => {
    const sub = makeSub();
    sub.clearDomainEvents();
    const expResult = sub.markExpired();
    expect(expResult.isOk).toBe(true);
    expect(sub.status).toBe('EXPIRED');

    const events = sub.domainEvents;
    expect(events).toHaveLength(1);
    expect(events[0].eventName).toBe('subscription.expired');
  });

  it('renews period and emits SubscriptionRenewedEvent', () => {
    const sub = makeSub();
    sub.markPastDue();
    sub.clearDomainEvents();

    const newStart = new Date('2026-02-01');
    const newEnd = new Date('2026-03-01');
    sub.renewPeriod(newStart, newEnd);

    expect(sub.status).toBe('ACTIVE');
    expect(sub.currentPeriodStart).toEqual(newStart);
    expect(sub.currentPeriodEnd).toEqual(newEnd);

    const events = sub.domainEvents;
    expect(events).toHaveLength(1);
    expect(events[0].eventName).toBe('subscription.renewed');
  });
});
