/**
 * TasksWidget Component Tests
 * Following TDD principles
 */

import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, waitFor } from "@testing-library/react";
import { TasksWidget } from "../TasksWidget";

// Mock fetch for API calls
global.fetch = vi.fn() as typeof global.fetch;

describe("TasksWidget", (): void => {
  beforeEach((): void => {
    vi.clearAllMocks();
  });

  it("should render loading state initially", (): void => {
    vi.mocked(global.fetch).mockImplementation(
      () =>
        new Promise(() => {
          // Intentionally empty - creates a never-resolving promise for loading state
        })
    );

    render(<TasksWidget id="tasks-1" />);

    expect(screen.getByText(/loading/i)).toBeInTheDocument();
  });

  // TODO: Re-enable when TasksWidget uses fetch API instead of setTimeout mock data
  it.skip("should render task statistics", async (): Promise<void> => {
    const mockTasks = [
      { id: "1", title: "Task 1", status: "IN_PROGRESS", priority: "HIGH" },
      { id: "2", title: "Task 2", status: "COMPLETED", priority: "MEDIUM" },
      { id: "3", title: "Task 3", status: "NOT_STARTED", priority: "LOW" },
    ];

    vi.mocked(global.fetch).mockResolvedValueOnce({
      ok: true,
      json: () => Promise.resolve(mockTasks),
    } as unknown as Response);

    render(<TasksWidget id="tasks-1" />);

    await waitFor(() => {
      expect(screen.getByText("3")).toBeInTheDocument(); // Total
      expect(screen.getByText("1")).toBeInTheDocument(); // In Progress
      expect(screen.getByText("1")).toBeInTheDocument(); // Completed
    });
  });

  // TODO: Re-enable when TasksWidget uses fetch API instead of setTimeout mock data
  it.skip("should render task list", async (): Promise<void> => {
    const mockTasks = [
      { id: "1", title: "Complete documentation", status: "IN_PROGRESS", priority: "HIGH" },
      { id: "2", title: "Review PRs", status: "NOT_STARTED", priority: "MEDIUM" },
    ];

    vi.mocked(global.fetch).mockResolvedValueOnce({
      ok: true,
      json: () => Promise.resolve(mockTasks),
    } as unknown as Response);

    render(<TasksWidget id="tasks-1" />);

    await waitFor(() => {
      expect(screen.getByText("Complete documentation")).toBeInTheDocument();
      expect(screen.getByText("Review PRs")).toBeInTheDocument();
    });
  });

  // TODO: Re-enable when TasksWidget uses fetch API instead of setTimeout mock data
  it.skip("should handle empty task list", async (): Promise<void> => {
    vi.mocked(global.fetch).mockResolvedValueOnce({
      ok: true,
      json: () => Promise.resolve([]),
    } as unknown as Response);

    render(<TasksWidget id="tasks-1" />);

    await waitFor(() => {
      expect(screen.getByText(/no tasks/i)).toBeInTheDocument();
    });
  });

  // TODO: Re-enable when TasksWidget uses fetch API instead of setTimeout mock data
  it.skip("should handle API errors gracefully", async (): Promise<void> => {
    vi.mocked(global.fetch).mockRejectedValueOnce(new Error("API Error"));

    render(<TasksWidget id="tasks-1" />);

    await waitFor(() => {
      expect(screen.getByText(/error/i)).toBeInTheDocument();
    });
  });

  // TODO: Re-enable when TasksWidget uses fetch API instead of setTimeout mock data
  it.skip("should display priority indicators", async (): Promise<void> => {
    const mockTasks = [
      { id: "1", title: "High priority task", status: "IN_PROGRESS", priority: "HIGH" },
    ];

    vi.mocked(global.fetch).mockResolvedValueOnce({
      ok: true,
      json: () => Promise.resolve(mockTasks),
    } as unknown as Response);

    render(<TasksWidget id="tasks-1" />);

    await waitFor(() => {
      expect(screen.getByText("High priority task")).toBeInTheDocument();
      // Priority icon should be rendered (high priority = red)
    });
  });

  // TODO: Re-enable when TasksWidget uses fetch API instead of setTimeout mock data
  it.skip("should limit displayed tasks to 5", async (): Promise<void> => {
    const mockTasks = Array.from({ length: 10 }, (_, i) => ({
      id: String(i + 1),
      title: `Task ${String(i + 1)}`,
      status: "NOT_STARTED",
      priority: "MEDIUM",
    }));

    vi.mocked(global.fetch).mockResolvedValueOnce({
      ok: true,
      json: () => Promise.resolve(mockTasks),
    } as unknown as Response);

    render(<TasksWidget id="tasks-1" />);

    await waitFor(() => {
      const taskElements = screen.getAllByText(/Task \d+/);
      expect(taskElements.length).toBeLessThanOrEqual(5);
    });
  });
});
