import type { AxelPlaceNetworkEvent } from "@/workers/rpa/axel-selection-bridge";
import type {
  AddressCommitState,
  AddressSelectDiagnostics,
  AddressSelectStatus,
} from "@/workers/rpa/address-adapter/types";

export type PlaceNetworkDiagnostic = {
  placeId: string;
  status: number;
  url: string;
  at: number;
};

export type AddressNetworkDiagnostics = {
  expectedPlaceId: string;
  observedPlaceIds: string[];
  placeNetworkEvents: PlaceNetworkDiagnostic[];
  placeRequestObserved: boolean;
  placeRequestHttpOk: boolean;
  pickupLostAfterDelivery: boolean;
};

export function buildNetworkDiagnostics(
  bridge: {
    getObservedPlaceCommitIds: () => string[];
    getPlaceNetworkLog: () => readonly AxelPlaceNetworkEvent[];
    hasPlaceCommit: (placeId: string) => boolean;
    hasSuccessfulPlaceNetworkRequest: (placeId: string) => boolean;
  },
  expectedPlaceId: string,
  pickupPlaceId?: string,
): AddressNetworkDiagnostics {
  return {
    expectedPlaceId,
    observedPlaceIds: bridge.getObservedPlaceCommitIds(),
    placeNetworkEvents: bridge.getPlaceNetworkLog().map((event) => ({
      placeId: event.placeId,
      status: event.status,
      url: event.url,
      at: event.at,
    })),
    placeRequestObserved: bridge.hasPlaceCommit(expectedPlaceId),
    placeRequestHttpOk: bridge.hasSuccessfulPlaceNetworkRequest(expectedPlaceId),
    pickupLostAfterDelivery: false,
  };
}

export function createEmptyDiagnostics(
  address: string,
  commitState: AddressCommitState = "EMPTY",
): AddressSelectDiagnostics {
  return {
    address,
    placeId: "",
    method: "",
    events: [],
    placeRequestObserved: false,
    status: "selection_failed",
    commitState,
  };
}

export function formatDiagnosticsFailure(diag: AddressSelectDiagnostics): string {
  const base = `address=${diag.address.slice(0, 64)} placeId=${diag.placeId || "—"} method=${diag.method || "—"} commitState=${diag.commitState}`;
  switch (diag.status) {
    case "no_place_request":
      return `${base}；失败于 place API 前：widget 未发起 GET place 请求（selection event 未触发）`;
    case "place_http_error":
      return `${base}；失败于 place API：HTTP 非 200`;
    case "place_id_mismatch":
      return `${base}；失败于 place API：placeId 与预期不匹配`;
    case "timeout":
      return `${base}；失败于 place API：等待 commit 超时`;
    case "selection_failed":
      return `${base}；失败于 selection event：候选/绑定/点选未完成`;
    default:
      return `${base}；地址 commit 未完成`;
  }
}

export function logAddressSelectDiagnostics(
  side: "pickup" | "delivery",
  diag: AddressSelectDiagnostics,
): void {
  console.log(
    `[rpa] address-select:${side} ${JSON.stringify({
      address: diag.address,
      placeId: diag.placeId,
      method: diag.method,
      events: diag.events,
      placeRequestObserved: diag.placeRequestObserved,
      status: diag.status,
      commitState: diag.commitState,
    })}`,
  );
}

export function resolvePlaceFailureStatus(
  placeRequestObserved: boolean,
  placeIdMismatch: boolean,
  httpError: boolean,
  timedOut: boolean,
): AddressSelectStatus {
  if (!placeRequestObserved) {
    return "no_place_request";
  }
  if (placeIdMismatch) {
    return "place_id_mismatch";
  }
  if (httpError) {
    return "place_http_error";
  }
  if (timedOut) {
    return "timeout";
  }
  return "selection_failed";
}
