import { describe, it, expect, vi, afterEach } from "vitest";
import { render, screen, fireEvent, cleanup } from "@testing-library/react";
import { NotificationItem } from "./notification-item";

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

const makeNotification = (overrides?: Record<string, unknown>) => ({
	id: "1",
	user_id: "user-1",
	category: "instance",
	severity: "info" as const,
	title: "Container started",
	message: null,
	source_type: null,
	source_id: null,
	metadata: {},
	read_at: null,
	dismissed_at: null,
	created_at: "2026-05-29T10:00:00Z",
	...overrides,
});

describe("NotificationItem", () => {
	it("displays title and relative time", () => {
		render(
			<NotificationItem
				notification={makeNotification()}
				onMarkRead={vi.fn()}
				onDismiss={vi.fn()}
			/>,
		);

		expect(screen.getByText("Container started")).toBeInTheDocument();
		expect(screen.getByText(/ago|just now/)).toBeInTheDocument();
	});

	it("applies unread styling when read_at is null", () => {
		render(
			<NotificationItem
				notification={makeNotification({ read_at: null })}
				onMarkRead={vi.fn()}
				onDismiss={vi.fn()}
			/>,
		);

		const row = screen.getByRole("listitem");
		expect(row.className).toContain("notification-item--unread");
	});

	it("applies read styling when read_at is set", () => {
		render(
			<NotificationItem
				notification={makeNotification({ read_at: "2026-05-29T10:01:00Z" })}
				onMarkRead={vi.fn()}
				onDismiss={vi.fn()}
			/>,
		);

		const row = screen.getByRole("listitem");
		expect(row.className).toContain("notification-item--read");
	});

	it("calls onMarkRead when mark read clicked", () => {
		const onMarkRead = vi.fn();
		render(
			<NotificationItem
				notification={makeNotification()}
				onMarkRead={onMarkRead}
				onDismiss={vi.fn()}
			/>,
		);

		fireEvent.click(screen.getByRole("button", { name: /mark read/i }));
		expect(onMarkRead).toHaveBeenCalledWith("1");
	});

	it("calls onDismiss when dismiss clicked", () => {
		const onDismiss = vi.fn();
		render(
			<NotificationItem
				notification={makeNotification()}
				onMarkRead={vi.fn()}
				onDismiss={onDismiss}
			/>,
		);

		fireEvent.click(screen.getByRole("button", { name: /dismiss/i }));
		expect(onDismiss).toHaveBeenCalledWith("1");
	});

	it("displays severity icon", () => {
		render(
			<NotificationItem
				notification={makeNotification({ severity: "error" })}
				onMarkRead={vi.fn()}
				onDismiss={vi.fn()}
			/>,
		);

		expect(screen.getByRole("img", { hidden: true })).toBeInTheDocument();
	});
});
