import type { Page } from "playwright";
import { isDualAddressPatchEnabled } from "@/lib/rpa/env";
import { INJECT_REACT_STATE } from "@/workers/rpa/fix-place/browser-eval-scripts";
import { DUAL_ADDRESS_PATCH_INIT } from "@/workers/rpa/inject/dual-address-patch-init";

export { DUAL_ADDRESS_PATCH_INIT };

export type DualAddressVaultEntry = {
  placeId: string;
  location: Record<string, unknown>;
  description: string;
};

type RegisterArg = {
  side: "pickup" | "delivery";
  payload: DualAddressVaultEntry;
};

export async function registerDualAddressInPage(
  page: Page,
  side: "pickup" | "delivery",
  payload: DualAddressVaultEntry,
): Promise<boolean> {
  return page.evaluate(
    ({ side: sideArg, payload: entry }: RegisterArg) => {
      const api = (
        window as Window & {
          __rpaDualAddressApi?: {
            register: (
              s: string,
              p: { placeId: string; location: Record<string, unknown>; description: string },
            ) => boolean;
          };
        }
      ).__rpaDualAddressApi;
      if (!api?.register) {
        return false;
      }
      return !!api.register(sideArg, {
        placeId: entry.placeId,
        location: entry.location,
        description: entry.description,
      });
    },
    { side, payload },
  );
}

export async function preservePickupInWidget(page: Page): Promise<boolean> {
  return page.evaluate(() => {
    const api = (
      window as Window & {
        __rpaDualAddressApi?: { preservePickup: () => boolean };
      }
    ).__rpaDualAddressApi;
    if (!api?.preservePickup) {
      return false;
    }
    return !!api.preservePickup();
  });
}

export async function releasePickupInputInWidget(page: Page): Promise<boolean> {
  return page.evaluate(() => {
    const api = (
      window as Window & {
        __rpaDualAddressApi?: { releasePickupInput: () => boolean };
      }
    ).__rpaDualAddressApi;
    if (!api?.releasePickupInput) {
      return false;
    }
    return !!api.releasePickupInput();
  });
}

export async function preserveDualAddressInWidget(page: Page): Promise<boolean> {
  return page.evaluate(() => {
    const api = (
      window as Window & {
        __rpaDualAddressApi?: { preserveBoth: () => boolean };
      }
    ).__rpaDualAddressApi;
    if (!api?.preserveBoth) {
      return false;
    }
    return !!api.preserveBoth();
  });
}

export async function readDualAddressPatchStats(
  page: Page,
): Promise<Record<string, unknown>> {
  return page.evaluate(() => {
    const api = (
      window as Window & {
        __rpaDualAddressApi?: { stats: () => Record<string, unknown> };
      }
    ).__rpaDualAddressApi;
    if (!api?.stats) {
      return { installed: false };
    }
    return { installed: true, ...api.stats() };
  });
}

/** pickup commit 后：vault + React setState + 释放派送输入框 */
export async function applyPickupDualAddressPatch(
  page: Page,
  payload: DualAddressVaultEntry,
): Promise<void> {
  if (!isDualAddressPatchEnabled()) {
    return;
  }
  const statsBefore = await readDualAddressPatchStats(page);
  const registered = await registerDualAddressInPage(page, "pickup", payload);
  const injected = await page.evaluate(INJECT_REACT_STATE, {
    sideArg: "pickup",
    pid: payload.placeId,
    loc: payload.location,
    desc: payload.description,
  });
  await releasePickupInputInWidget(page);
  await page.waitForTimeout(500);
  const preserved = await preservePickupInWidget(page);
  console.log("[rpa] dual-address-patch:pickup", {
    statsBefore,
    registered,
    injected,
    preserved,
  });
}

/** delivery 填写前/后巩固双地址 */
export async function applyDeliveryDualAddressPatch(
  page: Page,
  pickup: DualAddressVaultEntry,
  delivery: DualAddressVaultEntry,
): Promise<void> {
  if (!isDualAddressPatchEnabled()) {
    return;
  }
  await registerDualAddressInPage(page, "pickup", pickup);
  await preservePickupInWidget(page);
  const deliveryRegistered = await registerDualAddressInPage(
    page,
    "delivery",
    delivery,
  );
  const deliveryInjected = await page.evaluate(INJECT_REACT_STATE, {
    sideArg: "delivery",
    pid: delivery.placeId,
    loc: delivery.location,
    desc: delivery.description,
  });
  const both = await preserveDualAddressInWidget(page);
  console.log("[rpa] dual-address-patch:delivery", {
    deliveryRegistered,
    deliveryInjected,
    both,
  });
}
