import { describe, expect, it, vi } from "vitest";
import type { Locator, Page } from "playwright";
import { visibleStreetInput } from "@/workers/rpa/address-side";

function mockTextbox(isEditable: boolean, visible = true): Locator {
  const loc = {
    isVisible: vi.fn().mockResolvedValue(visible),
    isEditable: vi.fn().mockResolvedValue(isEditable),
    isDisabled: vi.fn().mockResolvedValue(false),
    getAttribute: vi.fn().mockResolvedValue(null),
    inputValue: vi.fn().mockResolvedValue(""),
  } as unknown as Locator;
  return loc;
}

function mockPageWithTextboxes(boxes: Locator[]): Page {
  const widget = {
    getByRole: vi.fn().mockReturnValue({
      count: vi.fn().mockResolvedValue(boxes.length),
      nth: (i: number) => boxes[i],
    }),
  };
  return {
    locator: vi.fn().mockReturnValue({
      first: () => widget,
    }),
  } as unknown as Page;
}

describe("visibleStreetInput", () => {
  it("派送：仅 1 个 textbox 时返回 null，强制先点送货至", async () => {
    const page = mockPageWithTextboxes([mockTextbox(false)]);
    const result = await visibleStreetInput(page, "delivery");
    expect(result).toBeNull();
  });

  it("派送：分区已打开且仅 1 个含提货文案的 textbox 时返回 null", async () => {
    const pickupBox = mockTextbox(true);
    (pickupBox as { inputValue: ReturnType<typeof vi.fn> }).inputValue = vi
      .fn()
      .mockResolvedValue("1234 Warehouse Street, Los Angeles, CA, USA");
    const page = mockPageWithTextboxes([pickupBox]);
    const result = await visibleStreetInput(page, "delivery", {
      deliverySectionOpened: true,
    });
    expect(result).toBeNull();
  });

  it("派送：分区已打开时取最后一个可编辑框", async () => {
    const page = mockPageWithTextboxes([
      mockTextbox(false),
      mockTextbox(true),
    ]);
    const result = await visibleStreetInput(page, "delivery", {
      deliverySectionOpened: true,
    });
    expect(result).toBeTruthy();
  });

  it("提货：单 textbox 可编辑时直接返回", async () => {
    const page = mockPageWithTextboxes([mockTextbox(true)]);
    const result = await visibleStreetInput(page, "pickup");
    expect(result).toBeTruthy();
  });
});
