/**
 * @vitest-environment happy-dom
 */
import { describe, it, expect, vi, beforeEach } from "vitest";
import { renderHook } from "@testing-library/react";
import { useShippingAddresses } from "./useShippingAddresses";

const mockUseQuery = vi.fn();
vi.mock("convex/react", () => ({
  useQuery: (...args: unknown[]) => mockUseQuery(...args),
}));

vi.mock("../../../../../convex/_generated/api", () => ({
  api: {
    checkout: { getShippingAddresses: "mock-getShippingAddresses-ref" },
  },
}));

describe("useShippingAddresses", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("returns loading state when query is undefined", () => {
    mockUseQuery.mockReturnValue(undefined);
    const { result } = renderHook(() => useShippingAddresses());
    expect(result.current.isLoading).toBe(true);
    expect(result.current.addresses).toEqual([]);
  });

  it("calls useQuery with the correct function reference", () => {
    mockUseQuery.mockReturnValue(undefined);
    renderHook(() => useShippingAddresses());
    expect(mockUseQuery).toHaveBeenCalledWith("mock-getShippingAddresses-ref");
  });

  it("maps Convex documents to CheckoutAddress with UK fields", () => {
    mockUseQuery.mockReturnValue([
      {
        _id: "addr_123",
        _creationTime: 1700000000000,
        userId: "user_1",
        type: "shipping",
        fullName: "Alice Smith",
        firstName: "Alice",
        lastName: "Smith",
        phone: "+447911123456",
        addressLine1: "10 Downing Street",
        additionalInformation: "Flat 4B",
        city: "London",
        postalCode: "SW1A 2AA",
        country: "GB",
        isDefault: true,
        isValidated: true,
      },
    ]);

    const { result } = renderHook(() => useShippingAddresses());
    expect(result.current.isLoading).toBe(false);
    expect(result.current.addresses).toHaveLength(1);

    const addr = result.current.addresses[0];
    expect(addr.id).toBe("addr_123");
    expect(addr.type).toBe("shipping");
    expect(addr.fullName).toBe("Alice Smith");
    expect(addr.firstName).toBe("Alice");
    expect(addr.lastName).toBe("Smith");
    expect(addr.phone).toBe("+447911123456");
    expect(addr.addressLine1).toBe("10 Downing Street");
    expect(addr.additionalInformation).toBe("Flat 4B");
    expect(addr.city).toBe("London");
    expect(addr.postalCode).toBe("SW1A 2AA");
    expect(addr.country).toBe("GB");
    expect(addr.isDefault).toBe(true);
    expect(addr.isValidated).toBe(true);
  });

  it("maps address without additionalInformation as undefined", () => {
    mockUseQuery.mockReturnValue([
      {
        _id: "addr_minimal",
        _creationTime: 1700000000000,
        userId: "user_1",
        type: "shipping",
        fullName: "Bob Jones",
        firstName: "Bob",
        lastName: "Jones",
        phone: "+447911999888",
        addressLine1: "221B Baker Street",
        city: "London",
        postalCode: "NW1 6XE",
        country: "GB",
        isDefault: false,
        isValidated: true,
      },
    ]);

    const { result } = renderHook(() => useShippingAddresses());
    expect(result.current.addresses[0].additionalInformation).toBeUndefined();
  });

  it("coerces isValidated: undefined to false for legacy addresses", () => {
    mockUseQuery.mockReturnValue([
      {
        _id: "addr_legacy",
        _creationTime: 1700000000000,
        userId: "user_1",
        type: "shipping",
        fullName: "Legacy User",
        firstName: "Legacy",
        lastName: "User",
        phone: "+447700900000",
        addressLine1: "1 Old Street",
        city: "Birmingham",
        postalCode: "B1 1AA",
        country: "GB",
        isDefault: false,
        isValidated: undefined,
      },
    ]);

    const { result } = renderHook(() => useShippingAddresses());
    expect(result.current.addresses[0].isValidated).toBe(false);
  });

  it("maps multiple addresses preserving order from query", () => {
    mockUseQuery.mockReturnValue([
      {
        _id: "addr_default",
        _creationTime: 1700000000000,
        userId: "user_1",
        type: "shipping",
        fullName: "Default Address",
        firstName: "Default",
        lastName: "Address",
        phone: "+447911000001",
        addressLine1: "1 Buckingham Palace Road",
        city: "London",
        postalCode: "SW1W 0QP",
        country: "GB",
        isDefault: true,
        isValidated: true,
      },
      {
        _id: "addr_second",
        _creationTime: 1699999000000,
        userId: "user_1",
        type: "shipping",
        fullName: "Second Address",
        firstName: "Second",
        lastName: "Address",
        phone: "+447911000002",
        addressLine1: "2 Abbey Road",
        city: "London",
        postalCode: "NW8 9AY",
        country: "GB",
        isDefault: false,
        isValidated: false,
      },
    ]);

    const { result } = renderHook(() => useShippingAddresses());
    expect(result.current.addresses).toHaveLength(2);
    expect(result.current.addresses[0].id).toBe("addr_default");
    expect(result.current.addresses[1].id).toBe("addr_second");
  });

  it("returns empty array (not loading) when query returns empty list", () => {
    mockUseQuery.mockReturnValue([]);
    const { result } = renderHook(() => useShippingAddresses());
    expect(result.current.isLoading).toBe(false);
    expect(result.current.addresses).toEqual([]);
  });
});
