import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import MapPicker from "@/apps/new-ui/components/CustomeComponents/MapPicker";
import { notifyOnce } from "@/lib/toastManager-2";

jest.mock("@/lib/toastManager-2", () => ({
  notifyOnce: jest.fn(),
}));

// mock map component
jest.mock("@neshan-maps-platform/react-openlayers", () => {
  return ({ onInit }: any) => {
    const fakeMap = {
      addLayer: jest.fn(),
      on: jest.fn(),
      getView: () => ({
        animate: jest.fn(),
      }),
    };

    if (onInit) {
      setTimeout(() => onInit(fakeMap), 0);
    }

    return <div data-testid="neshan-map" />;
  };
});
jest.mock("@neshan-maps-platform/ol", () => ({}));

// Mock OpenLayers / Neshan OL constructors correctly
jest.mock("@neshan-maps-platform/ol/style/Icon", () => {
  return jest.fn().mockImplementation(() => ({
    // هرچیزی لازم نیست، فقط باید constructor باشد
  }));
});

jest.mock("@neshan-maps-platform/ol/style/Style", () => {
  return jest.fn().mockImplementation(() => ({}));
});

jest.mock("@neshan-maps-platform/ol/Feature", () => {
  return jest.fn().mockImplementation(() => ({
    setStyle: jest.fn(),
    getGeometry: () => ({
      setCoordinates: jest.fn(),
    }),
  }));
});

jest.mock("@neshan-maps-platform/ol/geom/Point", () => {
  return jest.fn().mockImplementation(() => ({}));
});

jest.mock("@neshan-maps-platform/ol/source/Vector", () => {
  return jest.fn().mockImplementation(() => ({
    // فقط وجود داشته باشد کافیست
  }));
});

jest.mock("@neshan-maps-platform/ol/layer/Vector", () => {
  return jest.fn().mockImplementation(() => ({
    // فقط وجود داشته باشد کافیست
  }));
});

jest.mock("@neshan-maps-platform/ol/proj", () => ({
  fromLonLat: jest.fn(() => [100, 200]),
  toLonLat: jest.fn(() => [20, 10]),
}));

describe("MapPicker", () => {
  const onChange = jest.fn();

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

  it("renders map correctly", () => {
    render(
      <MapPicker latitude={35.7} longitude={51.4} onChange={onChange} />
    );

    expect(screen.getByTestId("neshan-map")).toBeInTheDocument();
  });

  it("calls geolocation when location button clicked", async () => {
    const mockGeo = {
      getCurrentPosition: jest.fn((success) =>
        success({
          coords: { latitude: 10, longitude: 20 },
        })
      ),
    };

    Object.defineProperty(global.navigator, "geolocation", {
      value: mockGeo,
      writable: true,
    });

    render(
      <MapPicker latitude={35.7} longitude={51.4} onChange={onChange} />
    );

    const button = screen.getByRole("button");

    fireEvent.click(button);

    await waitFor(() => {
      expect(onChange).toHaveBeenCalledWith(10, 20);
    });
  });

  it("shows error toast when geolocation permission denied", async () => {
    const mockGeo = {
  getCurrentPosition: jest.fn((_success, error) => {
    error({ code: 1 }); // PERMISSION DENIED
  }),
};


    Object.defineProperty(global.navigator, "geolocation", {
      value: mockGeo,
      writable: true,
    });

    Object.defineProperty(global.navigator, "permissions", {
      value: {
        query: jest.fn().mockResolvedValue({
          state: "granted",
        }),
      },
      writable: true,
    });

    render(
      <MapPicker latitude={35.7} longitude={51.4} onChange={onChange} />
    );

    fireEvent.click(screen.getByRole("button"));

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

  it("shows loading state when locating", () => {
    const mockGeo = {
      getCurrentPosition: jest.fn(),
    };

    Object.defineProperty(global.navigator, "geolocation", {
      value: mockGeo,
      writable: true,
    });

    render(
      <MapPicker latitude={35.7} longitude={51.4} onChange={onChange} />
    );

    const button = screen.getByRole("button");

    fireEvent.click(button);

    expect(button).toHaveTextContent("...");
  });
});
