import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { render, screen, waitFor, fireEvent, cleanup, within } from '@testing-library/react';
import ViewIngredientModal from '@/app/dashboard/ingredients/ViewIngredientModal';

const baseIngredient = {
  _id: 'ing1',
  code: 'ING-001',
  name: 'Organic Butter',
  category: 'Dairy',
  subcategory: 'Fresh',
  quantity: 10,
  unit: 'kg',
  unitPrice: 5.00,
  vat: 9,
  supplier: 'Acme Foods',
  createdAt: '2024-01-01T00:00:00Z',
  updatedAt: '2024-01-02T00:00:00Z',
};

function mockFetch(data: unknown) {
  return vi.spyOn(global, 'fetch').mockResolvedValue({
    json: () => Promise.resolve(data),
  } as Response);
}

describe('ViewIngredientModal', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.restoreAllMocks();
  });

  afterEach(() => {
    cleanup();
  });

  it('renders nothing when open=false', () => {
    const { container } = render(
      <ViewIngredientModal open={false} ingredientId="ing1" onClose={vi.fn()} />
    );
    expect(container.innerHTML).toBe('');
  });

  it('shows loading spinner then ingredient data', async () => {
    mockFetch(baseIngredient);

    const { container } = render(
      <ViewIngredientModal open={true} ingredientId="ing1" onClose={vi.fn()} />
    );

    expect(within(container).getByText('Loading...')).toBeInTheDocument();

    await waitFor(() => {
      expect(within(container).getByText('Organic Butter')).toBeInTheDocument();
    });
  });

  it('displays pricing section (gross, VAT, net price)', async () => {
    mockFetch(baseIngredient);

    const { container } = render(
      <ViewIngredientModal open={true} ingredientId="ing1" onClose={vi.fn()} />
    );

    await waitFor(() => {
      expect(within(container).getByText('Pricing')).toBeInTheDocument();
    });

    // Gross: €5.00
    expect(within(container).getByText(/€5\.00/)).toBeInTheDocument();
    // VAT: rendered as {vat}% — separate text nodes so use regex
    expect(within(container).getByText(/9%/)).toBeInTheDocument();
    // Net: 5.00 * 1.09 = 5.45
    expect(within(container).getByText(/€5\.45/)).toBeInTheDocument();
  });

  it('shows discount section only when discountValue > 0', async () => {
    const withDiscount = {
      ...baseIngredient,
      discountType: 'percent' as const,
      discountValue: 10,
      applyDiscountToNet: false,
    };
    mockFetch(withDiscount);

    const { container } = render(
      <ViewIngredientModal open={true} ingredientId="ing1" onClose={vi.fn()} />
    );

    await waitFor(() => {
      expect(within(container).getByText('Discount')).toBeInTheDocument();
    });

    expect(within(container).getByText('Percentage')).toBeInTheDocument();
    expect(within(container).getByText('10%')).toBeInTheDocument();
  });

  it('hides discount section when not present', async () => {
    mockFetch(baseIngredient);

    const { container } = render(
      <ViewIngredientModal open={true} ingredientId="ing1" onClose={vi.fn()} />
    );

    await waitFor(() => {
      expect(within(container).getByText('Organic Butter')).toBeInTheDocument();
    });

    expect(within(container).queryByText('Discount')).not.toBeInTheDocument();
  });

  it('shows advanced section only when advanced fields present', async () => {
    const withAdvanced = {
      ...baseIngredient,
      minStockLevel: 5,
      storageInstructions: 'Keep refrigerated',
      shelfLifeDays: 30,
      notes: 'Premium quality',
    };
    mockFetch(withAdvanced);

    const { container } = render(
      <ViewIngredientModal open={true} ingredientId="ing1" onClose={vi.fn()} />
    );

    await waitFor(() => {
      expect(within(container).getByText('Additional Details')).toBeInTheDocument();
    });

    expect(within(container).getByText('Keep refrigerated')).toBeInTheDocument();
    expect(within(container).getByText('30 days')).toBeInTheDocument();
    expect(within(container).getByText('Premium quality')).toBeInTheDocument();
  });

  it('hides advanced section when not present', async () => {
    mockFetch(baseIngredient);

    const { container } = render(
      <ViewIngredientModal open={true} ingredientId="ing1" onClose={vi.fn()} />
    );

    await waitFor(() => {
      expect(within(container).getByText('Organic Butter')).toBeInTheDocument();
    });

    expect(within(container).queryByText('Additional Details')).not.toBeInTheDocument();
  });

  it('calls onClose on close button', async () => {
    mockFetch(baseIngredient);
    const onClose = vi.fn();

    const { container } = render(
      <ViewIngredientModal open={true} ingredientId="ing1" onClose={onClose} />
    );

    await waitFor(() => {
      expect(within(container).getByText('Organic Butter')).toBeInTheDocument();
    });

    fireEvent.click(within(container).getByRole('button', { name: 'Close' }));
    expect(onClose).toHaveBeenCalledOnce();
  });
});
