import type { Locator, Page } from "playwright";
import type { AxelSelectionBridge } from "@/workers/rpa/axel-selection-bridge";
import type { AddressLookupInput } from "@/modules/address/types";
import { getRpaPlaceFixMode } from "@/lib/rpa/env";
import {
  clickMothershipStyledSuggestion,
  reopenStyledSuggestionDropdown,
  waitForStyledSuggestionRows,
} from "@/workers/rpa/mothership-styled-suggestion-click";
import { commitViaGooglePlaceEvent } from "./google-event-commit";
import { commitViaReactStateInjection } from "./react-state-commit";
import { commitViaBrowserPlaceFetch } from "./browser-place-commit";
import { commitViaCdpDomClick } from "./cdp-pac-commit";
import { commitViaDirectPlaceChangedListener } from "./direct-listener-commit";
import { loadReconVerdict } from "./recon-helpers";
import {
  isPlaceDiagEnabled,
  logPlaceDiagnostic,
  setPlaceDiagMark,
  writePlaceDiagnosticArtifact,
} from "./place-diagnostic-probe";

const STYLED_CLICK_RETRIES = 3;

async function diagPhase(
  page: Page,
  phase: string,
  runId: string,
): Promise<void> {
  if (!isPlaceDiagEnabled()) {
    return;
  }
  const snapshot = await logPlaceDiagnostic(page, phase);
  if (snapshot.ok) {
    writePlaceDiagnosticArtifact(runId, phase, snapshot);
  }
}

async function tryStyledClickCommit(
  page: Page,
  bridge: AxelSelectionBridge,
  placeId: string,
  description: string,
  side: "pickup" | "delivery",
  input: Locator,
  query: AddressLookupInput,
): Promise<{ ok: boolean; method: string }> {
  for (let attempt = 0; attempt < STYLED_CLICK_RETRIES; attempt += 1) {
    if (attempt > 0) {
      await reopenStyledSuggestionDropdown(page, input, query, description);
      await waitForStyledSuggestionRows(page, [], query, 8_000);
    }

    const styled = await clickMothershipStyledSuggestion(
      page,
      description,
      query,
      {
        input,
        side,
        bridge,
        placeId,
        skipReopen: attempt > 0,
        maxStrategyAttempts: 3,
      },
    );

    if (!styled.clicked) {
      console.log(
        `[rpa] fix-place: styled-click attempt=${attempt + 1} miss reason=${styled.reason ?? "unknown"}`,
      );
      continue;
    }

    const committed = await bridge.waitForPlaceCommit(placeId, 8_000);
    const httpOk = bridge.hasSuccessfulPlaceNetworkRequest(placeId);
    if (committed && httpOk) {
      console.log(
        `[rpa] fix-place: mothership-styled-click 成功 method=${styled.method ?? "styled"}`,
      );
      return { ok: true, method: styled.method ?? "mothership-styled-click" };
    }

    console.log(
      `[rpa] fix-place: styled-click attempt=${attempt + 1} 无 place 200 committed=${committed} httpOk=${httpOk}`,
    );
  }

  return { ok: false, method: "mothership-styled-click-failed" };
}

export async function commitPlaceWithStrategy(
  page: Page,
  bridge: AxelSelectionBridge,
  placeId: string,
  description: string,
  side: "pickup" | "delivery",
  pickupInfo?: {
    placeId: string;
    description: string;
    location: Record<string, unknown>;
  },
  options?: {
    input?: Locator;
    query?: AddressLookupInput;
  },
): Promise<{ ok: boolean; method: string }> {
  const mode = getRpaPlaceFixMode();
  const verdict = loadReconVerdict();
  const diagRunId = `${side}-${placeId.slice(0, 12)}`;
  const googleAvailable =
    verdict.googleMapsLoaded &&
    verdict.triggerAvailable &&
    verdict.placeChangedTriggerOk;
  const fiberAvailable = verdict.reactFiberKey !== "not-found";

  if (options?.input && options?.query) {
    await setPlaceDiagMark(page, `${diagRunId}-before-styled`);
    const styled = await tryStyledClickCommit(
      page,
      bridge,
      placeId,
      description,
      side,
      options.input,
      options.query,
    );
    if (styled.ok) {
      await diagPhase(page, `${diagRunId}-after-styled`, diagRunId);
      return styled;
    }
    await diagPhase(page, `${diagRunId}-styled-miss`, diagRunId);
  }

  if (mode === "legacy") {
    return { ok: false, method: "legacy-skip" };
  }

  if (options?.input && options?.query) {
    await setPlaceDiagMark(page, `${diagRunId}-before-cdp`);
    const cdpResult = await commitViaCdpDomClick(
      page,
      bridge,
      placeId,
      description,
      {
        candidateIndex: bridge.getCandidateIndex(placeId),
        query: options.query,
      },
    );
    if (
      cdpResult.ok &&
      bridge.hasSuccessfulPlaceNetworkRequest(placeId)
    ) {
      await diagPhase(page, `${diagRunId}-after-cdp`, diagRunId);
      return cdpResult;
    }
    await diagPhase(page, `${diagRunId}-cdp-miss`, diagRunId);
  }

  await setPlaceDiagMark(page, `${diagRunId}-before-direct-listener`);
  const directListener = await commitViaDirectPlaceChangedListener(
    page,
    bridge,
    placeId,
    description,
  );
  if (
    directListener.ok &&
    bridge.hasSuccessfulPlaceNetworkRequest(placeId)
  ) {
    await diagPhase(page, `${diagRunId}-after-direct-listener`, diagRunId);
    return directListener;
  }
  await diagPhase(page, `${diagRunId}-direct-listener-miss`, diagRunId);

  await setPlaceDiagMark(page, `${diagRunId}-before-browser-fetch`);
  const browserFetch = await commitViaBrowserPlaceFetch(
    page,
    bridge,
    placeId,
    description,
    side,
  );
  if (
    browserFetch.ok &&
    bridge.hasSuccessfulPlaceNetworkRequest(placeId)
  ) {
    await diagPhase(page, `${diagRunId}-after-browser-fetch`, diagRunId);
    return browserFetch;
  }
  await diagPhase(page, `${diagRunId}-browser-fetch-miss`, diagRunId);

  if (mode === "event" && googleAvailable) {
    await setPlaceDiagMark(page, `${diagRunId}-before-google-event`);
    const result = await commitViaGooglePlaceEvent(
      page,
      bridge,
      placeId,
      description,
    );
    if (
      result.ok &&
      bridge.hasSuccessfulPlaceNetworkRequest(placeId)
    ) {
      await diagPhase(page, `${diagRunId}-after-google-event`, diagRunId);
      console.log("[rpa] fix-place: google-event 成功");
      return { ok: true, method: "google-event" };
    }
    await diagPhase(page, `${diagRunId}-google-event-miss`, diagRunId);
    console.log("[rpa] fix-place: google-event 失败，降级到 react-state");
  } else if (mode === "event" && !googleAvailable) {
    console.log(
      "[rpa] fix-place: verdict 无 Google Autocomplete，跳过 google-event",
    );
  }

  if (fiberAvailable) {
    const stateResult = await commitViaReactStateInjection(
      page,
      bridge,
      placeId,
      description,
      side,
      pickupInfo,
    );
    if (
      stateResult.ok &&
      bridge.hasSuccessfulPlaceNetworkRequest(placeId)
    ) {
      console.log("[rpa] fix-place: react-state 成功");
      return { ok: true, method: "react-state" };
    }
  } else {
    console.log("[rpa] fix-place: verdict 无 React Fiber，跳过 react-state");
  }

  return { ok: false, method: "all-failed" };
}
