import { afterEach, describe, expect, it, vi } from "vitest";
import { computeAssociationDirectoryGeoUpdate, computeAssociationDirectoryGeoUpdateForPrecision, getPublicMapCoordinates } from "./associationGeo";

describe("associationGeo", () => {
  afterEach(() => {
    vi.restoreAllMocks();
  });

  it("returns public coordinates for visible entries and keeps hidden precision visible by policy", () => {
    const visible = getPublicMapCoordinates({
      latitude: "5.123456",
      longitude: "-52.123456",
      geoPrecision: "commune_center",
    } as any);

    expect(visible).toEqual({
      latitude: 5.123456,
      longitude: -52.123456,
      precision: "commune_center",
    });

    const hidden = getPublicMapCoordinates({
      latitude: "5.123456",
      longitude: "-52.123456",
      geoPrecision: "hidden",
    } as any);

    expect(hidden).toEqual({
      latitude: 5.123456,
      longitude: -52.123456,
      precision: "exact_address",
    });
  });

  it("geocodes the address when exact precision is requested", async () => {
    const fetchMock = vi
      .spyOn(globalThis, "fetch")
      .mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          features: [
            {
              geometry: { coordinates: [-52.61, 5.08] },
              properties: { label: "Adresse test" },
            },
          ],
        }),
      } as Response);

    const result = await computeAssociationDirectoryGeoUpdateForPrecision({
      id: 1,
      nomAssociation: "Association Test",
      adresse: "1 rue Test",
      codePostal: "97310",
      ville: "Kourou",
    } as any, null, "exact_address");

    expect(fetchMock).toHaveBeenCalledTimes(1);
    expect(result.geoSource).toBe("adresse_gouv");
    expect(result.latitude).toBe("5.080000");
    expect(result.longitude).toBe("-52.610000");
  });

  it("falls back to commune center by default", async () => {
    vi.spyOn(globalThis, "fetch")
      .mockResolvedValueOnce({
        ok: true,
        json: async () => ([
          { nom: "Kourou", centre: { coordinates: [-52.7767, 4.9085] } },
        ]),
      } as Response);

    const result = await computeAssociationDirectoryGeoUpdate({
      id: 1,
      nomAssociation: "Association Test",
      adresse: "Adresse introuvable",
      codePostal: "97310",
      ville: "Kourou",
    } as any);

    expect(result.geoSource).toBe("commune_center");
    expect(result.latitude).toBe("4.908500");
    expect(result.longitude).toBe("-52.776700");
  });
});
