import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import DailyStatusForm from '../src/components/DailyStatusForm';
import * as client from '../src/api/client';

jest.mock('../src/api/client', () => ({
  dailyStatusesApi: {
    create: jest.fn(),
    update: jest.fn(),
  },
  experimentsApi: {
    updateTemplate: jest.fn(),
  },
}));

const ANIMAL_ID = 'animal-001';
const onSuccess = jest.fn();
const onCancel = jest.fn();

const BUILTIN_TEMPLATE = [
  { fieldId: 'f1', key: 'vitals', label: 'Vitals', type: 'textarea', builtin: true, active: true, width: 100 },
  { fieldId: 'f2', key: 'treatment', label: 'Treatment', type: 'textarea', builtin: true, active: true, width: 100 },
  { fieldId: 'f3', key: 'notes', label: 'Notes', type: 'textarea', builtin: true, active: true, width: 100 },
  { fieldId: 'f4', key: 'experiment_description', label: 'Experiment Description', type: 'textarea', builtin: true, active: true, width: 100 },
];

beforeEach(() => jest.clearAllMocks());

describe('DailyStatusForm', () => {
  it('renders date field (required) and optional fields', () => {
    render(<DailyStatusForm animalId={ANIMAL_ID} template={BUILTIN_TEMPLATE} onSuccess={onSuccess} onCancel={onCancel} />);
    expect(screen.getByLabelText(/date/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/vitals/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/treatment/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/notes/i)).toBeInTheDocument();
    expect(screen.getByLabelText(/experiment description/i)).toBeInTheDocument();
  });

  it('pre-fills date with today by default', () => {
    render(<DailyStatusForm animalId={ANIMAL_ID} template={BUILTIN_TEMPLATE} onSuccess={onSuccess} onCancel={onCancel} />);
    const today = new Date().toISOString().slice(0, 10);
    expect(screen.getByLabelText(/date/i)).toHaveValue(today);
  });

  it('shows error when date is cleared', async () => {
    render(<DailyStatusForm animalId={ANIMAL_ID} template={BUILTIN_TEMPLATE} onSuccess={onSuccess} onCancel={onCancel} />);
    const dateInput = screen.getByLabelText(/date/i);
    await userEvent.clear(dateInput);
    fireEvent.click(screen.getByRole('button', { name: /log status/i }));
    expect(await screen.findByRole('alert')).toHaveTextContent(/date is required/i);
    expect(client.dailyStatusesApi.create).not.toHaveBeenCalled();
  });

  it('calls create with correct payload including animal_id', async () => {
    const status = { id: 's-1', animal_id: ANIMAL_ID, date: '2024-06-01', vitals: 'HR 72' };
    client.dailyStatusesApi.create.mockResolvedValue(status);

    render(<DailyStatusForm animalId={ANIMAL_ID} template={BUILTIN_TEMPLATE} onSuccess={onSuccess} onCancel={onCancel} />);

    const dateInput = screen.getByLabelText(/date/i);
    fireEvent.change(dateInput, { target: { value: '2024-06-01' } });

    await userEvent.type(screen.getByLabelText(/vitals/i), 'HR 72');

    fireEvent.click(screen.getByRole('button', { name: /log status/i }));

    await waitFor(() =>
      expect(client.dailyStatusesApi.create).toHaveBeenCalledWith(
        expect.objectContaining({ animal_id: ANIMAL_ID, vitals: 'HR 72' })
      )
    );
    await waitFor(() => expect(onSuccess).toHaveBeenCalled());
  });

  it('shows "Save Changes" and pre-fills fields for existing status', () => {
    const existing = {
      id: 's-1',
      date: '2024-06-01T00:00:00.000Z',
      vitals: 'HR 72',
      treatment: 'Control',
      notes: 'Normal',
      experiment_description: 'Baseline',
    };
    render(
      <DailyStatusForm
        existing={existing}
        template={BUILTIN_TEMPLATE}
        animalId={ANIMAL_ID}
        onSuccess={onSuccess}
        onCancel={onCancel}
      />
    );
    expect(screen.getByRole('button', { name: /save changes/i })).toBeInTheDocument();
    expect(screen.getByDisplayValue('HR 72')).toBeInTheDocument();
  });

  it('calls onCancel when Cancel is clicked', () => {
    render(<DailyStatusForm animalId={ANIMAL_ID} template={BUILTIN_TEMPLATE} onSuccess={onSuccess} onCancel={onCancel} />);
    fireEvent.click(screen.getByRole('button', { name: /cancel/i }));
    expect(onCancel).toHaveBeenCalled();
  });
});
