import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import { describe, expect, it, vi } from "vitest";
import { TimeEntryForm } from "../src/components/TimeEntryForm";

// stub api module
vi.mock("../src/lib/api", () => ({
  api: {
    projects: {
      list: () =>
        Promise.resolve([
          {
            id: 1,
            name: "Test Project",
            timeBudgetMinutes: 6000,
            costBudgetCents: 100000,
            hourlyRateCents: 10000,
            minutesLogged: 0,
            costLoggedCents: 0,
            timeExceeded: false,
            costExceeded: false,
          },
        ]),
    },
    timeEntries: {
      create: vi.fn().mockResolvedValue({
        id: 42,
        userId: 1,
        userName: "Alice",
        projectId: 1,
        projectName: "Test Project",
        entryDate: "2026-05-16",
        durationMinutes: 90,
      }),
    },
  },
}));

function renderForm(onSaved = vi.fn()) {
  return render(
    <MemoryRouter>
      <TimeEntryForm userId={1} onSaved={onSaved} />
    </MemoryRouter>,
  );
}

describe("TimeEntryForm", () => {
  it("submits with correct durationMinutes", async () => {
    const onSaved = vi.fn();
    renderForm(onSaved);

    // wait for project list to load
    await waitFor(() =>
      expect(screen.getByRole("combobox")).toBeInTheDocument(),
    );

    const durationInput = screen.getByPlaceholderText(/e\.g\. 2:30/i);
    fireEvent.change(durationInput, { target: { value: "1:30" } });

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

    const { api } = await import("../src/lib/api");
    await waitFor(() => {
      expect(api.timeEntries.create).toHaveBeenCalledWith(
        expect.objectContaining({ durationMinutes: 90 }),
      );
    });
    await waitFor(() => expect(onSaved).toHaveBeenCalled());
  });

  it("shows error for invalid duration format", async () => {
    renderForm();
    await waitFor(() => screen.getByRole("combobox"));

    const durationInput = screen.getByPlaceholderText(/e\.g\. 2:30/i);
    fireEvent.change(durationInput, { target: { value: "abc" } });
    fireEvent.click(screen.getByRole("button", { name: /log/i }));

    expect(await screen.findByText(/h:mm format/i)).toBeInTheDocument();
  });
});
