import React from "react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";
import { jest } from "@jest/globals";

const mockPostApi = jest.fn();
const mockToastError = jest.fn();

jest.unstable_mockModule("react-toastify", () => ({
  __esModule: true,
  toast: {
    error: mockToastError,
  },
}));

jest.unstable_mockModule("../services/apiService.js", () => ({
  __esModule: true,
  default: () => ({
    postApi: mockPostApi,
  }),
}));

jest.unstable_mockModule("../constants/apiEndPoints.js", () => ({
  getScreenshots: "/api/screenshots",
}));

jest.unstable_mockModule("../components/CommonTable.js", () => ({
  __esModule: true,
  default: ({ data, columns }) => {
    const rowCount = Array.isArray(data) ? data.length : data?.Records?.length ?? 0;
    return (
      <div data-testid="common-table">
        <span data-testid="row-count">{rowCount}</span>
        <span data-testid="col-count">{columns?.length ?? 0}</span>
      </div>
    );
  },
}));

jest.unstable_mockModule("../components/SearchInput.js", () => ({
  __esModule: true,
  default: ({ onSearch, onClear }) => (
    <div>
      <input
        data-testid="search-input"
        onChange={(event) => onSearch(event.target.value)}
        placeholder="Search"
      />
      <button data-testid="clear-btn" onClick={() => onClear("")} type="button">
        Clear
      </button>
    </div>
  ),
}));

jest.unstable_mockModule("../components/Loader.js", () => ({
  __esModule: true,
  default: () => <div data-testid="loader" />,
}));

jest.unstable_mockModule("../components/SingleDatePicker.js", () => ({
  __esModule: true,
  default: ({ onChange, value }) => (
    <div data-testid="date-selector">
      <div>
        <input 
          data-testid="date-input" 
          value={value ? new Date(value).toISOString().split('T')[0] : new Date().toISOString().split('T')[0]}
          readOnly
          onClick={() => {
            const selectedDate = new Date(2024, 0, 15).toISOString();
            if (onChange) {
              onChange(selectedDate);
            }
          }}
        />
        <svg data-testid="calendar-icon" onClick={() => {
          const selectedDate = new Date(2024, 0, 15).toISOString();
          if (onChange) {
            onChange(selectedDate);
          }
        }}>
          <path d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.89-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.11-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z"/>
        </svg>
      </div>
      <div className="action-buttons-date-picker">
        <div>
          <button
            className="button"
            onClick={() => {
              const selectedDate = new Date(2024, 0, 15).toISOString();
              if (onChange) {
                onChange(selectedDate);
              }
            }}
          >
            Apply
          </button>
          <button
            className="btn2"
            onClick={() => {
              const today = new Date().toISOString();
              if (onChange) {
                onChange(today);
              }
            }}
          >
            Clear
          </button>
          <button className="btn2">Close</button>
        </div>
      </div>
    </div>
  ),
}));

const mockScreenshotData = [
  { EmpCode: "E001", NameApplication: "Chrome", Date: "2024-01-15", Picture: "img1.png" },
  { EmpCode: "E002", NameApplication: "VS Code", Date: "2024-01-15", Picture: "img2.png" },
];

const defaultProps = {
  employeeId: null,
  EmployeeName: "",
  title: "",
  summaryFilter: {
    Date: "2024-01-15",
    EmpCode: "E001",
    ResultsFor: "All",
  },
};

describe("Screenshots Component", () => {
  let Screenshots;

  beforeAll(async () => {
    ({ default: Screenshots } = await import("../pages/ActivityReports/Screenshots.js"));
  });

  beforeEach(() => {
    mockPostApi.mockReset();
    mockPostApi.mockResolvedValue(mockScreenshotData);
    mockToastError.mockReset();
  });

  it("renders table, date selector, and search input by default", async () => {
    render(<Screenshots {...defaultProps} />);

    expect(screen.getByTestId("common-table")).toBeInTheDocument();
    expect(screen.getByTestId("date-selector")).toBeInTheDocument();
    expect(screen.getByTestId("search-input")).toBeInTheDocument();
  });

  it("hides search input when employeeId is provided", async () => {
    render(<Screenshots {...defaultProps} employeeId="E001" />);

    expect(screen.queryByTestId("search-input")).not.toBeInTheDocument();
  });

  it("calls postApi on mount with initial filter values", async () => {
    render(<Screenshots {...defaultProps} />);

    await waitFor(() => {
      expect(mockPostApi).toHaveBeenCalledTimes(1);
    });

    const [, filterArg] = mockPostApi.mock.calls[0];
    expect(filterArg).toMatchObject({
      SearchText: "",
      PageSize: 50,
      PageNumber: 1,
      IgnorePaging: true,
    });
  });

  it("renders row and column counts from API data", async () => {
    render(<Screenshots {...defaultProps} />);

    await waitFor(() => {
      expect(screen.getByTestId("row-count")).toHaveTextContent("2");
    });

    await waitFor(() => {
      expect(screen.getByTestId("col-count")).toHaveTextContent("4");
    });
  });

  it("shows loader while awaiting API response", async () => {
    let resolveApi;
    mockPostApi.mockImplementationOnce(() => new Promise((resolve) => { resolveApi = resolve; }));

    render(<Screenshots {...defaultProps} />);

    await waitFor(() => {
      expect(screen.getByTestId("loader")).toBeInTheDocument();
    });

    resolveApi(mockScreenshotData);

    await waitFor(() => {
      expect(screen.queryByTestId("loader")).not.toBeInTheDocument();
    });
  });

  it("handles API failure and shows empty data", async () => {
    mockPostApi.mockRejectedValueOnce(new Error("Network error"));

    render(<Screenshots {...defaultProps} />);

    await waitFor(() => {
      expect(mockToastError).toHaveBeenCalled();
    });

    expect(screen.getByTestId("row-count")).toHaveTextContent("0");
  });

 it("triggers refetch when date filter changes", async () => {
  render(<Screenshots {...defaultProps} />);

  // initial call on mount
  await waitFor(() => {
    expect(mockPostApi).toHaveBeenCalledTimes(1);
  });

  fireEvent.click(screen.getByTestId("date-input"));

  await waitFor(() => {
    expect(mockPostApi).toHaveBeenCalledTimes(2);
  });

  const [, lastCallArg] = mockPostApi.mock.calls[1];

  expect(lastCallArg.Filter.Date).toMatch(/^\d{4}-\d{2}-\d{2}$/);
  expect(lastCallArg.PageNumber).toBe(1);
});

  it("lowercases search text and refetches", async () => {
    render(<Screenshots {...defaultProps} />);

    fireEvent.change(screen.getByTestId("search-input"), {
      target: { value: "Chrome" },
    });

    const [, lastCallArg] = mockPostApi.mock.calls[1];
    expect(lastCallArg.SearchText).toBe("chrome");
  });

  it("clears search text and employee id on clear", async () => {
    render(<Screenshots {...defaultProps} />);

    fireEvent.click(screen.getByTestId("clear-btn"));

    const [, lastCallArg] = mockPostApi.mock.calls[1];
    expect(lastCallArg.SearchText).toBe("");
    expect(lastCallArg.Filter.EmployeeId).toBe("");
  });

  it("excludes 'Select Results For' from ResultsFor filter", async () => {
    render(
      <Screenshots
        {...defaultProps}
        summaryFilter={{ Date: "2024-01-15", EmpCode: "E001", ResultsFor: "Select Results For" }}
      />
    );

    const [, callArg] = mockPostApi.mock.calls[0];
    expect(callArg.Filter.ResultsFor).toBe("");
  });

  it("uses userProfile columns when title is userProfile", async () => {
    render(<Screenshots {...defaultProps} title="userProfile" />);

    await waitFor(() => {
      expect(screen.getByTestId("col-count")).toHaveTextContent("3");
    });
  });

  it('handles search input', async () => {
    render(<Screenshots {...defaultProps} />);
    expect(screen.getByTestId('search-input')).toBeInTheDocument();
  });

  it('opens and applies date range filter', async () => {
    render(<Screenshots {...defaultProps} />);
    const dateSelector = screen.getByTestId('date-selector');
    expect(dateSelector).toBeInTheDocument();
    fireEvent.click(dateSelector);
  });

  it('closes date range picker', () => {
    render(<Screenshots {...defaultProps} />);
    const dateSelector = screen.getByTestId('date-selector');
    expect(dateSelector).toBeInTheDocument();
  });
});
