import type {
  DeviceModelDefinition,
  ObservationSourceAvailability,
  ObservationSourceDelivery,
  ObservationSourceDescriptor,
  ObservationSourceProvider,
} from "@mission-core/plugin-sdk";
import { confirmedRuntimeSourceMode, effectiveAcquisition } from "./lifecycle";
import { xgridsK1Manifest } from "./manifest";
import type {
  XgridsCameraPreviewDelivery,
  XgridsK1State,
  XgridsSensorCatalogStream,
} from "./api";

function providerFor(
  state: XgridsK1State,
  activeModel: DeviceModelDefinition,
): ObservationSourceProvider {
  return {
    pluginId: xgridsK1Manifest.metadata.id,
    pluginVersion: xgridsK1Manifest.metadata.version,
    modelId: state.device_ref?.model_id || activeModel.id,
    compatibilityProfileId:
      state.device_session?.compatibility_profile_id ?? state.compatibility?.profile_id ?? null,
  };
}

function bindingFor(state: XgridsK1State) {
  const acquisition = effectiveAcquisition(state);
  return {
    deviceId: state.device_ref?.device_id ?? null,
    deviceSessionId: state.device_session?.device_session_id ?? null,
    acquisitionId: acquisition?.acquisition_id ?? null,
  };
}

function catalogDeclares(state: XgridsK1State, streamId: string): boolean {
  return Boolean(state.sensor_catalog?.streams?.some((stream) => stream.stream_id === streamId));
}

function spatialAvailability(state: XgridsK1State): ObservationSourceAvailability {
  const mode = confirmedRuntimeSourceMode(state);
  if (mode !== "idle" && state.rerun_grpc_url?.trim()) return "streaming";
  if (state.rerun_grpc_url?.trim()) return "available";
  if (state.device_session?.connectivity === "degraded") return "degraded";
  if (state.device_session?.connectivity === "connected") return "available";
  return catalogDeclares(state, "spatial.point-cloud.live") ? "declared" : "unavailable";
}

function catalogAvailability(value: string | null | undefined): ObservationSourceAvailability {
  switch (value?.trim().toLowerCase()) {
    case "observed":
    case "available":
      return "available";
    case "connecting":
      return "connecting";
    case "streaming":
      return "streaming";
    case "degraded":
      return "degraded";
    case "unavailable":
      return "unavailable";
    case "error":
      return "error";
    case "declared":
      return "declared";
    default:
      return "unverified";
  }
}

function cameraCatalogEntry(stream: XgridsSensorCatalogStream): boolean {
  const sourceId = stream.source_id?.trim();
  const semanticChannelId = stream.semantic_channel_id?.trim();
  if (!sourceId || !semanticChannelId) return false;
  const modality = stream.modality?.trim().toLowerCase();
  const sensorKind = stream.sensor_kind?.trim().toLowerCase();
  return (
    modality === "encoded-video" ||
    modality === "video" ||
    sensorKind === "camera" ||
    semanticChannelId.startsWith("camera.")
  );
}

function safeEndpointLabel(value: string | null | undefined): string | null {
  const label = value?.trim();
  if (!label || label.length > 128) return null;
  if (label.includes("://") || /(?:^|\D)(?:\d{1,3}\.){3}\d{1,3}(?:\D|$)/.test(label)) {
    return null;
  }
  return label;
}

const SENSITIVE_QUERY_KEYS = new Set([
  "accesskey", "accesstoken", "apikey", "auth", "authorization", "clientsecret",
  "credential", "credentials", "password", "passwd", "passphrase", "privatekey",
  "psk", "pwd", "refreshtoken", "secret", "sessionkey", "token", "user",
  "username", "wifipassword",
]);

function decodedForInspection(value: string): string | null {
  let decoded = value;
  try {
    for (let depth = 0; depth < 4; depth += 1) {
      const next = decodeURIComponent(decoded);
      if (next === decoded) break;
      decoded = next;
    }
  } catch {
    return null;
  }
  return decoded;
}

function sensitiveQueryKey(value: string): boolean {
  const canonical = value.toLowerCase().replace(/[^a-z0-9]/g, "");
  return SENSITIVE_QUERY_KEYS.has(canonical) ||
    /(?:token|secret|password|passwd|passphrase|credential|credentials)$/.test(canonical);
}

function safeBrowserDeliveryUrl(value: string): boolean {
  if (value.length > 4_096 || !value.startsWith("/") || value.startsWith("//")) return false;
  const inspected = decodedForInspection(value);
  if (!inspected) return false;
  if (
    /[\\\r\n\u0000-\u001f\u007f]/.test(inspected) ||
    /\brtsps?\s*:/i.test(inspected) ||
    /(?:^|\D)(?:\d{1,3}\.){3}\d{1,3}(?:\D|$)/.test(inspected) ||
    /\[[0-9a-f:]+\]/i.test(inspected) ||
    /(?:^|[/?#&=])[^/?#&=\s:@]+:[^/?#&\s@]+@/.test(inspected) ||
    /\b(?:basic|bearer)\s+[a-z0-9._~+/=-]+/i.test(inspected)
  ) return false;

  const base = new URL("https://mission-core.invalid/");
  let parsed: URL;
  let inspectedParsed: URL;
  try {
    parsed = new URL(value, base);
    inspectedParsed = new URL(inspected, base);
  } catch {
    return false;
  }
  if (
    parsed.origin !== base.origin || inspectedParsed.origin !== base.origin ||
    parsed.username || parsed.password || parsed.hash ||
    inspectedParsed.username || inspectedParsed.password || inspectedParsed.hash
  ) return false;
  for (const [key] of inspectedParsed.searchParams) {
    if (sensitiveQueryKey(key)) return false;
  }
  return true;
}

function browserDelivery(
  value: XgridsCameraPreviewDelivery | null | undefined,
): ObservationSourceDelivery | null {
  const id = value?.id?.trim();
  const url = value?.url?.trim();
  const mediaType = value?.media_type?.trim();
  if (!id || value?.kind !== "mse-fmp4-websocket" || !url || !mediaType) return null;
  // Browser delivery is host-owned and same-origin. A device RTSP/IP endpoint
  // must never cross the plugin boundary into the host descriptor catalog.
  if (!safeBrowserDeliveryUrl(url)) return null;
  if (!/^video\/mp4(?:\s*;|$)/i.test(mediaType)) return null;
  return { id, kind: value.kind, url, mediaType };
}

function cameraAvailability(
  state: XgridsK1State,
  stream: XgridsSensorCatalogStream,
  selected: boolean,
  delivery: ObservationSourceDelivery | null,
  attested: boolean,
): ObservationSourceAvailability {
  if (!attested) return "unverified";
  if (state.device_session?.connectivity === "degraded") return "degraded";
  const base = catalogAvailability(stream.availability);
  if (!selected) return base === "streaming" || base === "connecting" ? "available" : base;

  const phase = state.camera_preview?.phase?.trim().toLowerCase();
  if (phase === "error" || base === "error") return "error";
  if (delivery && (phase === "streaming" || phase === "active" || phase === "ready")) {
    return "streaming";
  }
  if (phase === "degraded") return "degraded";
  return "connecting";
}

export function xgridsK1ObservationSources(
  state: XgridsK1State,
  activeModel: DeviceModelDefinition,
): ObservationSourceDescriptor[] {
  const provider = providerFor(state, activeModel);
  const binding = bindingFor(state);
  const clockId = binding.acquisitionId ?? binding.deviceSessionId ?? binding.deviceId ?? null;
  const descriptorId = (sourceId: string) =>
    `${provider.pluginId}:${provider.modelId}:${sourceId}`;
  const pointCloud: ObservationSourceDescriptor = {
      id: descriptorId("sensor.lidar.primary"),
      sourceId: "sensor.lidar.primary",
      semanticChannelId: "spatial.point-cloud.live",
      label: "K1 · облако точек",
      description: "Облако точек, поза и траектория в общей 3D-сцене",
      modality: "point-cloud",
      role: "primary",
      availability: spatialAvailability(state),
      transport: "rerun-grpc",
      endpointLabel: state.rerun_grpc_url?.trim() ? "Rerun gRPC" : "MQTT → Rerun",
      previewUrl: state.rerun_grpc_url?.trim() || null,
      delivery: null,
      activation: null,
      provider,
      binding,
      capabilities: {
        overlay: false,
        fullscreen: true,
        resizable: false,
        defaultVisible: true,
        timelineMode: "live-only",
        // Rerun can hold replay data, but the Mission Core host timeline is not
        // wired to its time controller yet.
        seekable: false,
        sessionRecording: false,
        clockId,
        spatialRegistration: "native",
      },
    };

  const cameraRows = (state.sensor_catalog?.streams ?? []).filter(cameraCatalogEntry);
  const sourceIdCounts = new Map<string, number>();
  for (const stream of cameraRows) {
    const sourceId = stream.source_id?.trim();
    if (sourceId) sourceIdCounts.set(sourceId, (sourceIdCounts.get(sourceId) ?? 0) + 1);
  }
  const attested = Boolean(provider.compatibilityProfileId && binding.deviceSessionId);
  const sessionScope = binding.deviceSessionId ?? binding.deviceId ?? "unbound";
  const activeSourceId = state.camera_preview?.active_source_id?.trim() ?? null;

  const cameras = cameraRows.flatMap<ObservationSourceDescriptor>((stream) => {
    const sourceId = stream.source_id?.trim();
    const semanticChannelId = stream.semantic_channel_id?.trim();
    if (!sourceId || !semanticChannelId || sourceIdCounts.get(sourceId) !== 1) return [];

    const rawActivation = stream.activation;
    const groupId = rawActivation?.group_id?.trim();
    const maxActive = rawActivation?.max_active;
    const activationValid = Boolean(
      groupId && Number.isInteger(maxActive) && (maxActive ?? 0) > 0,
    );
    const selected = Boolean(
      attested && activationValid && rawActivation?.selected === true && activeSourceId === sourceId,
    );
    const activation = activationValid
      ? {
          groupId: `${provider.pluginId}:${sessionScope}:${groupId}`,
          maxActive: maxActive as number,
          selected,
          controllable: Boolean(attested && rawActivation?.controllable),
        }
      : null;
    const candidateDelivery = stream.delivery ?? state.camera_preview?.delivery;
    const delivery = selected ? browserDelivery(candidateDelivery) : null;
    const label = stream.label?.trim() || sourceId;

    return [{
      id: descriptorId(sourceId),
      sourceId,
      semanticChannelId,
      label,
      description: "Видеоканал, опубликованный активным device-плагином",
      modality: "video",
      role: "auxiliary",
      availability: cameraAvailability(state, stream, selected, delivery, attested),
      transport: delivery ? "websocket" : "other",
      endpointLabel: safeEndpointLabel(stream.endpoint_label) ?? "Локальный video adapter",
      previewUrl: null,
      delivery,
      activation,
      provider,
      binding,
      capabilities: {
        overlay: true,
        fullscreen: true,
        resizable: true,
        defaultVisible: selected && Boolean(delivery),
        timelineMode: "live-only",
        seekable: false,
        sessionRecording: false,
        clockId,
        spatialRegistration: "unresolved",
      },
    }];
  });

  return [pointCloud, ...cameras];
}
