import { ComponentFixture, TestBed } from '@angular/core/testing';
import { OrderTotalFormulaComponent } from './order-total-formula.component';
import { AdminOrder } from '../../models/admin-order.model';

function order(overrides: Partial<AdminOrder> = {}): AdminOrder {
  return {
    id: 'o1',
    orderNumber: '1001',
    status: 'pending',
    customer: { name: 'Buyer', email: 'b@example.com', phone: '' },
    payment: { method: 'card', status: 'paid', amount: 1000, currency: 'RUB' },
    shipping: { address: '', method: '', trackingNumber: '' },
    items: [],
    total: 1000,
    currency: 'RUB',
    notes: '',
    internalNotes: '',
    timeline: [],
    archived: false,
    createdAt: '2026-08-18T00:00:00.000Z',
    updatedAt: '2026-08-18T00:00:00.000Z',
    ...overrides,
  };
}

describe('OrderTotalFormulaComponent', () => {
  let fixture: ComponentFixture<OrderTotalFormulaComponent>;
  let component: OrderTotalFormulaComponent;

  beforeEach(() => {
    TestBed.configureTestingModule({ imports: [OrderTotalFormulaComponent] });
    fixture = TestBed.createComponent(OrderTotalFormulaComponent);
    component = fixture.componentInstance;
  });

  it('reports no breakdown when the order carries no line pricing data', () => {
    fixture.componentRef.setInput('order', order({
      items: [{ productId: 'p1', name: 'Widget', quantity: 1, price: 100 }],
    }));
    fixture.detectChanges();

    expect(component.hasFullBreakdown()).toBeFalse();
    expect(component.subtotalMinor()).toBeNull();
  });

  it('requires every line to carry unitPriceMinor before showing a breakdown', () => {
    fixture.componentRef.setInput('order', order({
      items: [
        { productId: 'p1', name: 'A', quantity: 1, price: 100, unitPriceMinor: 10000, lineTotalMinor: 10000 },
        { productId: 'p2', name: 'B', quantity: 1, price: 50 },
      ],
    }));
    fixture.detectChanges();

    // One line missing the field must not silently render a partial total.
    expect(component.hasFullBreakdown()).toBeFalse();
  });

  it('sums lineTotalMinor across lines for the subtotal', () => {
    fixture.componentRef.setInput('order', order({
      items: [
        { productId: 'p1', name: 'A', quantity: 2, price: 50, unitPriceMinor: 5000, lineTotalMinor: 10000 },
        { productId: 'p2', name: 'B', quantity: 1, price: 30, unitPriceMinor: 3000, lineTotalMinor: 3000 },
      ],
    }));
    fixture.detectChanges();

    expect(component.hasFullBreakdown()).toBeTrue();
    expect(component.subtotalMinor()).toBe(13000);
  });

  it('sums discounts across lines even when some lines have none', () => {
    fixture.componentRef.setInput('order', order({
      items: [
        { productId: 'p1', name: 'A', quantity: 1, price: 100, unitPriceMinor: 10000, lineTotalMinor: 9000, discountMinor: 1000 },
        { productId: 'p2', name: 'B', quantity: 1, price: 50, unitPriceMinor: 5000, lineTotalMinor: 5000 },
      ],
    }));
    fixture.detectChanges();

    expect(component.totalDiscountMinor()).toBe(1000);
  });

  it('formats minor units as a two-decimal major amount', () => {
    expect(component.toDisplay(123456)).toBe('1234.56');
  });

  it('returns null for missing amounts rather than "0.00"', () => {
    expect(component.toDisplay(undefined)).toBeNull();
    expect(component.toDisplay(null)).toBeNull();
  });
});
