// =============================================================================
// WOOO AIOps - AwoooP M5 Run 監控頁面
// =============================================================================
// 每 30 秒自動刷新，RUNNING 狀態顯示 pulse 動畫

"use client";

import { useState, useEffect, useCallback, useMemo, useRef } from "react";
import { useTranslations } from "next-intl";
import { Link } from "@/i18n/routing";
import {
  AwoooPStatusChainPanel,
  type AwoooPStatusChain,
} from "@/components/awooop/status-chain";
import { useIncidentStatusChains } from "@/hooks/useIncidentStatusChains";
import {
  Activity,
  Waypoints,
  Lock,
  GitBranch,
  FileText,
  ArrowRight,
  BellOff,
  RefreshCw,
  AlertCircle,
  Filter,
  ChevronDown,
  ChevronLeft,
  ChevronRight,
  Cpu,
  ListChecks,
  SearchCheck,
  Send,
  ShieldCheck,
  TriangleAlert,
} from "lucide-react";
import { cn } from "@/lib/utils";

// =============================================================================
// Types
// =============================================================================

type RunState =
  | "pending"
  | "running"
  | "waiting_tool"
  | "waiting_approval"
  | "completed"
  | "failed"
  | "cancelled"
  | "timeout";

type RunLane = "intake" | "diagnosis" | "approval" | "execution" | "done" | "manual";
type CallbackReplyStatus =
  | "no_callback"
  | "sent"
  | "fallback_sent"
  | "rescue_sent"
  | "failed"
  | "observed";
type CallbackEvidenceCaptureState =
  | "captured"
  | "partial"
  | "not_captured"
  | "observed";
type RemediationStatus =
  | "no_evidence"
  | "mcp_observed"
  | "read_only_dry_run"
  | "write_observed"
  | "blocked"
  | "observed";
type RecurrenceRepairStatus =
  | "no_incident_link"
  | "auto_repair_verified"
  | "auto_repair_succeeded_unverified"
  | "auto_repair_failed"
  | "auto_repair_recorded"
  | "manual_gate"
  | "investigating"
  | "run_completed_no_repair"
  | "source_correlation_review"
  | "no_repair_record";
type AutomationFlowStatus = "passed" | "warning" | "blocked" | "no_data" | string;

interface RemediationSummary {
  schema_version?: string;
  source?: string;
  incident_ids?: string[];
  total?: number;
  evidence_total?: number;
  status?: RemediationStatus | string;
  has_dry_run?: boolean;
  has_mcp_investigation?: boolean;
  is_read_only?: boolean;
  human_gate_open?: boolean;
  latest_at?: string | null;
  latest_preview?: string | null;
  latest_mode?: string | null;
  latest_route?: string | null;
  latest_agent_id?: string | null;
  latest_tool_name?: string | null;
  latest_required_scope?: string | null;
  writes_incident_state?: boolean | null;
  writes_auto_repair_result?: boolean | null;
  mcp_observation_total?: number;
  mcp_observation_success?: number;
  mcp_observation_failed?: number;
  latest_mcp_server?: string | null;
}

interface CallbackReplySummary {
  schema_version?: string;
  status?: CallbackReplyStatus | string;
  total?: number;
  sent?: number;
  fallback_sent?: number;
  rescue_sent?: number;
  failed?: number;
  needs_human?: boolean;
  latest_status?: string | null;
  latest_action?: string | null;
  latest_incident_id?: string | null;
  latest_at?: string | null;
  latest_provider_message_id?: string | null;
  capture_status?: CallbackEvidenceCaptureState | "no_callback" | string | null;
  capture_captured?: number;
  capture_partial?: number;
  capture_not_captured?: number;
  latest_capture_status?: CallbackEvidenceCaptureState | string | null;
  latest_capture_missing?: string[];
  latest_capture_next_action?: string | null;
}

interface CallbackEvidenceCaptureStatus {
  schema_version?: string;
  status?: CallbackEvidenceCaptureState | string | null;
  reason?: string | null;
  action?: string | null;
  captured?: string[];
  missing?: string[];
  snapshot_rollout?: string | null;
  next_action?: string | null;
  event_at?: string | null;
}

interface CallbackReplyAuditSummary {
  schema_version?: string;
  project_id?: string;
  outbound_total?: number;
  outbound_source_envelope_total?: number;
  outbound_source_refs_total?: number;
  outbound_trace_ref_total?: number;
  outbound_incident_ref_total?: number;
  outbound_reply_markup_total?: number;
  outbound_reply_markup_missing_incident_ref_total?: number;
  outbound_reply_markup_missing_incident_ref_recent_1h_total?: number;
  outbound_reply_markup_missing_incident_ref_recent_24h_total?: number;
  outbound_reply_markup_missing_incident_ref_latest_sent_at?: string | null;
  outbound_reply_markup_missing_trace_ref_total?: number;
  outbound_reply_markup_missing_trace_ref_recent_1h_total?: number;
  outbound_reply_markup_missing_trace_ref_recent_24h_total?: number;
  outbound_reply_markup_missing_trace_ref_latest_sent_at?: string | null;
  outbound_reply_markup_trace_ref_gap_status?: string | null;
  outbound_reply_markup_trace_ref_gap_next_action?: string | null;
  outbound_reply_markup_trace_ref_after_gap_total?: number;
  outbound_reply_markup_trace_ref_after_gap_first_sent_at?: string | null;
  outbound_reply_markup_trace_ref_after_gap_latest_sent_at?: string | null;
  outbound_reply_markup_trace_ref_gap_recovery_status?: string | null;
  outbound_reply_markup_missing_incident_ref_top_prefixes?: Array<{
    prefix?: string | null;
    total?: number | null;
    recent_24h_total?: number | null;
    first_sent_at?: string | null;
    last_sent_at?: string | null;
  }>;
  outbound_reply_markup_missing_trace_ref_top_prefixes?: Array<{
    prefix?: string | null;
    total?: number | null;
    recent_24h_total?: number | null;
    first_sent_at?: string | null;
    last_sent_at?: string | null;
  }>;
  outbound_failed_total?: number;
  callback_total?: number;
  callback_sent_total?: number;
  callback_fallback_total?: number;
  callback_rescue_total?: number;
  callback_failed_total?: number;
  callback_detail_total?: number;
  callback_history_total?: number;
  callback_snapshot_captured_total?: number;
  callback_snapshot_partial_total?: number;
  callback_snapshot_missing_total?: number;
  callback_incident_total?: number;
  inbound_callback_total?: number;
  inbound_callback_recent_24h_total?: number;
  inbound_callback_latest_at?: string | null;
  inbound_callback_mirror_status?: string | null;
  inbound_callback_next_action?: string | null;
  snapshot_status?: CallbackEvidenceCaptureState | "no_callback" | string | null;
  next_action?: string | null;
  latest_outbound_at?: string | null;
  latest_callback_at?: string | null;
}

interface OperatorSummaryCacheInfo {
  schema_version?: string;
  status?: "hit" | "miss" | string;
  source?: string;
  ttl_seconds?: number;
  age_seconds?: number;
  stored_at?: string;
  expires_at?: string;
}

interface AutomationFlowGateExample {
  incident_id?: string | null;
  alertname?: string | null;
  verdict?: string | null;
  truth_stage?: string | null;
  source_statuses?: Record<string, string>;
  blockers?: string[];
}

interface AutomationFlowGate {
  gate: string;
  status: AutomationFlowStatus;
  passed_total: number;
  warning_total: number;
  missing_total: number;
  failed_total: number;
  evaluated_total: number;
  passed_percent: number;
  quality_gates?: string[];
  next_action?: string;
  examples?: AutomationFlowGateExample[];
}

interface AutomationFlowGateSummary {
  schema_version?: "automation_flow_gate_summary_v1" | string;
  evaluated_total: number;
  overall_status: AutomationFlowStatus;
  blocked_gates: string[];
  warning_gates: string[];
  gates: AutomationFlowGate[];
}

interface AutomationQualitySummary {
  schema_version?: "automation_quality_summary_v1" | string;
  incident_total: number;
  evaluated_total: number;
  verified_auto_repair_total: number;
  average_score: number;
  production_claim?: {
    can_claim_full_auto_repair?: boolean;
    reason?: string | null;
  } | null;
  automation_flow_gates?: AutomationFlowGateSummary | null;
  cache?: OperatorSummaryCacheInfo | null;
}

interface Run {
  run_id: string;
  project_id: string;
  agent_id: string;
  state: RunState;
  is_shadow: boolean;
  cost_usd: number | string;
  step_count: number;
  created_at: string;
  remediation_summary?: RemediationSummary | null;
  callback_reply_summary?: CallbackReplySummary | null;
}

interface Tenant {
  project_id: string;
  display_name: string;
}

interface RunsResponse {
  runs?: Run[];
  items?: Run[];
  total: number;
  page: number;
  per_page: number;
}

interface PlatformEvent {
  event_id: string;
  project_id: string;
  channel_type: string;
  provider_event_id: string;
  channel_chat_id?: string | null;
  content_preview?: string | null;
  is_duplicate: boolean;
  received_at: string;
}

interface RecentEventsResponse {
  events?: PlatformEvent[];
  total: number;
  limit: number;
}

interface DossierCoverageSummary {
  source_count: number;
  source_envelope_total: number;
  missing_source_envelope_total: number;
  with_source_refs_total: number;
  missing_source_refs_total: number;
  duplicate_total: number;
  redacted_total: number;
  source_ref_total: number;
  sentry_ref_total: number;
  signoz_ref_total: number;
  alert_ref_total: number;
  latest_received_at?: string | null;
}

interface DossierCoverageProvider {
  provider: string;
  total: number;
  duplicate_total: number;
  redacted_total: number;
  source_ref_total: number;
  missing_source_refs_total: number;
  sentry_ref_total: number;
  signoz_ref_total: number;
  alert_ref_total: number;
  latest_received_at?: string | null;
}

interface DossierCoverageResponse {
  project_id: string;
  limit: number;
  summary: DossierCoverageSummary;
  providers: DossierCoverageProvider[];
}

interface EventRecurrenceSummary {
  source_event_total: number;
  recurrence_group_total: number;
  recurrent_group_total: number;
  duplicate_event_total: number;
  linked_run_total: number;
  unlinked_event_total: number;
  auto_repair_linked_total?: number;
  verified_repair_group_total?: number;
  open_work_item_group_total?: number;
  manual_gate_group_total?: number;
  automation_gap_group_total?: number;
  failed_repair_group_total?: number;
  source_correlation_review_group_total?: number;
  latest_received_at?: string | null;
}

interface EventRecurrenceRepairSummary {
  schema_version?: string;
  status?: RecurrenceRepairStatus | string;
  incident_id?: string | null;
  latest_auto_repair_id?: string | null;
  latest_playbook_id?: string | null;
  latest_playbook_name?: string | null;
  latest_success?: boolean | null;
  latest_error_message_preview?: string | null;
  latest_triggered_by?: string | null;
  latest_risk_level?: string | null;
  latest_execution_time_ms?: number | null;
  latest_auto_repair_at?: string | null;
  latest_verification_result?: string | null;
  latest_verification_at?: string | null;
  auto_repair_total?: number;
  success_total?: number;
  failed_total?: number;
}

interface EventRecurrenceWorkItem {
  schema_version?: string;
  work_item_id?: string | null;
  incident_id?: string | null;
  auto_repair_id?: string | null;
  status?: "open" | "closed" | "none" | string;
  kind?: string | null;
  next_step?: string | null;
  reason?: string | null;
  needs_human?: boolean;
}

interface EventRecurrenceItem {
  recurrence_key: string;
  provider?: string | null;
  alertname?: string | null;
  severity?: string | null;
  namespace?: string | null;
  target_resource?: string | null;
  fingerprint?: string | null;
  latest_stage?: string | null;
  latest_event_id?: string | null;
  latest_provider_event_id?: string | null;
  latest_content_preview?: string | null;
  latest_run_id?: string | null;
  latest_run_state?: RunState | string | null;
  latest_agent_id?: string | null;
  latest_incident_id?: string | null;
  incident_ids?: string[];
  repair_summary?: EventRecurrenceRepairSummary | null;
  work_item?: EventRecurrenceWorkItem | null;
  occurrence_total: number;
  duplicate_total: number;
  linked_run_total: number;
  source_ref_total: number;
  missing_source_refs_total: number;
  sentry_ref_total: number;
  signoz_ref_total: number;
  alert_ref_total: number;
  stage_counts: Record<string, number>;
  run_state_counts: Record<string, number>;
  first_received_at?: string | null;
  latest_received_at?: string | null;
}

interface EventRecurrenceResponse {
  project_id: string;
  limit: number;
  summary: EventRecurrenceSummary;
  items: EventRecurrenceItem[];
}

interface KmStaleCompletionSummaryItem {
  entry_id?: string | null;
  title?: string | null;
  dispatch_id?: string | null;
  governance_event_id?: string | null;
  readiness?: string | null;
  workflow_stage?: string | null;
  next_action?: string | null;
  priority_tier?: string | null;
  recommended_completion_outcome?: string | null;
  can_preview?: boolean | null;
}

interface KmStaleCallbackOwnerReviewWorkItem {
  schema_version?: string;
  work_item_id?: string | null;
  kind?: string | null;
  status?: string | null;
  project_id?: string | null;
  incident_id?: string | null;
  reason?: string | null;
  title?: string | null;
  next_step?: string | null;
  target_surface?: string | null;
  target_href?: string | null;
  work_item_href?: string | null;
  triage?: KmStaleCallbackOwnerReviewTriage | null;
  writes_on_read?: boolean | null;
  manual_review_required?: boolean | null;
  batch_writes_allowed?: boolean | null;
}

interface KmStaleCallbackOwnerReviewTriage {
  schema_version?: string;
  flow_stage?: string | null;
  ai_lead_agent?: string | null;
  supporting_agents?: string[];
  automation_state?: string | null;
  safe_to_auto_repair?: boolean | null;
  blocking_reason?: string | null;
  matching_strategy?: string | null;
  already_done?: string[];
  next_actions?: string[];
}

interface KmStaleCompletionSummary {
  schema_version?: string;
  source_schema_version?: string | null;
  project_id?: string | null;
  incident_id?: string | null;
  status?: string | null;
  missing_reason?: string | null;
  total?: number;
  returned?: number;
  pending_count?: number;
  ready_count?: number;
  blocked_count?: number;
  completed_count?: number;
  failed_count?: number;
  writes_on_read?: boolean | null;
  manual_review_required?: boolean | null;
  batch_writes_allowed?: boolean | null;
  items_truncated?: boolean | null;
  related_total?: number;
  related_items?: KmStaleCompletionSummaryItem[];
  work_item?: KmStaleCallbackOwnerReviewWorkItem | null;
  triage?: KmStaleCallbackOwnerReviewTriage | null;
}

interface CallbackReplyEvent {
  message_id: string;
  run_id: string;
  project_id: string;
  status: CallbackReplyStatus | string;
  needs_human: boolean;
  action?: string | null;
  incident_id?: string | null;
  event_at?: string | null;
  channel_type: string;
  message_type: string;
  send_status: string;
  send_error?: string | null;
  provider_message_id?: string | null;
  triggered_by_state?: string | null;
  content_preview?: string | null;
  run_state?: string | null;
  agent_id?: string | null;
  run_detail_href?: string | null;
  awooop_status_chain?: AwoooPStatusChain | null;
  persisted_awooop_status_chain?: AwoooPStatusChain | null;
  km_stale_completion_summary?: KmStaleCompletionSummary | null;
  persisted_km_stale_completion_summary?: KmStaleCompletionSummary | null;
  evidence_capture_status?: CallbackEvidenceCaptureStatus | null;
}

interface CallbackRepliesResponse {
  items?: CallbackReplyEvent[];
  total: number;
  page: number;
  per_page: number;
  summary?: CallbackReplyAuditSummary | null;
  cache?: OperatorSummaryCacheInfo | null;
}

interface AiRoutePolicyItem {
  priority: number;
  provider_name: string;
  url?: string | null;
  workload_type?: string | null;
  reason?: string | null;
  role?: string | null;
  runtime?: string | null;
  model?: string | null;
}

interface AiRouteHealthItem {
  status?: string | null;
  host?: string | null;
  latency_ms?: number | null;
  reason?: string | null;
  checked_at?: number | null;
  from_cache?: boolean;
  checked?: boolean;
}

interface AiRouteLaneItem {
  priority?: number | null;
  provider_name?: string | null;
  role?: string | null;
  runtime?: string | null;
  url?: string | null;
  health_status?: string | null;
  reason?: string | null;
  action_required?: boolean;
}

interface AiRouteOperatorAction {
  human_required?: boolean;
  action?: string | null;
  reason?: string | null;
}

interface AiRouteRepairEvidence {
  provider?: string | null;
  stage?: string | null;
  provider_event_id?: string | null;
  conversation_event_id?: string | null;
  run_id?: string | null;
  alertname?: string | null;
  severity?: string | null;
  fingerprint?: string | null;
  target_resource?: string | null;
  observed_state?: Record<string, unknown>;
  live_probe?: Record<string, unknown>;
  access_blockers?: string[];
  side_effects?: {
    incident_created?: boolean | null;
    telegram_sent?: boolean | null;
    approval_created?: boolean | null;
    runtime_route_changed?: boolean | null;
  };
  source_ref_count?: number | null;
  provider_ts?: string | null;
  received_at?: string | null;
}

interface AiRouteStatusResponse {
  schema_version: string;
  workload_type: string;
  policy_order: AiRoutePolicyItem[];
  selected_provider?: string | null;
  selected_url?: string | null;
  selected_model?: string | null;
  fallback_chain: AiRoutePolicyItem[];
  route_reason: string;
  route_source: string;
  route_error?: string | null;
  health: Record<string, AiRouteHealthItem>;
  lane_mode?: string | null;
  active_lane?: AiRouteLaneItem | null;
  skipped_lanes?: AiRouteLaneItem[];
  operator_action?: AiRouteOperatorAction | null;
  repair_evidence?: AiRouteRepairEvidence | null;
  checked_at: string;
}

type GitHubRunReadinessMetric = {
  key: string;
  value: string;
  icon: typeof Activity;
  tone: "neutral" | "warn";
};

type GitHubRunReadinessRef = {
  key: string;
  name: string;
  status: string;
};

type OwnerResponseValidationRunRef = {
  phase: string;
  key: string;
  contract: string;
};

// =============================================================================
// 常數
// =============================================================================

const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? "";
const PER_PAGE = 50;
const AUTO_REFRESH_INTERVAL = 30_000; // 30 秒
const INCIDENT_ID_FILTER_RE = /^INC-\d{8}-[A-Z0-9]{4,}$/;

const STATE_CONFIG: Record<
  RunState,
  { label: string; bg: string; text: string; border: string; pulse?: boolean }
> = {
  pending: {
    label: "待執行",
    bg: "bg-[#f4f1e8]",
    text: "text-[#5f5b52]",
    border: "border-[#d8d3c7]",
  },
  running: {
    label: "執行中",
    bg: "bg-[#f0faf2]",
    text: "text-[#17602a]",
    border: "border-[#9bc7a4]",
    pulse: true,
  },
  waiting_tool: {
    label: "等待工具",
    bg: "bg-[#fff7e8]",
    text: "text-[#8a5a08]",
    border: "border-[#d9b36f]",
  },
  waiting_approval: {
    label: "等待審批",
    bg: "bg-[#fff7e8]",
    text: "text-[#8a5a08]",
    border: "border-[#d9b36f]",
  },
  completed: {
    label: "已完成",
    bg: "bg-[#f0faf2]",
    text: "text-[#17602a]",
    border: "border-[#9bc7a4]",
  },
  failed: {
    label: "失敗",
    bg: "bg-[#fff0ef]",
    text: "text-[#9f2f25]",
    border: "border-[#e2a29b]",
  },
  cancelled: {
    label: "已取消",
    bg: "bg-[#fff0ef]",
    text: "text-[#9f2f25]",
    border: "border-[#e2a29b]",
  },
  timeout: {
    label: "已超時",
    bg: "bg-[#fff0ef]",
    text: "text-[#9f2f25]",
    border: "border-[#e2a29b]",
  },
};

const LANE_CONFIG: Record<
  RunLane,
  {
    label: string;
    detail: string;
    icon: typeof Activity;
    className: string;
  }
> = {
  intake: {
    label: "排程入口",
    detail: "等待 worker 接手",
    icon: ListChecks,
    className: "border-[#d8d3c7] bg-white text-[#5f5b52]",
  },
  diagnosis: {
    label: "只讀診斷",
    detail: "MCP / SSH / RAG 收集證據",
    icon: SearchCheck,
    className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
  },
  approval: {
    label: "人工閘門",
    detail: "等待 SRE 批准或拒絕",
    icon: ShieldCheck,
    className: "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
  },
  execution: {
    label: "AI 執行中",
    detail: "模型推理或安全動作執行",
    icon: Activity,
    className: "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
  },
  done: {
    label: "已收斂",
    detail: "完成並等待稽核回寫",
    icon: Activity,
    className: "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
  },
  manual: {
    label: "人工升級",
    detail: "AI 無法閉環，需人工處置",
    icon: TriangleAlert,
    className: "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]",
  },
};

const REMEDIATION_STATUS_CONFIG: Record<
  RemediationStatus,
  {
    labelKey: string;
    detailKey: string;
    icon: typeof Activity;
    className: string;
  }
> = {
  no_evidence: {
    labelKey: "statuses.noEvidence",
    detailKey: "details.noEvidence",
    icon: AlertCircle,
    className: "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]",
  },
  mcp_observed: {
    labelKey: "statuses.mcpObserved",
    detailKey: "details.mcpObserved",
    icon: SearchCheck,
    className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
  },
  read_only_dry_run: {
    labelKey: "statuses.readOnlyDryRun",
    detailKey: "details.readOnlyDryRun",
    icon: SearchCheck,
    className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
  },
  write_observed: {
    labelKey: "statuses.writeObserved",
    detailKey: "details.writeObserved",
    icon: TriangleAlert,
    className: "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
  },
  blocked: {
    labelKey: "statuses.blocked",
    detailKey: "details.blocked",
    icon: TriangleAlert,
    className: "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]",
  },
  observed: {
    labelKey: "statuses.observed",
    detailKey: "details.observed",
    icon: ListChecks,
    className: "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
  },
};
const REMEDIATION_FILTER_OPTIONS: RemediationStatus[] = [
  "mcp_observed",
  "read_only_dry_run",
  "write_observed",
  "blocked",
  "observed",
  "no_evidence",
];

const CALLBACK_REPLY_CONFIG: Record<
  CallbackReplyStatus,
  {
    labelKey: string;
    detailKey: string;
    className: string;
  }
> = {
  no_callback: {
    labelKey: "statuses.noCallback",
    detailKey: "details.noCallback",
    className: "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]",
  },
  sent: {
    labelKey: "statuses.sent",
    detailKey: "details.sent",
    className: "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
  },
  fallback_sent: {
    labelKey: "statuses.fallbackSent",
    detailKey: "details.fallbackSent",
    className: "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
  },
  rescue_sent: {
    labelKey: "statuses.rescueSent",
    detailKey: "details.rescueSent",
    className: "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
  },
  failed: {
    labelKey: "statuses.failed",
    detailKey: "details.failed",
    className: "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]",
  },
  observed: {
    labelKey: "statuses.observed",
    detailKey: "details.observed",
    className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
  },
};
const CALLBACK_REPLY_FILTER_OPTIONS: CallbackReplyStatus[] = [
  "failed",
  "fallback_sent",
  "rescue_sent",
  "sent",
  "observed",
  "no_callback",
];

const githubRunReadinessMetrics: GitHubRunReadinessMetric[] = [
  { key: "candidateRepos", value: "8", icon: GitBranch, tone: "neutral" },
  { key: "inScopeRepos", value: "7", icon: ListChecks, tone: "warn" },
  { key: "securityRuns", value: "0", icon: Activity, tone: "warn" },
  { key: "ownerResponses", value: "0/22", icon: ShieldCheck, tone: "warn" },
  { key: "workflowInventory", value: "0/7", icon: SearchCheck, tone: "warn" },
];

const githubRunReadinessRefs: GitHubRunReadinessRef[] = [
  {
    key: "primaryReadiness",
    name: "source_control_primary_readiness_gate_v1",
    status: "ready=0",
  },
  {
    key: "ownerValidation",
    name: "source_control_owner_response_validation_rollup_v1",
    status: "0/22",
  },
  {
    key: "workflowInventory",
    name: "source_control_workflow_secret_name_inventory_v1",
    status: "0/7",
  },
  {
    key: "rollbackAdr",
    name: "source_control_primary_rollback_adr_v1",
    status: "0/7",
  },
];

const githubRunReadinessBoundaries = [
  "security_run_created=false",
  "github_primary_run_created=false",
  "execution_router_linked=false",
  "repo_creation_authorized=false",
  "refs_mutation_authorized=false",
  "workflow_secret_modification_authorized=false",
  "secret_value_collection_allowed=false",
  "github_primary_switch_authorized=false",
  "gitea_disablement_authorized=false",
  "runtime_execution_authorized=false",
  "action_buttons_allowed=false",
];

const ownerResponseValidationRunRefs: OwnerResponseValidationRunRef[] = [
  {
    phase: "S4.13",
    key: "validationRollup",
    contract: "source_control_owner_response_validation_rollup_v1",
  },
  {
    phase: "S4.9",
    key: "giteaAttestation",
    contract: "gitea_inventory_owner_attestation_response_v1",
  },
  {
    phase: "S4.10",
    key: "githubTarget",
    contract: "github_target_owner_decision_response_v1",
  },
  {
    phase: "S4.11",
    key: "refsTruth",
    contract: "source_control_ref_truth_owner_response_v1",
  },
  {
    phase: "S4.12",
    key: "workflowSecret",
    contract: "source_control_workflow_secret_name_owner_response_v1",
  },
];

const ownerResponseValidationRunBoundaries = [
  "owner_response_validation_received_count=0",
  "owner_response_validation_accepted_count=0",
  "owner_response_validation_rejected_count=0",
  "security_run_created=false",
  "owner_response_validation_run_created=false",
  "platform_run_creation_authorized=false",
  "execution_router_linked=false",
  "approval_record_created=false",
  "repo_creation_authorized=false",
  "refs_sync_authorized=false",
  "workflow_modification_authorized=false",
  "secret_value_collection_allowed=false",
  "github_primary_switch_authorized=false",
  "runtime_execution_authorized=false",
  "action_buttons_allowed=false",
];

function getRunLane(state: RunState): RunLane {
  if (state === "pending") return "intake";
  if (state === "waiting_tool") return "diagnosis";
  if (state === "waiting_approval") return "approval";
  if (state === "running") return "execution";
  if (state === "completed") return "done";
  return "manual";
}

// =============================================================================
// Sub Components
// =============================================================================

function RunStateBadge({ state }: { state: RunState }) {
  const config = STATE_CONFIG[state] ?? STATE_CONFIG.pending;
  return (
    <span
      className={cn(
        "inline-flex items-center gap-1.5 rounded-wooo-sm border px-2.5 py-0.5 text-xs font-mono font-medium",
        config.bg,
        config.text,
        config.border
      )}
    >
      {config.pulse && (
        <span className="w-1.5 h-1.5 rounded-full bg-green-400 animate-pulse" aria-hidden="true" />
      )}
      {config.label}
    </span>
  );
}

function ShadowBadge({ isShadow }: { isShadow: boolean }) {
  if (!isShadow) return <span className="text-muted-foreground text-sm">--</span>;
  return (
    <span className="inline-flex items-center border border-[#d8d3c7] bg-white px-2 py-0.5 text-xs font-medium text-[#5f5b52]">
      Shadow
    </span>
  );
}

function RunLaneBadge({ state }: { state: RunState }) {
  const lane = LANE_CONFIG[getRunLane(state)];
  const Icon = lane.icon;

  return (
    <span
      className={cn(
        "inline-flex items-center gap-1.5 border px-2 py-0.5 text-xs font-semibold",
        lane.className
      )}
      title={lane.detail}
    >
      <Icon className="h-3.5 w-3.5" aria-hidden="true" />
      {lane.label}
    </span>
  );
}

function normalizeRemediationStatus(summary?: RemediationSummary | null): RemediationStatus {
  const statusValue = summary?.status;
  if (
    statusValue === "mcp_observed" ||
    statusValue === "read_only_dry_run" ||
    statusValue === "write_observed" ||
    statusValue === "blocked" ||
    statusValue === "observed"
  ) {
    return statusValue;
  }
  return "no_evidence";
}

function normalizeCallbackReplyStatus(summary?: CallbackReplySummary | null): CallbackReplyStatus {
  const statusValue = summary?.status;
  if (
    statusValue === "sent" ||
    statusValue === "fallback_sent" ||
    statusValue === "rescue_sent" ||
    statusValue === "failed" ||
    statusValue === "observed"
  ) {
    return statusValue;
  }
  return "no_callback";
}

function normalizeCallbackReplyEventStatus(statusValue?: string | null): CallbackReplyStatus {
  if (
    statusValue === "sent" ||
    statusValue === "fallback_sent" ||
    statusValue === "rescue_sent" ||
    statusValue === "failed" ||
    statusValue === "observed"
  ) {
    return statusValue;
  }
  return "observed";
}

function normalizeCallbackEvidenceCaptureStatus(
  statusValue?: string | null
): CallbackEvidenceCaptureState {
  if (
    statusValue === "captured" ||
    statusValue === "partial" ||
    statusValue === "not_captured"
  ) {
    return statusValue;
  }
  return "observed";
}

function normalizeKmCompletionStatus(statusValue?: string | null) {
  if (
    statusValue === "matched_owner_review" ||
    statusValue === "no_related_owner_review" ||
    statusValue === "fetch_failed" ||
    statusValue === "no_incident"
  ) {
    return statusValue;
  }
  return "observed";
}

function SecurityRunStateCandidatePanel() {
  const t = useTranslations("awooop.runs.securityRunStateCandidate");
  const metrics = [
    {
      label: t("metrics.visibility"),
      value: t("metrics.visibilityValue"),
      detail: t("metrics.visibilityDetail"),
    },
    {
      label: t("metrics.runtimeRuns"),
      value: "0",
      detail: t("metrics.runtimeRunsDetail"),
    },
    {
      label: t("metrics.activeGates"),
      value: "0",
      detail: t("metrics.activeGatesDetail"),
    },
    {
      label: t("metrics.ownerResponse"),
      value: "0",
      detail: t("metrics.ownerResponseDetail"),
    },
  ];
  const runRefs = [
    {
      name: "security_mirror_run_state_candidate",
      detail: t("runRefs.mirrorRunState"),
    },
    {
      name: "read_only_dry_run_only",
      detail: t("runRefs.readOnlyDryRun"),
    },
    {
      name: "S4.9-S4.12 負責人回覆等待中",
      detail: t("runRefs.ownerResponse"),
    },
    {
      name: "主動執行期閘門 0",
      detail: t("runRefs.activeGates"),
    },
  ];

  return (
    <section className="overflow-hidden border border-[#e0ddd4] bg-white">
      <div className="sm:hidden">
        <div className="border-b border-[#e0ddd4] bg-[#faf9f3] px-2 py-2">
          <p className="text-[11px] font-semibold leading-4 text-[#141413]">{t("title")}</p>
          <span className="mt-1 inline-flex border border-[#9bb6d9] bg-[#eef5ff] px-1.5 py-0.5 text-[10px] font-semibold text-[#1f5b9b]">
            {t("badge")}
          </span>
        </div>
        <div className="grid gap-px bg-[#e0ddd4] text-[10px]">
          <div className="bg-white px-2 py-2">
            <p className="font-semibold text-[#77736a]">視圖</p>
            <p className="mt-1 text-lg font-semibold text-[#141413]">只讀</p>
          </div>
          <div className="bg-white px-2 py-2">
            <p className="font-semibold text-[#77736a]">執行</p>
            <p className="mt-1 font-mono text-lg font-semibold text-[#141413]">0</p>
          </div>
          <div className="bg-white px-2 py-2">
            <p className="font-semibold text-[#77736a]">閘門</p>
            <p className="mt-1 font-mono text-lg font-semibold text-[#141413]">0</p>
          </div>
          <div className="bg-white px-2 py-2">
            <p className="font-semibold text-[#77736a]">負責人</p>
            <p className="mt-1 font-mono text-lg font-semibold text-[#141413]">0</p>
          </div>
        </div>
        <div className="space-y-2 bg-[#faf9f3] px-2 py-2 text-[10px] leading-4 text-[#5f5b52]">
          <p className="font-semibold text-[#141413]">{t("boundaryTitle")}</p>
          <p>4 gates = false</p>
          <Link
            href="/iwooos"
            className="inline-flex items-center gap-1 border border-[#d8d3c7] bg-white px-2 py-1 font-semibold text-[#141413] hover:border-[#d97757]"
          >
            IwoooS
            <ArrowRight className="h-3 w-3 text-[#77736a]" aria-hidden="true" />
          </Link>
        </div>
      </div>

      <div className="hidden sm:block">
        <div className="flex flex-wrap items-start justify-between gap-3 border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
          <div className="flex items-start gap-2">
            <ShieldCheck className="mt-0.5 h-4 w-4 text-[#d97757]" aria-hidden="true" />
            <div>
              <h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
              <p className="mt-1 max-w-3xl text-xs leading-5 text-[#77736a]">{t("subtitle")}</p>
            </div>
          </div>
          <span className="inline-flex border border-[#9bb6d9] bg-[#eef5ff] px-2 py-0.5 text-xs font-semibold text-[#1f5b9b]">
            {t("badge")}
          </span>
        </div>

        <div className="grid gap-px bg-[#e0ddd4] md:grid-cols-2 xl:grid-cols-4">
          {metrics.map((item) => (
            <div key={item.label} className="bg-white px-4 py-3">
              <p className="text-xs font-semibold text-[#77736a]">{item.label}</p>
              <p className="mt-2 break-words font-mono text-2xl font-semibold text-[#141413]">{item.value}</p>
              <p className="mt-2 text-xs leading-5 text-[#5f5b52]">{item.detail}</p>
            </div>
          ))}
        </div>

        <div className="grid min-w-0 gap-4 p-4 xl:grid-cols-[1.1fr_0.9fr]">
          <div className="min-w-0 border border-[#e0ddd4] bg-white">
            <div className="border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3 text-xs font-semibold text-[#141413]">
              {t("runRefsTitle")}
            </div>
            <div className="divide-y divide-[#eee9dd]">
              {runRefs.map((item) => (
                <div key={item.name} className="px-4 py-3">
                  <p className="break-words font-mono text-xs font-semibold text-[#141413]">{item.name}</p>
                  <p className="mt-1 text-xs leading-5 text-[#5f5b52]">{item.detail}</p>
                </div>
              ))}
            </div>
          </div>

          <div className="min-w-0 border border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
            <p className="text-xs font-semibold text-[#77736a]">{t("boundaryLabel")}</p>
            <p className="mt-2 text-sm font-semibold text-[#141413]">{t("boundaryTitle")}</p>
            <p className="mt-2 text-xs leading-5 text-[#5f5b52]">{t("boundaryDetail")}</p>
            <div className="mt-4 grid gap-2 font-mono text-xs text-[#141413]">
              <span>security_run_created=false</span>
              <span>execution_router_linked=false</span>
              <span>runtime_execution_authorized=false</span>
              <span>action_buttons_allowed=false</span>
            </div>
            <Link
              href="/iwooos"
              className="mt-4 inline-flex items-center gap-2 border border-[#d8d3c7] bg-white px-3 py-1.5 text-xs font-semibold text-[#141413] hover:border-[#d97757]"
            >
              {t("openIwooos")}
              <ArrowRight className="h-3.5 w-3.5 text-[#77736a]" aria-hidden="true" />
            </Link>
          </div>
        </div>
      </div>
    </section>
  );
}

function GitHubRunReadinessBoundaryPanel() {
  const t = useTranslations("awooop.runs.githubRunReadinessBoundary");

  return (
    <section className="overflow-hidden border border-[#e0ddd4] bg-white">
      <div className="flex flex-wrap items-start justify-between gap-3 border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
        <div className="flex min-w-0 items-start gap-2">
          <GitBranch className="mt-0.5 h-4 w-4 shrink-0 text-[#d97757]" aria-hidden="true" />
          <div className="min-w-0">
            <h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
            <p className="mt-1 max-w-3xl text-xs leading-5 text-[#77736a]">{t("subtitle")}</p>
          </div>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          <span className="inline-flex border border-[#d9b36f] bg-[#fff7e8] px-2 py-0.5 text-xs font-semibold text-[#8a5a08]">
            {t("badge")}
          </span>
          <Link
            href="/iwooos"
            className="inline-flex items-center gap-2 border border-[#d8d3c7] bg-white px-3 py-1.5 text-xs font-semibold text-[#141413] hover:border-[#d97757]"
          >
            {t("openIwooos")}
            <ArrowRight className="h-3.5 w-3.5 text-[#77736a]" aria-hidden="true" />
          </Link>
        </div>
      </div>

      <div className="grid gap-px bg-[#e0ddd4] md:grid-cols-2 xl:grid-cols-5">
        {githubRunReadinessMetrics.map((metric) => {
          const Icon = metric.icon;
          return (
            <div key={metric.key} className="min-h-[122px] bg-white px-4 py-3">
              <div className="flex items-start justify-between gap-3">
                <div className="min-w-0">
                  <p className="text-xs font-semibold text-[#77736a]">
                    {t(`metrics.${metric.key}.label` as never)}
                  </p>
                  <p className="mt-2 break-words font-mono text-2xl font-semibold text-[#141413]">
                    {metric.value}
                  </p>
                </div>
                <span
                  className={cn(
                    "flex h-8 w-8 shrink-0 items-center justify-center border",
                    metric.tone === "warn" && "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
                    metric.tone === "neutral" && "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]"
                  )}
                >
                  <Icon className="h-4 w-4" aria-hidden="true" />
                </span>
              </div>
              <p className="mt-3 text-xs leading-5 text-[#5f5b52]">
                {t(`metrics.${metric.key}.detail` as never)}
              </p>
            </div>
          );
        })}
      </div>

      <div className="grid min-w-0 gap-4 p-4 xl:grid-cols-[1.1fr_0.9fr]">
        <div className="min-w-0 border border-[#e0ddd4] bg-white">
          <div className="border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3 text-xs font-semibold text-[#141413]">
            {t("runRefsTitle")}
          </div>
          <div className="divide-y divide-[#eee9dd]">
            {githubRunReadinessRefs.map((ref) => (
              <div key={ref.key} className="grid gap-3 px-4 py-3 md:grid-cols-[minmax(0,1fr)_96px]">
                <div className="min-w-0">
                  <p className="break-all font-mono text-xs font-semibold text-[#141413]">
                    {ref.name}
                  </p>
                  <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
                    {t(`runRefs.${ref.key}` as never)}
                  </p>
                </div>
                <div>
                  <span className="inline-flex border border-[#d9b36f] bg-[#fff7e8] px-2 py-0.5 font-mono text-xs font-semibold text-[#8a5a08]">
                    {ref.status}
                  </span>
                </div>
              </div>
            ))}
          </div>
        </div>

        <div className="min-w-0 border border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
          <div className="flex items-start gap-2">
            <Lock className="mt-0.5 h-4 w-4 shrink-0 text-[#8a5a08]" aria-hidden="true" />
            <div>
              <p className="text-xs font-semibold text-[#77736a]">{t("boundaryLabel")}</p>
              <p className="mt-2 text-sm font-semibold text-[#141413]">{t("boundaryTitle")}</p>
            </div>
          </div>
          <p className="mt-2 text-xs leading-5 text-[#5f5b52]">{t("boundaryDetail")}</p>
          <div className="mt-4 grid gap-2 break-all font-mono text-xs text-[#141413]">
            {githubRunReadinessBoundaries.map((boundary) => (
              <span key={boundary}>{boundary}</span>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

function OwnerResponseValidationRunBoundaryPanel() {
  const t = useTranslations("awooop.runs.ownerResponseValidationRunBoundary");
  const metrics = [
    {
      label: t("metrics.packets"),
      value: "4",
      detail: t("metrics.packetsDetail"),
    },
    {
      label: t("metrics.templates"),
      value: "22",
      detail: t("metrics.templatesDetail"),
    },
    {
      label: t("metrics.received"),
      value: "0",
      detail: t("metrics.receivedDetail"),
    },
    {
      label: t("metrics.accepted"),
      value: "0",
      detail: t("metrics.acceptedDetail"),
    },
    {
      label: t("metrics.securityRuns"),
      value: "0",
      detail: t("metrics.securityRunsDetail"),
    },
    {
      label: t("metrics.displaySections"),
      value: "8",
      detail: t("metrics.displaySectionsDetail"),
    },
  ];

  return (
    <section className="overflow-hidden border border-[#d9d4e6] bg-white">
      <div className="flex flex-wrap items-start justify-between gap-3 border-b border-[#d9d4e6] bg-[#f8f6fc] px-4 py-3">
        <div className="flex min-w-0 items-start gap-2">
          <ListChecks className="mt-0.5 h-4 w-4 shrink-0 text-[#6f5ca8]" aria-hidden="true" />
          <div className="min-w-0">
            <h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
            <p className="mt-1 max-w-3xl text-xs leading-5 text-[#5f5a70]">{t("subtitle")}</p>
          </div>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          <span className="inline-flex border border-[#b7add8] bg-white px-2 py-0.5 text-xs font-semibold text-[#5b4b91]">
            {t("badge")}
          </span>
          <Link
            href="/iwooos"
            className="inline-flex items-center gap-2 border border-[#b7add8] bg-white px-3 py-1.5 text-xs font-semibold text-[#141413] hover:border-[#6f5ca8]"
          >
            {t("openIwooos")}
            <ArrowRight className="h-3.5 w-3.5 text-[#5f5a70]" aria-hidden="true" />
          </Link>
        </div>
      </div>

      <div className="grid gap-px bg-[#d9d4e6] md:grid-cols-2 xl:grid-cols-6">
        {metrics.map((item) => (
          <div key={item.label} className="min-h-[122px] bg-white px-4 py-3">
            <p className="text-xs font-semibold text-[#5f5a70]">{item.label}</p>
            <p className="mt-2 break-words font-mono text-2xl font-semibold text-[#141413]">{item.value}</p>
            <p className="mt-2 text-xs leading-5 text-[#4f4a60]">{item.detail}</p>
          </div>
        ))}
      </div>

      <div className="grid min-w-0 gap-4 p-4 xl:grid-cols-[1.1fr_0.9fr]">
        <div className="min-w-0 border border-[#d9d4e6] bg-white">
          <div className="border-b border-[#d9d4e6] bg-[#f8f6fc] px-4 py-3 text-xs font-semibold text-[#141413]">
            {t("runRefsTitle")}
          </div>
          <div className="divide-y divide-[#e8e3f2]">
            {ownerResponseValidationRunRefs.map((item) => (
              <div key={item.key} className="grid gap-3 px-4 py-3 md:grid-cols-[72px_minmax(0,1fr)]">
                <span className="font-mono text-xs font-semibold text-[#141413]">{item.phase}</span>
                <div className="min-w-0">
                  <p className="text-sm font-semibold text-[#141413]">
                    {t(`runRefs.${item.key}.title` as never)}
                  </p>
                  <p className="mt-1 text-xs leading-5 text-[#4f4a60]">
                    {t(`runRefs.${item.key}.detail` as never)}
                  </p>
                  <p className="mt-2 break-all font-mono text-[11px] text-[#5f5a70]">
                    {item.contract}
                  </p>
                </div>
              </div>
            ))}
          </div>
        </div>

        <div className="min-w-0 border border-[#d9d4e6] bg-[#f8f6fc] px-4 py-3">
          <div className="flex items-start gap-2">
            <Lock className="mt-0.5 h-4 w-4 shrink-0 text-[#6f5ca8]" aria-hidden="true" />
            <div>
              <p className="text-xs font-semibold text-[#5f5a70]">{t("boundaryLabel")}</p>
              <p className="mt-2 text-sm font-semibold text-[#141413]">{t("boundaryTitle")}</p>
            </div>
          </div>
          <p className="mt-2 text-xs leading-5 text-[#4f4a60]">{t("boundaryDetail")}</p>
          <div className="mt-4 grid gap-2 break-all font-mono text-xs text-[#141413]">
            {ownerResponseValidationRunBoundaries.map((boundary) => (
              <span key={boundary}>{boundary}</span>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

// =============================================================================
// Main Component
// =============================================================================

function CallbackEvidenceCaptureStatusPanel({
  captureStatus,
}: {
  captureStatus?: CallbackEvidenceCaptureStatus | null;
}) {
  const t = useTranslations("awooop.callbackReply.events.capture");
  if (!captureStatus) return null;

  const state = normalizeCallbackEvidenceCaptureStatus(captureStatus.status);
  const config = {
    captured: {
      className: "border-[#8ec58e] bg-[#edf8ed] text-[#17602a]",
      icon: ShieldCheck,
    },
    partial: {
      className: "border-[#e1c36a] bg-[#fff7df] text-[#8a5a08]",
      icon: AlertCircle,
    },
    not_captured: {
      className: "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]",
      icon: BellOff,
    },
    observed: {
      className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
      icon: SearchCheck,
    },
  }[state];
  const Icon = config.icon;
  const itemLabels: Record<string, string> = {
    awooop_status_chain: t("items.awooopStatusChain"),
    km_stale_completion_summary: t("items.kmCompletionSummary"),
  };
  const formatItems = (items?: string[]) => (
    items && items.length > 0
      ? items.map((item) => itemLabels[item] ?? item).join(" / ")
      : t("none")
  );
  const nextActionRaw = captureStatus.next_action ?? "observed";
  const nextActionKey = nextActionRaw === "none"
    || nextActionRaw === "press_telegram_detail_or_history_after_rollout"
    ? nextActionRaw
    : "observed";

  return (
    <div className="mt-3 border-t border-[#e0ddd4] pt-3">
      <div className="flex flex-wrap items-center gap-2">
        <Icon className="h-3.5 w-3.5 text-[#1f5b9b]" aria-hidden="true" />
        <p className="text-xs font-semibold text-[#141413]">{t("title")}</p>
        <span
          className={cn(
            "inline-flex items-center border px-2 py-0.5 text-xs font-semibold",
            config.className
          )}
        >
          {t(`statuses.${state}` as never)}
        </span>
      </div>
      <div className="mt-2 grid gap-1 text-xs leading-5 text-[#5f5b52]">
        <p>
          {t("captured", {
            items: formatItems(captureStatus.captured),
          })}
        </p>
        <p>
          {t("missing", {
            items: formatItems(captureStatus.missing),
          })}
        </p>
        <p>
          {t("nextAction", {
            action: t(`nextActions.${nextActionKey}` as never),
          })}
        </p>
        <p className="truncate font-mono text-[#77736a]">
          {t("reason", {
            reason: captureStatus.reason ?? "--",
            rollout: captureStatus.snapshot_rollout ?? "--",
          })}
        </p>
      </div>
    </div>
  );
}

function RemediationEvidenceCell({ summary }: { summary?: RemediationSummary | null }) {
  const t = useTranslations("awooop.listEvidence");
  const status = normalizeRemediationStatus(summary);
  const config = REMEDIATION_STATUS_CONFIG[status];
  const Icon = config.icon;
  const total = summary?.total ?? 0;
  const mcpTotal = summary?.mcp_observation_total ?? 0;
  const evidenceTotal = summary?.evidence_total ?? total + mcpTotal;
  const route = summary?.latest_route && summary.latest_route !== "--"
    ? summary.latest_route
    : null;
  const countText = status === "mcp_observed"
    ? t("mcpCount", { count: mcpTotal || evidenceTotal })
    : t("count", { count: total });

  return (
    <div className="flex min-w-[230px] flex-col gap-1">
      <span
        className={cn(
          "inline-flex w-fit items-center gap-1.5 border px-2 py-0.5 text-xs font-semibold",
          config.className
        )}
        title={t(config.detailKey)}
      >
        <Icon className="h-3.5 w-3.5" aria-hidden="true" />
        {t(config.labelKey)}
      </span>
      {total > 0 || mcpTotal > 0 ? (
        <span className="text-xs leading-5 text-[#5f5b52]">
          {countText}
          {route ? ` · ${t("route", { route })}` : ""}
        </span>
      ) : (
        <span className="text-xs leading-5 text-[#77736a]">{t("emptyShort")}</span>
      )}
      {summary?.human_gate_open && (
        <span className="text-xs font-semibold text-[#8a5a08]">
          {t("manualGate")}
        </span>
      )}
    </div>
  );
}

function CallbackReplyCell({ summary }: { summary?: CallbackReplySummary | null }) {
  const t = useTranslations("awooop.callbackReply");
  const status = normalizeCallbackReplyStatus(summary);
  const config = CALLBACK_REPLY_CONFIG[status];
  const total = summary?.total ?? 0;
  const captureStatus = total > 0
    ? normalizeCallbackEvidenceCaptureStatus(summary?.capture_status)
    : null;
  const captureConfig = captureStatus
    ? {
        captured: "text-[#17602a]",
        partial: "text-[#8a5a08]",
        not_captured: "text-[#9f2f25]",
        observed: "text-[#1f5b9b]",
      }[captureStatus]
    : null;
  const latestAction = summary?.latest_action ? String(summary.latest_action) : null;
  const latestIncidentId = summary?.latest_incident_id ? String(summary.latest_incident_id) : null;
  const captureItemLabels: Record<string, string> = {
    awooop_status_chain: t("captureItems.awooopStatusChain"),
    km_stale_completion_summary: t("captureItems.kmCompletionSummary"),
  };
  const latestCaptureMissing = Array.isArray(summary?.latest_capture_missing)
    ? summary.latest_capture_missing
    : [];
  const latestCaptureMissingText = latestCaptureMissing.length > 0
    ? latestCaptureMissing.map((item) => captureItemLabels[item] ?? item).join(" / ")
    : null;
  const countText = total > 0
    ? t("count", {
        total,
        failed: summary?.failed ?? 0,
        fallback: (summary?.fallback_sent ?? 0) + (summary?.rescue_sent ?? 0),
      })
    : t("emptyShort");
  const latestText = latestAction || latestIncidentId
    ? t("latest", {
        action: latestAction ?? "--",
        incidentId: latestIncidentId ?? "--",
      })
    : null;

  return (
    <div className="flex min-w-[210px] flex-col gap-1">
      <span
        className={cn(
          "inline-flex w-fit items-center gap-1.5 border px-2 py-0.5 text-xs font-semibold",
          config.className
        )}
        title={t(config.detailKey)}
      >
        <Send className="h-3.5 w-3.5" aria-hidden="true" />
        {t(config.labelKey)}
      </span>
      <span className={cn("text-xs leading-5", total > 0 ? "text-[#5f5b52]" : "text-[#77736a]")}>
        {countText}
      </span>
      {latestText && (
        <span className="truncate font-mono text-xs text-[#77736a]">
          {latestText}
        </span>
      )}
      {captureStatus && (
        <span
          className={cn("text-xs leading-5", captureConfig)}
          title={latestCaptureMissingText ? t("captureMissing", { items: latestCaptureMissingText }) : undefined}
        >
          {t("captureLine", {
            status: t(`captureStatuses.${captureStatus}` as never),
            captured: summary?.capture_captured ?? 0,
            partial: summary?.capture_partial ?? 0,
            notCaptured: summary?.capture_not_captured ?? 0,
          })}
        </span>
      )}
      {summary?.needs_human && (
        <span className="text-xs font-semibold text-[#9f2f25]">
          {t("needsHuman")}
        </span>
      )}
    </div>
  );
}

function linkedIncidentIds(summary?: RemediationSummary | null): string[] {
  const rawIds = summary?.incident_ids ?? [];
  return Array.from(
    new Set(
      rawIds
        .map((incidentId) => String(incidentId || "").trim().toUpperCase())
        .filter((incidentId) => INCIDENT_ID_FILTER_RE.test(incidentId))
    )
  );
}

function IncidentIdsCell({ run }: { run: Run }) {
  const t = useTranslations("awooop.listEvidence");
  const incidentIds = linkedIncidentIds(run.remediation_summary);
  const visibleIds = incidentIds.slice(0, 2);
  const hiddenCount = Math.max(incidentIds.length - visibleIds.length, 0);

  if (visibleIds.length === 0) {
    return (
      <span className="text-xs text-[#77736a]">
        {t("incident.empty")}
      </span>
    );
  }

  return (
    <div className="flex min-w-[220px] flex-wrap gap-1.5">
      {visibleIds.map((incidentId) => (
        <Link
          key={incidentId}
          href={`/awooop/runs?project_id=${encodeURIComponent(run.project_id)}&incident_id=${encodeURIComponent(incidentId)}` as never}
          className="inline-flex items-center border border-[#d8d3c7] bg-[#faf9f3] px-2 py-1 font-mono text-xs font-semibold text-[#2e2b26] hover:border-[#1f6feb] hover:bg-[#edf4ff] hover:text-[#0f4fa8]"
          title={t("incident.filterTitle", { incidentId })}
        >
          {incidentId}
        </Link>
      ))}
      {hiddenCount > 0 && (
        <span
          className="inline-flex items-center border border-[#d8d3c7] bg-white px-2 py-1 font-mono text-xs text-[#5f5b52]"
          title={incidentIds.slice(2).join(", ")}
        >
          {t("incident.more", { count: hiddenCount })}
        </span>
      )}
    </div>
  );
}

type SourceFlowListStatus = "verified" | "applied" | "evidence" | "provider" | "waiting" | "loading";
type OperatorFlowListStatus = "needsHuman" | "failed" | "verified" | "executed" | "waiting";

function sourceFlowListStatus(chain?: AwoooPStatusChain | null): SourceFlowListStatus {
  const correlation = chain?.source_refs?.correlation;
  if (!correlation) return "waiting";
  const verificationStatus = String(correlation.verification_status ?? correlation.status ?? "missing");
  if (verificationStatus === "applied_link_verified" || verificationStatus === "direct_ref_verified") {
    return "verified";
  }
  if ((correlation.applied_link_total ?? 0) > 0) return "applied";
  if ((correlation.direct_ref_total ?? 0) > 0 || (correlation.candidate_total ?? 0) > 0) {
    return "evidence";
  }
  if ((correlation.provider_event_total ?? 0) > 0) return "provider";
  return "waiting";
}

function sourceFlowListClass(status: SourceFlowListStatus) {
  if (status === "verified") return "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]";
  if (status === "applied" || status === "evidence") return "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]";
  if (status === "provider" || status === "loading") return "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]";
  return "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]";
}

function operatorFlowListStatus(chain?: AwoooPStatusChain | null): OperatorFlowListStatus {
  if (!chain) return "waiting";
  const outcomeState = String(chain.operator_outcome?.state ?? "").toLowerCase();
  const completionStatus = String(chain.operator_outcome?.execution_result?.completion_status ?? "").toLowerCase();
  const commandStatus = String(chain.operator_outcome?.execution_result?.command_status ?? "").toLowerCase();
  const repairState = String(chain.repair_state ?? "").toLowerCase();
  const verification = String(chain.verification ?? "").toLowerCase();
  const stageStatus = String(chain.stage_status ?? "").toLowerCase();

  if (chain.needs_human) return "needsHuman";
  if (
    outcomeState.includes("failed") ||
    completionStatus.includes("failed") ||
    commandStatus.includes("failed") ||
    stageStatus === "error"
  ) {
    return "failed";
  }
  if (repairState === "auto_repaired_verified" || verification === "verified") {
    return "verified";
  }
  if (repairState === "executed" || completionStatus === "completed" || stageStatus === "success") {
    return "executed";
  }
  return "waiting";
}

function operatorFlowListClass(status: OperatorFlowListStatus) {
  if (status === "verified") return "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]";
  if (status === "executed") return "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]";
  if (status === "failed" || status === "needsHuman") return "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]";
  return "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]";
}

function shortValue(value?: string | number | boolean | null) {
  if (value === null || value === undefined || value === "") return "--";
  return String(value);
}

function SourceFlowCell({
  chain,
  summary,
  hasIncident,
  loading,
}: {
  chain?: AwoooPStatusChain | null;
  summary?: RemediationSummary | null;
  hasIncident: boolean;
  loading: boolean;
}) {
  const t = useTranslations("awooop.listEvidence.sourceFlow");
  const status = loading && hasIncident ? "loading" : sourceFlowListStatus(chain);
  const operatorStatus = operatorFlowListStatus(chain);
  const correlation = chain?.source_refs?.correlation;
  const outcome = chain?.operator_outcome;
  const executionResult = outcome?.execution_result;
  const gateway = chain?.mcp?.gateway;
  const ansible = chain?.execution?.ansible;
  const firstBlocker = chain?.blockers?.[0];
  const nextAction = outcome?.next_action ?? chain?.next_step;
  const fallbackMcpTotal = summary?.mcp_observation_total ?? summary?.evidence_total ?? 0;
  const fallbackMcpSuccess = summary?.mcp_observation_success ?? (summary?.has_mcp_investigation ? fallbackMcpTotal : 0);
  const fallbackMcpFailed = summary?.mcp_observation_failed ?? 0;
  const hasChain = Boolean(chain);
  const shouldShowOperatorFallback = hasChain || hasIncident;
  const outcomeSummary = outcome?.summary_zh
    ?? executionResult?.summary_zh
    ?? (chain
      ? `${shortValue(chain.current_stage)} / ${shortValue(chain.stage_status)}`
      : summary?.has_mcp_investigation
        ? t("operator.fallbackMcpSummary", {
            count: fallbackMcpTotal,
            route: shortValue(summary.latest_route),
          })
        : hasIncident
          ? t("operator.fallbackMissingChain")
          : null);
  const blockerLine = firstBlocker
    ? t("blockedLine", { blocker: firstBlocker })
    : t("nextLine", {
        next: shortValue(
          nextAction
            ?? (hasChain ? chain?.next_step : t("operator.nextStatusChain"))
        ),
      });
  const mcpLine = t("mcpLine", {
    success: gateway?.success ?? fallbackMcpSuccess,
    total: gateway?.total ?? fallbackMcpTotal,
    failed: gateway?.failed ?? fallbackMcpFailed,
    blocked: gateway?.blocked ?? 0,
  });
  const ansibleLine = t("ansibleLine", {
    candidates: ansible?.candidate_count ?? 0,
    applied: ansible?.apply_total ?? 0,
    reason: shortValue(ansible?.not_used_reason ?? (!hasChain && hasIncident ? t("operator.statusChainPending") : null)),
  });
  const kmLine = t("kmLine", {
    count: chain?.evidence?.knowledge_entries ?? 0,
  });
  const detail = !hasIncident
    ? t("notLinked")
    : t("detail", {
        providers: correlation?.provider_event_total ?? 0,
        direct: correlation?.direct_ref_total ?? 0,
        candidate: correlation?.candidate_total ?? 0,
        applied: correlation?.applied_link_total ?? 0,
      });
  const Icon = status === "verified" ? ShieldCheck : (status === "waiting" ? BellOff : SearchCheck);
  const OperatorIcon = operatorStatus === "needsHuman" || operatorStatus === "failed"
    ? TriangleAlert
    : (operatorStatus === "verified" ? ShieldCheck : SearchCheck);

  return (
    <div className="min-w-[280px] max-w-[340px]">
      <div className="flex flex-wrap gap-1.5">
        <span className={cn(
          "inline-flex items-center gap-1.5 border px-2 py-1 text-xs font-semibold",
          sourceFlowListClass(status)
        )}>
          <Icon className="h-3.5 w-3.5" aria-hidden="true" />
          {t(`statuses.${status}`)}
        </span>
        <span className={cn(
          "inline-flex items-center gap-1.5 border px-2 py-1 text-xs font-semibold",
          operatorFlowListClass(operatorStatus)
        )}>
          <OperatorIcon className="h-3.5 w-3.5" aria-hidden="true" />
          {t(`operator.statuses.${operatorStatus}`)}
        </span>
      </div>
      <p className="mt-1 truncate font-mono text-xs text-[#77736a]" title={detail}>
        {detail}
      </p>
      {shouldShowOperatorFallback && (
        <>
          <p className="mt-1 truncate text-xs font-semibold text-[#141413]" title={shortValue(outcomeSummary)}>
            {shortValue(outcomeSummary)}
          </p>
          <p className="mt-1 truncate font-mono text-xs text-[#9f2f25]" title={blockerLine}>
            {blockerLine}
          </p>
          <div className="mt-1 grid gap-0.5 font-mono text-[11px] leading-4 text-[#5f5b52]">
            <span className="truncate" title={mcpLine}>{mcpLine}</span>
            <span className="truncate" title={ansibleLine}>{ansibleLine}</span>
            <span className="truncate" title={kmLine}>{kmLine}</span>
          </div>
        </>
      )}
    </div>
  );
}

function RunRow({
  run,
  statusChain,
  sourceFlowLoading,
}: {
  run: Run;
  statusChain?: AwoooPStatusChain | null;
  sourceFlowLoading: boolean;
}) {
  const formattedDate = run.created_at
    ? new Date(run.created_at).toLocaleDateString("zh-TW", {
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
      })
    : "--";

  const cost = Number(run.cost_usd ?? 0);
  const incidentIds = linkedIncidentIds(run.remediation_summary);

  return (
    <tr className="border-b border-border hover:bg-accent/30 transition-colors">
      <td className="px-4 py-3">
        <Link
          href={`/awooop/runs/${run.run_id}?project_id=${encodeURIComponent(run.project_id)}` as never}
          className="font-mono text-xs text-brand-accent bg-brand-accent/10 px-2 py-1 rounded border border-brand-accent/20 hover:bg-brand-accent/15"
        >
          {run.run_id.slice(0, 8)}
        </Link>
      </td>
      <td className="px-4 py-3">
        <span className="font-mono text-sm text-muted-foreground">
          {run.project_id || "--"}
        </span>
      </td>
      <td className="px-4 py-3">
        <IncidentIdsCell run={run} />
      </td>
      <td className="px-4 py-3">
        <span className="font-mono text-sm text-muted-foreground">
          {run.agent_id || "--"}
        </span>
      </td>
      <td className="px-4 py-3">
        <RunStateBadge state={run.state} />
      </td>
      <td className="px-4 py-3">
        <RunLaneBadge state={run.state} />
      </td>
      <td className="px-4 py-3">
        <RemediationEvidenceCell summary={run.remediation_summary} />
      </td>
      <td className="px-4 py-3">
        <CallbackReplyCell summary={run.callback_reply_summary} />
      </td>
      <td className="px-4 py-3">
        <SourceFlowCell
          chain={statusChain}
          summary={run.remediation_summary}
          hasIncident={incidentIds.length > 0}
          loading={sourceFlowLoading}
        />
      </td>
      <td className="px-4 py-3">
        <ShadowBadge isShadow={run.is_shadow} />
      </td>
      <td className="px-4 py-3">
        <span className="flex items-center gap-1 text-sm font-mono text-muted-foreground">
          {run.step_count > 0 || cost > 0 ? (
            <>
              <Cpu className="w-3.5 h-3.5" aria-hidden="true" />
              {run.step_count.toLocaleString()} steps
              <span className="text-xs text-muted-foreground/60">
                (${cost.toFixed(4)})
              </span>
            </>
          ) : (
            "--"
          )}
        </span>
      </td>
      <td className="px-4 py-3">
        <span className="text-sm text-muted-foreground font-mono">
          {formattedDate}
        </span>
      </td>
    </tr>
  );
}

function SourceDossierCoveragePanel({
  coverage,
  error,
}: {
  coverage: DossierCoverageResponse | null;
  error: string | null;
}) {
  const t = useTranslations("awooop.sourceDossierCoverage");
  const summary = coverage?.summary;
  const providers = coverage?.providers ?? [];
  const latestAt = summary?.latest_received_at
    ? new Date(summary.latest_received_at).toLocaleTimeString("zh-TW", {
        hour: "2-digit",
        minute: "2-digit",
      })
    : "--";
  const metrics = [
    {
      label: t("metrics.sources"),
      value: summary?.source_count ?? 0,
      detail: t("details.latest", { time: latestAt }),
      className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
    },
    {
      label: t("metrics.refs"),
      value: summary?.source_ref_total ?? 0,
      detail: t("details.withRefs", { count: summary?.with_source_refs_total ?? 0 }),
      className: "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
    },
    {
      label: t("metrics.missingRefs"),
      value: summary?.missing_source_refs_total ?? 0,
      detail: t("details.missingEnvelope", {
        count: summary?.missing_source_envelope_total ?? 0,
      }),
      className: (summary?.missing_source_refs_total ?? 0) > 0
        ? "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]"
        : "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
    },
    {
      label: t("metrics.duplicates"),
      value: summary?.duplicate_total ?? 0,
      detail: t("details.redacted", { count: summary?.redacted_total ?? 0 }),
      className: "border-[#d8d3c7] bg-white text-[#5f5b52]",
    },
    {
      label: t("metrics.sentry"),
      value: summary?.sentry_ref_total ?? 0,
      detail: t("details.alertRefs", { count: summary?.alert_ref_total ?? 0 }),
      className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
    },
    {
      label: t("metrics.signoz"),
      value: summary?.signoz_ref_total ?? 0,
      detail: t("details.limit", { count: coverage?.limit ?? 0 }),
      className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
    },
  ];

  return (
    <section className="border border-[#e0ddd4] bg-white">
      <div className="flex flex-wrap items-center justify-between gap-3 border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
        <div className="flex items-center gap-2">
          <ListChecks className="h-4 w-4 text-[#1f5b9b]" aria-hidden="true" />
          <div>
            <h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
            <p className="text-xs text-[#77736a]">{t("subtitle")}</p>
          </div>
        </div>
        <span className="border border-[#9bb6d9] bg-[#eef5ff] px-2 py-0.5 text-xs font-semibold text-[#1f5b9b]">
          {t("total", { count: summary?.source_count ?? 0 })}
        </span>
      </div>

      {error ? (
        <div className="px-4 py-4 text-sm text-[#9f2f25]">
          {t("error", { error })}
        </div>
      ) : (
        <>
          <div className="grid gap-px bg-[#e0ddd4] md:grid-cols-3 xl:grid-cols-6">
            {metrics.map((item) => (
              <div key={item.label} className="bg-white px-4 py-3">
                <div className="flex items-start justify-between gap-3">
                  <div>
                    <p className="text-xs font-semibold text-[#77736a]">{item.label}</p>
                    <div className="mt-2 font-mono text-2xl font-semibold text-[#141413]">
                      {item.value}
                    </div>
                  </div>
                  <span
                    className={cn(
                      "flex h-8 w-8 items-center justify-center border",
                      item.className
                    )}
                  >
                    <SearchCheck className="h-4 w-4" aria-hidden="true" />
                  </span>
                </div>
                <p className="mt-2 text-xs leading-5 text-[#5f5b52]">{item.detail}</p>
              </div>
            ))}
          </div>

          {providers.length === 0 ? (
            <div className="px-4 py-4 text-sm text-[#5f5b52]">
              {t("empty")}
            </div>
          ) : (
            <div className="grid gap-px bg-[#eee9dd] md:grid-cols-2 xl:grid-cols-4">
              {providers.slice(0, 4).map((provider) => {
                const providerLatest = provider.latest_received_at
                  ? new Date(provider.latest_received_at).toLocaleTimeString("zh-TW", {
                      hour: "2-digit",
                      minute: "2-digit",
                    })
                  : "--";
                return (
                  <article key={provider.provider} className="bg-white px-4 py-3">
                    <div className="flex items-start justify-between gap-3">
                      <div className="min-w-0">
                        <p className="truncate font-mono text-xs font-semibold text-[#141413]">
                          {provider.provider}
                        </p>
                        <p className="mt-1 text-xs text-[#77736a]">
                          {t("provider.latest", { time: providerLatest })}
                        </p>
                      </div>
                      <span className="shrink-0 border border-[#d8d3c7] bg-[#faf9f3] px-2 py-0.5 font-mono text-xs text-[#5f5b52]">
                        {provider.total}
                      </span>
                    </div>
                    <div className="mt-3 grid grid-cols-2 gap-2 text-xs leading-5 text-[#5f5b52]">
                      <p>{t("provider.refs", { count: provider.source_ref_total })}</p>
                      <p>{t("provider.missing", { count: provider.missing_source_refs_total })}</p>
                      <p>{t("provider.redacted", { count: provider.redacted_total })}</p>
                      <p>{t("provider.duplicates", { count: provider.duplicate_total })}</p>
                    </div>
                  </article>
                );
              })}
            </div>
          )}
        </>
      )}
    </section>
  );
}

function recurrenceStateLabelKey(state?: string | null) {
  if (
    state === "pending" ||
    state === "running" ||
    state === "waiting_tool" ||
    state === "waiting_approval" ||
    state === "completed" ||
    state === "failed" ||
    state === "cancelled" ||
    state === "timeout"
  ) {
    return `states.${state}`;
  }
  return "states.unlinked";
}

function recurrenceRepairStatusLabelKey(status?: string | null) {
  if (
    status === "no_incident_link" ||
    status === "auto_repair_verified" ||
    status === "auto_repair_succeeded_unverified" ||
    status === "auto_repair_failed" ||
    status === "auto_repair_recorded" ||
    status === "manual_gate" ||
    status === "investigating" ||
    status === "run_completed_no_repair" ||
    status === "source_correlation_review" ||
    status === "no_repair_record"
  ) {
    return `repairStatuses.${status}`;
  }
  return "repairStatuses.no_repair_record";
}

function EventRecurrencePanel({
  recurrence,
  error,
}: {
  recurrence: EventRecurrenceResponse | null;
  error: string | null;
}) {
  const t = useTranslations("awooop.eventRecurrence");
  const summary = recurrence?.summary;
  const items = recurrence?.items ?? [];
  const latestAt = summary?.latest_received_at
    ? new Date(summary.latest_received_at).toLocaleTimeString("zh-TW", {
        hour: "2-digit",
        minute: "2-digit",
      })
    : "--";
  const metrics = [
    {
      label: t("metrics.groups"),
      value: summary?.recurrence_group_total ?? 0,
      detail: t("details.sourceEvents", { count: summary?.source_event_total ?? 0 }),
      className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
    },
    {
      label: t("metrics.recurrent"),
      value: summary?.recurrent_group_total ?? 0,
      detail: t("details.latest", { time: latestAt }),
      className: (summary?.recurrent_group_total ?? 0) > 0
        ? "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]"
        : "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
    },
    {
      label: t("metrics.duplicates"),
      value: summary?.duplicate_event_total ?? 0,
      detail: t("details.unlinked", { count: summary?.unlinked_event_total ?? 0 }),
      className: "border-[#d8d3c7] bg-white text-[#5f5b52]",
    },
    {
      label: t("metrics.linkedRuns"),
      value: summary?.linked_run_total ?? 0,
      detail: t("details.limit", { count: recurrence?.limit ?? 0 }),
      className: "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
    },
    {
      label: t("metrics.autoRepair"),
      value: summary?.auto_repair_linked_total ?? 0,
      detail: t("details.verifiedRepair", { count: summary?.verified_repair_group_total ?? 0 }),
      className: "border-[#b9a6d9] bg-[#f5f0ff] text-[#51358f]",
    },
    {
      label: t("metrics.sourceReview"),
      value: summary?.source_correlation_review_group_total ?? 0,
      detail: t("details.sourceReview", {
        count: summary?.source_correlation_review_group_total ?? 0,
      }),
      className: (summary?.source_correlation_review_group_total ?? 0) > 0
        ? "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]"
        : "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
    },
    {
      label: t("metrics.openWorkItems"),
      value: summary?.open_work_item_group_total ?? 0,
      detail: t("details.manualGates", { count: summary?.manual_gate_group_total ?? 0 }),
      className: (summary?.open_work_item_group_total ?? 0) > 0
        ? "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]"
        : "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
    },
  ];

  return (
    <section className="border border-[#e0ddd4] bg-white">
      <div className="flex flex-wrap items-center justify-between gap-3 border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
        <div className="flex items-center gap-2">
          <Activity className="h-4 w-4 text-[#8a5a08]" aria-hidden="true" />
          <div>
            <h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
            <p className="text-xs text-[#77736a]">{t("subtitle")}</p>
          </div>
        </div>
        <span className="border border-[#d9b36f] bg-[#fff7e8] px-2 py-0.5 text-xs font-semibold text-[#8a5a08]">
          {t("total", { count: items.length })}
        </span>
      </div>

      {error ? (
        <div className="px-4 py-4 text-sm text-[#9f2f25]">
          {t("error", { error })}
        </div>
      ) : (
        <>
          <div className="grid gap-px bg-[#e0ddd4] md:grid-cols-2 xl:grid-cols-7">
            {metrics.map((item) => (
              <div key={item.label} className="bg-white px-4 py-3">
                <div className="flex items-start justify-between gap-3">
                  <div>
                    <p className="text-xs font-semibold text-[#77736a]">{item.label}</p>
                    <div className="mt-2 font-mono text-2xl font-semibold text-[#141413]">
                      {item.value}
                    </div>
                  </div>
                  <span
                    className={cn(
                      "flex h-8 w-8 items-center justify-center border",
                      item.className
                    )}
                  >
                    <Activity className="h-4 w-4" aria-hidden="true" />
                  </span>
                </div>
                <p className="mt-2 text-xs leading-5 text-[#5f5b52]">{item.detail}</p>
              </div>
            ))}
          </div>

          {items.length === 0 ? (
            <div className="px-4 py-4 text-sm text-[#5f5b52]">
              {t("empty")}
            </div>
          ) : (
            <div className="grid gap-px bg-[#eee9dd] md:grid-cols-2 xl:grid-cols-3">
              {items.slice(0, 6).map((item) => {
                const latest = item.latest_received_at
                  ? new Date(item.latest_received_at).toLocaleTimeString("zh-TW", {
                      hour: "2-digit",
                      minute: "2-digit",
                    })
                  : "--";
                const stateKey = recurrenceStateLabelKey(item.latest_run_state);
                const stateLabel = t(stateKey as never);
                const repair = item.repair_summary;
                const workItem = item.work_item;
                const repairKey = recurrenceRepairStatusLabelKey(repair?.status);
                const repairLabel = t(repairKey as never);
                const runHref = item.latest_run_id
                  ? `/awooop/runs/${item.latest_run_id}?project_id=${encodeURIComponent(recurrence?.project_id ?? "awoooi")}`
                  : null;
                const workHref = workItem?.work_item_id
                  ? `/awooop/work-items?project_id=${encodeURIComponent(recurrence?.project_id ?? "awoooi")}&work_item_id=${encodeURIComponent(workItem.work_item_id)}${workItem.incident_id ? `&incident_id=${encodeURIComponent(workItem.incident_id)}` : ""}`
                  : null;

                return (
                  <article key={item.recurrence_key} className="bg-white px-4 py-3">
                    <div className="flex items-start justify-between gap-3">
                      <div className="min-w-0">
                        <p className="truncate font-mono text-xs font-semibold text-[#141413]">
                          {item.alertname || item.provider || item.latest_provider_event_id || item.recurrence_key}
                        </p>
                        <p className="mt-1 truncate text-xs text-[#77736a]">
                          {item.namespace || "--"} · {item.target_resource || "--"}
                        </p>
                      </div>
                      <span className="shrink-0 border border-[#d9b36f] bg-[#fff7e8] px-2 py-0.5 font-mono text-xs font-semibold text-[#8a5a08]">
                        {item.occurrence_total}
                      </span>
                    </div>
                    <div className="mt-3 grid grid-cols-2 gap-2 text-xs leading-5 text-[#5f5b52]">
                      <p>{t("item.latest", { time: latest })}</p>
                      <p>{t("item.duplicates", { count: item.duplicate_total })}</p>
                      <p>{t("item.refs", { count: item.source_ref_total })}</p>
                      <p>{t("item.linkedRuns", { count: item.linked_run_total })}</p>
                      <p>{t("item.stage", { stage: item.latest_stage || "--" })}</p>
                      <p>{t("item.incident", { incidentId: item.latest_incident_id || "--" })}</p>
                      <p>{t("item.repair", { status: repairLabel })}</p>
                    </div>
                    <div className="mt-3 flex flex-wrap items-center gap-2">
                      <span className="border border-[#d8d3c7] bg-[#faf9f3] px-2 py-0.5 text-xs font-semibold text-[#5f5b52]">
                        {stateLabel}
                      </span>
                      <span
                        className={cn(
                          "border px-2 py-0.5 text-xs font-semibold",
                          workItem?.status === "open"
                            ? "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]"
                            : repair?.status === "auto_repair_verified"
                              ? "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]"
                              : "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]"
                        )}
                      >
                        {repairLabel}
                      </span>
                      {runHref ? (
                        <Link
                          href={runHref as never}
                          className="inline-flex items-center gap-1.5 border border-[#d8d3c7] bg-white px-2 py-1 text-xs font-semibold text-[#2e2b26] hover:border-[#1f6feb] hover:bg-[#edf4ff] hover:text-[#0f4fa8]"
                        >
                          <SearchCheck className="h-3.5 w-3.5" aria-hidden="true" />
                          {t("item.openRun")}
                        </Link>
                      ) : (
                        <span className="text-xs text-[#77736a]">{t("item.noRun")}</span>
                      )}
                      {workHref ? (
                        <Link
                          href={workHref as never}
                          className="inline-flex items-center gap-1.5 border border-[#d8d3c7] bg-white px-2 py-1 text-xs font-semibold text-[#2e2b26] hover:border-[#1f6feb] hover:bg-[#edf4ff] hover:text-[#0f4fa8]"
                        >
                          <ListChecks className="h-3.5 w-3.5" aria-hidden="true" />
                          {t("item.openWorkItem")}
                        </Link>
                      ) : (
                        <span className="text-xs text-[#77736a]">{t("item.noWorkItem")}</span>
                      )}
                    </div>
                  </article>
                );
              })}
            </div>
          )}
        </>
      )}
    </section>
  );
}

function GroupedAlertEventsPanel({ events }: { events: PlatformEvent[] }) {
  return (
    <section className="border border-[#e0ddd4] bg-white">
      <div className="flex flex-wrap items-center justify-between gap-3 border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
        <div className="flex items-center gap-2">
          <BellOff className="h-4 w-4 text-[#8a5a08]" aria-hidden="true" />
          <div>
            <h3 className="text-sm font-semibold text-[#141413]">最近告警收斂</h3>
            <p className="text-xs text-[#77736a]">
              子告警不再洗 Telegram，改保留在 AwoooP 事件流
            </p>
          </div>
        </div>
        <span className="border border-[#d9b36f] bg-[#fff7e8] px-2 py-0.5 text-xs font-semibold text-[#8a5a08]">
          {events.length} 筆
        </span>
      </div>
      {events.length === 0 ? (
        <div className="px-4 py-4 text-sm text-[#5f5b52]">
          目前沒有近期收斂事件。若同組告警再次觸發，第二筆起會出現在這裡。
        </div>
      ) : (
        <div className="grid gap-px bg-[#eee9dd] md:grid-cols-2 xl:grid-cols-3">
          {events.slice(0, 6).map((event) => {
            const receivedAt = event.received_at
              ? new Date(event.received_at).toLocaleTimeString("zh-TW", {
                  hour: "2-digit",
                  minute: "2-digit",
                })
              : "--";
            return (
              <article key={event.event_id} className="bg-white px-4 py-3">
                <div className="flex items-start justify-between gap-3">
                  <div className="min-w-0">
                    <p className="truncate font-mono text-xs font-semibold text-[#141413]">
                      {event.provider_event_id.replace("alert-group:", "")}
                    </p>
                    <p className="mt-1 text-xs text-[#77736a]">
                      {event.project_id} · {receivedAt}
                    </p>
                  </div>
                  <span className="shrink-0 border border-[#d8d3c7] bg-[#faf9f3] px-2 py-0.5 text-xs text-[#5f5b52]">
                    internal
                  </span>
                </div>
                <p className="mt-3 line-clamp-3 whitespace-pre-line text-xs leading-5 text-[#5f5b52]">
                  {event.content_preview || "無摘要"}
                </p>
              </article>
            );
          })}
        </div>
      )}
    </section>
  );
}

function CallbackKmCompletionSummary({
  summary,
}: {
  summary?: KmStaleCompletionSummary | null;
}) {
  const t = useTranslations("awooop.callbackReply.events.kmCompletion");
  if (!summary) return null;

  const statusKey = normalizeKmCompletionStatus(summary.status);
  const related = Array.isArray(summary.related_items)
    ? summary.related_items[0]
    : null;
  const workItem = summary.work_item?.status === "open" ? summary.work_item : null;
  const triage = workItem?.triage ?? null;

  return (
    <div className="mt-3 border-t border-[#e0ddd4] pt-3">
      <div className="flex items-center gap-2">
        <ShieldCheck className="h-3.5 w-3.5 text-[#17602a]" aria-hidden="true" />
        <p className="text-xs font-semibold text-[#141413]">{t("title")}</p>
      </div>
      <div className="mt-2 grid gap-1 text-xs leading-5 text-[#5f5b52]">
        <p>
          {t("status", {
            status: t(`statuses.${statusKey}` as never),
          })}
        </p>
        <p>
          {t("counts", {
            ready: summary.ready_count ?? 0,
            blocked: summary.blocked_count ?? 0,
            completed: summary.completed_count ?? 0,
            failed: summary.failed_count ?? 0,
          })}
        </p>
        <p>
          {t("guardrail", {
            writesOnRead: String(summary.writes_on_read ?? false),
            batchWrite: String(summary.batch_writes_allowed ?? false),
            manualReview: String(summary.manual_review_required ?? true),
          })}
        </p>
        {related ? (
          <p className="truncate font-mono text-[#77736a]">
            {t("related", {
              entryId: related.entry_id ?? "--",
              readiness: related.readiness ?? "--",
              nextAction: related.next_action ?? "--",
            })}
          </p>
        ) : statusKey === "fetch_failed" ? (
          <p className="text-[#9f2f25]">
            {t("fetchFailed", { reason: summary.missing_reason ?? "--" })}
          </p>
        ) : (
          <p className="text-[#77736a]">{t("noRelated")}</p>
        )}
        {workItem?.work_item_href || workItem?.target_href ? (
          <Link
            href={(workItem.work_item_href ?? workItem.target_href) as never}
            className="mt-1 inline-flex w-fit items-center gap-1.5 border border-[#d8d3c7] bg-[#faf9f3] px-2 py-1 text-xs font-semibold text-[#2e2b26] hover:border-[#d97757] hover:text-[#8a4a2f]"
          >
            <SearchCheck className="h-3.5 w-3.5" aria-hidden="true" />
            {t("openWorkItem")}
          </Link>
        ) : null}
        {triage ? (
          <div className="mt-2 grid gap-1 text-xs text-[#5f5b52]">
            <p>
              {t("triageFlow", {
                stage: triage.flow_stage ?? "--",
                strategy: triage.matching_strategy ?? "--",
              })}
            </p>
            <p>
              {t("triageAgents", {
                lead: triage.ai_lead_agent ?? "--",
                support: triage.supporting_agents?.join(" / ") || "--",
              })}
            </p>
            <p>
              {t("triageAutomation", {
                state: triage.automation_state ?? "--",
                safe: String(triage.safe_to_auto_repair ?? false),
              })}
            </p>
            <p>
              {t("triageBlocker", {
                reason: triage.blocking_reason ?? "--",
              })}
            </p>
          </div>
        ) : null}
      </div>
    </div>
  );
}

function CallbackKmCompletionSnapshot({
  snapshot,
}: {
  snapshot?: KmStaleCompletionSummary | null;
}) {
  const t = useTranslations("awooop.callbackReply.events.kmCompletion");
  if (!snapshot) return null;

  const statusKey = normalizeKmCompletionStatus(snapshot.status);
  const triage = snapshot.triage ?? null;

  return (
    <div className="mt-3 border-t border-[#e0ddd4] pt-3">
      <div className="flex items-center gap-2">
        <ShieldCheck className="h-3.5 w-3.5 text-[#1f5b9b]" aria-hidden="true" />
        <p className="text-xs font-semibold text-[#141413]">
          {t("snapshotTitle")}
        </p>
      </div>
      <div className="mt-2 grid gap-1 text-xs leading-5 text-[#5f5b52]">
        <p>
          {t("snapshotStatus", {
            status: t(`statuses.${statusKey}` as never),
            ready: snapshot.ready_count ?? 0,
            blocked: snapshot.blocked_count ?? 0,
            completed: snapshot.completed_count ?? 0,
            failed: snapshot.failed_count ?? 0,
          })}
        </p>
        {triage ? (
          <>
            <p>
              {t("snapshotFlow", {
                stage: triage.flow_stage ?? "--",
                strategy: triage.matching_strategy ?? "--",
              })}
            </p>
            <p>
              {t("snapshotAutomation", {
                lead: triage.ai_lead_agent ?? "--",
                state: triage.automation_state ?? "--",
                safe: String(triage.safe_to_auto_repair ?? false),
                blocker: triage.blocking_reason ?? "--",
              })}
            </p>
          </>
        ) : null}
      </div>
    </div>
  );
}

function CallbackAwoooPStatusChainSnapshot({
  chain,
}: {
  chain?: AwoooPStatusChain | null;
}) {
  const t = useTranslations("awooop.callbackReply.events");
  if (!chain) return null;

  const mcpGateway = chain.mcp?.gateway ?? {};
  const topTool = chain.mcp?.top_tools?.[0];
  const execution = chain.execution ?? {};
  const ansible = execution.ansible ?? {};
  const correlation = chain.source_refs?.correlation;
  const providerSummary = ["sentry", "signoz"].map((provider) => {
    const item = correlation?.providers?.[provider];
    return `${provider} ${item?.direct_ref_total ?? 0}/${item?.candidate_total ?? 0}/${item?.applied_link_total ?? 0}`;
  }).join(" · ");

  return (
    <div className="mt-3 border-t border-[#e0ddd4] pt-3">
      <div className="flex items-center gap-2">
        <Activity className="h-3.5 w-3.5 text-[#1f5b9b]" aria-hidden="true" />
        <p className="text-xs font-semibold text-[#141413]">
          {t("awooopSnapshotTitle")}
        </p>
      </div>
      <AwoooPStatusChainPanel
        chain={chain}
        compact
        className="mt-2"
      />
      <div className="grid gap-px border border-t-0 border-[#e0ddd4] bg-[#e0ddd4] md:grid-cols-3">
        <p className="truncate bg-white px-3 py-2 font-mono text-xs text-[#5f5b52]" title={topTool?.tool_name ?? "--"}>
          {t("awooopSnapshotMcp", {
            total: mcpGateway.total ?? 0,
            success: mcpGateway.success ?? 0,
            failed: mcpGateway.failed ?? 0,
            blocked: mcpGateway.blocked ?? 0,
            topTool: topTool?.tool_name ?? "--",
          })}
        </p>
        <p className="truncate bg-white px-3 py-2 font-mono text-xs text-[#5f5b52]" title={execution.playbook_paths?.[0] ?? "--"}>
          {t("awooopSnapshotExecution", {
            executor: execution.latest_executor ?? "--",
            playbook: execution.playbook_paths?.[0] ?? "--",
            ansible: String(ansible.considered ?? false),
            candidates: ansible.candidate_count ?? 0,
          })}
        </p>
        <p className="truncate bg-white px-3 py-2 font-mono text-xs text-[#5f5b52]" title={providerSummary}>
          {t("awooopSnapshotSource", {
            status: correlation?.status ?? "--",
            direct: correlation?.direct_ref_total ?? 0,
            candidate: correlation?.candidate_total ?? 0,
            applied: correlation?.applied_link_total ?? 0,
            providers: providerSummary,
          })}
        </p>
      </div>
    </div>
  );
}

function formatCoveragePercent(value: number, total: number) {
  if (total <= 0) return "0%";
  return `${Math.round((value / total) * 100)}%`;
}

function normalizeCallbackAuditSnapshotStatus(statusValue?: string | null) {
  if (
    statusValue === "captured" ||
    statusValue === "partial" ||
    statusValue === "not_captured" ||
    statusValue === "no_callback"
  ) {
    return statusValue;
  }
  return "observed";
}

function CallbackReplyAuditSummaryPanel({
  summary,
}: {
  summary?: CallbackReplyAuditSummary | null;
}) {
  const t = useTranslations("awooop.callbackReply.events.summary");
  if (!summary) return null;

  const outboundTotal = summary.outbound_total ?? 0;
  const callbackTotal = summary.callback_total ?? 0;
  const snapshotStatus = normalizeCallbackAuditSnapshotStatus(summary.snapshot_status);
  const nextActionRaw = summary.next_action ?? "observed";
  const nextActionKey = (
    nextActionRaw === "none" ||
    nextActionRaw === "press_telegram_detail_or_history" ||
    nextActionRaw === "press_telegram_detail_or_history_after_rollout" ||
    nextActionRaw === "review_legacy_callback_snapshot_gap" ||
    nextActionRaw === "review_outbound_source_refs"
  ) ? nextActionRaw : "observed";
  const sourceRefCoverage = formatCoveragePercent(
    summary.outbound_trace_ref_total ?? summary.outbound_incident_ref_total ?? 0,
    outboundTotal
  );
  const formatShortDateTime = (value?: string | null) =>
    value
      ? new Date(value).toLocaleString("zh-TW", {
          month: "2-digit",
          day: "2-digit",
          hour: "2-digit",
          minute: "2-digit",
        })
      : "--";
  const formatPrefixGaps = (
    items?: Array<{
      prefix?: string | null;
      total?: number | null;
      recent_24h_total?: number | null;
      last_sent_at?: string | null;
    }>
  ) => (
    items ?? []
  ).slice(0, 3)
    .map((item) => {
      return t("outboundReplyMarkupTopPrefixItem", {
        prefix: item.prefix || "--",
        total: item.total ?? 0,
        recent: item.recent_24h_total ?? 0,
        last: formatShortDateTime(item.last_sent_at),
      });
    })
    .join(" / ") || "--";
  const topMissingIncidentPrefixes = formatPrefixGaps(
    summary.outbound_reply_markup_missing_incident_ref_top_prefixes
  );
  const topMissingTracePrefixes = formatPrefixGaps(
    summary.outbound_reply_markup_missing_trace_ref_top_prefixes
  );
  const snapshotCoverage = formatCoveragePercent(
    summary.callback_snapshot_captured_total ?? 0,
    callbackTotal
  );
  const latestCallback = formatShortDateTime(summary.latest_callback_at);
  const latestMissingTraceRef = formatShortDateTime(
    summary.outbound_reply_markup_missing_trace_ref_latest_sent_at
  );
  const latestMissingIncidentRef = formatShortDateTime(
    summary.outbound_reply_markup_missing_incident_ref_latest_sent_at
  );
  const traceGapStatusRaw =
    summary.outbound_reply_markup_trace_ref_gap_status ?? "observed";
  const traceGapStatusKey = (
    traceGapStatusRaw === "clean" ||
    traceGapStatusRaw === "active_gap" ||
    traceGapStatusRaw === "recent_backlog" ||
    traceGapStatusRaw === "legacy_backlog"
  ) ? traceGapStatusRaw : "observed";
  const traceGapNextActionRaw =
    summary.outbound_reply_markup_trace_ref_gap_next_action ?? "observed";
  const traceGapNextActionKey = (
    traceGapNextActionRaw === "none" ||
    traceGapNextActionRaw === "inspect_recent_outbound_source_refs" ||
    traceGapNextActionRaw === "watch_24h_decay" ||
    traceGapNextActionRaw === "backfill_or_archive_legacy_callbacks"
  ) ? traceGapNextActionRaw : "observed";
  const traceGapRecoveryStatusRaw =
    summary.outbound_reply_markup_trace_ref_gap_recovery_status ?? "observed";
  const traceGapRecoveryStatusKey = (
    traceGapRecoveryStatusRaw === "not_needed" ||
    traceGapRecoveryStatusRaw === "recovered_after_gap" ||
    traceGapRecoveryStatusRaw === "no_recovery_signal"
  ) ? traceGapRecoveryStatusRaw : "observed";
  const inboundStatusRaw =
    summary.inbound_callback_mirror_status ?? "no_callback_observed";
  const inboundStatusKey = (
    inboundStatusRaw === "capturing" ||
    inboundStatusRaw === "reply_only_gap" ||
    inboundStatusRaw === "no_callback_observed"
  ) ? inboundStatusRaw : "observed";
  const inboundNextActionRaw =
    summary.inbound_callback_next_action ??
    "press_any_telegram_callback_after_rollout";
  const inboundNextActionKey = (
    inboundNextActionRaw === "none" ||
    inboundNextActionRaw === "press_any_telegram_callback_after_rollout"
  ) ? inboundNextActionRaw : "observed";
  const traceRefAfterGapFirst = formatShortDateTime(
    summary.outbound_reply_markup_trace_ref_after_gap_first_sent_at
  );
  const traceRefAfterGapLatest = formatShortDateTime(
    summary.outbound_reply_markup_trace_ref_after_gap_latest_sent_at
  );
  const latestInboundCallback = formatShortDateTime(
    summary.inbound_callback_latest_at
  );
  const snapshotStatusLabel = t(`statuses.${snapshotStatus}` as never);
  const traceRecoveryStatusLabel = t(
    `traceGapRecoveryStatuses.${traceGapRecoveryStatusKey}` as never
  );
  const nextActionLabel = t(`nextActions.${nextActionKey}` as never);
  const inboundStatusLabel = t(`inboundStatuses.${inboundStatusKey}` as never);
  const inboundNextActionLabel = t(
    `inboundNextActions.${inboundNextActionKey}` as never
  );
  const snapshotClass = {
    captured: "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
    partial: "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
    not_captured: "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]",
    no_callback: "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]",
    observed: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
  }[snapshotStatus];

  return (
    <div className="border-b border-[#e0ddd4]">
      <div className="border-b border-[#d7e2f3] bg-[#f4f8ff] px-4 py-3">
        <p className="text-xs font-semibold text-[#1f5b9b]">
          {t("operatorVerdictTitle")}
        </p>
        <p className="mt-1 text-xs leading-5 text-[#354052]">
          {t("operatorVerdictDetail", {
            inboundStatus: inboundStatusLabel,
            inboundTotal: summary.inbound_callback_total ?? 0,
            inboundRecent24h: summary.inbound_callback_recent_24h_total ?? 0,
            snapshotStatus: snapshotStatusLabel,
            snapshotCoverage,
            traceRecoveryStatus: traceRecoveryStatusLabel,
            nextAction: nextActionLabel,
          })}
        </p>
      </div>
      <div className="grid gap-px bg-[#e0ddd4] md:grid-cols-2 xl:grid-cols-5">
      <div className="bg-white px-4 py-3">
        <p className="text-xs font-semibold text-[#77736a]">{t("outbound")}</p>
        <p className="mt-2 font-mono text-xl font-semibold text-[#141413]">
          {outboundTotal}
        </p>
        <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
          {t("outboundDetail", {
            sourceRefs: summary.outbound_source_refs_total ?? 0,
            traceRefs:
              summary.outbound_trace_ref_total ??
              summary.outbound_incident_ref_total ??
              0,
            incidentRefs: summary.outbound_incident_ref_total ?? 0,
            coverage: sourceRefCoverage,
          })}
        </p>
        <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
          {t("outboundReplyMarkupDetail", {
            replyMarkup: summary.outbound_reply_markup_total ?? 0,
            missingIncidentRefs:
              summary.outbound_reply_markup_missing_incident_ref_total ?? 0,
            missingTraceRefs:
              summary.outbound_reply_markup_missing_trace_ref_total ?? 0,
          })}
        </p>
        <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
          {t("outboundReplyMarkupTraceFreshness", {
            recent1h:
              summary.outbound_reply_markup_missing_trace_ref_recent_1h_total ??
              0,
            recent24h:
              summary.outbound_reply_markup_missing_trace_ref_recent_24h_total ??
              0,
            latest: latestMissingTraceRef,
          })}
        </p>
        <p className="mt-1 text-xs font-semibold leading-5 text-[#141413]">
          {t("outboundReplyMarkupTraceDecision", {
            status: t(`traceGapStatuses.${traceGapStatusKey}` as never),
            action: t(`traceGapNextActions.${traceGapNextActionKey}` as never),
          })}
        </p>
        <p className="mt-1 text-xs font-semibold leading-5 text-[#17602a]">
          {t("outboundReplyMarkupTraceRecovery", {
            status: t(
              `traceGapRecoveryStatuses.${traceGapRecoveryStatusKey}` as never
            ),
            count: summary.outbound_reply_markup_trace_ref_after_gap_total ?? 0,
            first: traceRefAfterGapFirst,
            latest: traceRefAfterGapLatest,
          })}
        </p>
        <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
          {t("outboundReplyMarkupIncidentFreshness", {
            recent1h:
              summary
                .outbound_reply_markup_missing_incident_ref_recent_1h_total ??
              0,
            recent24h:
              summary
                .outbound_reply_markup_missing_incident_ref_recent_24h_total ??
              0,
            latest: latestMissingIncidentRef,
          })}
        </p>
        <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
          {t("outboundReplyMarkupTraceTopPrefixes", {
            prefixes: topMissingTracePrefixes,
          })}
        </p>
        <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
          {t("outboundReplyMarkupTopPrefixes", {
            prefixes: topMissingIncidentPrefixes,
          })}
        </p>
      </div>
      <div className="bg-white px-4 py-3">
        <p className="text-xs font-semibold text-[#77736a]">{t("callbacks")}</p>
        <p className="mt-2 font-mono text-xl font-semibold text-[#141413]">
          {callbackTotal}
        </p>
        <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
          {t("callbackDetail", {
            detail: summary.callback_detail_total ?? 0,
            history: summary.callback_history_total ?? 0,
            incidents: summary.callback_incident_total ?? 0,
          })}
        </p>
        <p className="mt-1 text-xs font-semibold leading-5 text-[#1f5b9b]">
          {t("inboundCallbackDetail", {
            total: summary.inbound_callback_total ?? 0,
            recent24h: summary.inbound_callback_recent_24h_total ?? 0,
            latest: latestInboundCallback,
            status: inboundStatusLabel,
            action: inboundNextActionLabel,
          })}
        </p>
      </div>
      <div className="bg-white px-4 py-3">
        <p className="text-xs font-semibold text-[#77736a]">{t("snapshots")}</p>
        <span
          className={cn(
            "mt-2 inline-flex border px-2 py-0.5 text-xs font-semibold",
            snapshotClass
          )}
        >
          {snapshotStatusLabel}
        </span>
        <p className="mt-2 text-xs leading-5 text-[#5f5b52]">
          {t("snapshotDetail", {
            captured: summary.callback_snapshot_captured_total ?? 0,
            partial: summary.callback_snapshot_partial_total ?? 0,
            missing: summary.callback_snapshot_missing_total ?? 0,
            coverage: snapshotCoverage,
          })}
        </p>
      </div>
      <div className="bg-white px-4 py-3">
        <p className="text-xs font-semibold text-[#77736a]">{t("delivery")}</p>
        <p className="mt-2 font-mono text-xl font-semibold text-[#141413]">
          {summary.callback_failed_total ?? 0}
        </p>
        <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
          {t("deliveryDetail", {
            sent: summary.callback_sent_total ?? 0,
            fallback: (summary.callback_fallback_total ?? 0)
              + (summary.callback_rescue_total ?? 0),
            outboundFailed: summary.outbound_failed_total ?? 0,
          })}
        </p>
      </div>
      <div className="bg-white px-4 py-3">
        <p className="text-xs font-semibold text-[#77736a]">{t("next")}</p>
        <p className="mt-2 text-xs font-semibold leading-5 text-[#141413]">
          {nextActionLabel}
        </p>
        <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
          {t("latest", { time: latestCallback })}
        </p>
      </div>
      </div>
    </div>
  );
}

const AUTOMATION_FLOW_GATE_LABEL_KEYS: Record<string, string> = {
  alert_intake: "alert_intake",
  mcp_investigation: "mcp_investigation",
  approval_policy: "approval_policy",
  execution_recorded: "execution_recorded",
  repair_recorded: "repair_recorded",
  verification_recorded: "verification_recorded",
  knowledge_recorded: "knowledge_recorded",
  operator_visible: "operator_visible",
};

const AUTOMATION_FLOW_ACTION_KEYS: Record<string, string> = {
  repair_alert_intake_or_outbound_mirror: "repair_alert_intake_or_outbound_mirror",
  route_incident_to_mcp_gateway_and_evidence_collectors:
    "route_incident_to_mcp_gateway_and_evidence_collectors",
  resolve_pending_or_expired_human_gate: "resolve_pending_or_expired_human_gate",
  record_effective_execution_or_mark_manual_no_action:
    "record_effective_execution_or_mark_manual_no_action",
  write_auto_repair_execution_or_blocker_reason:
    "write_auto_repair_execution_or_blocker_reason",
  run_post_execution_verification: "run_post_execution_verification",
  write_km_or_learning_evidence: "write_km_or_learning_evidence",
  repair_timeline_or_operator_notification_visibility:
    "repair_timeline_or_operator_notification_visibility",
};

const AUTOMATION_FLOW_CLAIM_REASON_KEYS: Record<string, string> = {
  all_evaluated_incidents_auto_repaired_verified:
    "all_evaluated_incidents_auto_repaired_verified",
  some_incidents_are_not_auto_repaired_verified:
    "some_incidents_are_not_auto_repaired_verified",
};

function automationFlowStatusClass(status?: AutomationFlowStatus | null) {
  if (status === "passed") {
    return "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]";
  }
  if (status === "warning") {
    return "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]";
  }
  if (status === "blocked") {
    return "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]";
  }
  return "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]";
}

function automationFlowStatusFill(status?: AutomationFlowStatus | null) {
  if (status === "passed") return "bg-[#4f9d5f]";
  if (status === "warning") return "bg-[#c58a24]";
  if (status === "blocked") return "bg-[#c65145]";
  return "bg-[#b8b2a7]";
}

function automationFlowStatusSurface(status?: AutomationFlowStatus | null) {
  if (status === "passed") return "border-[#9bc7a4] bg-[#f4fbf5]";
  if (status === "warning") return "border-[#d9b36f] bg-[#fff8ea]";
  if (status === "blocked") return "border-[#e2a29b] bg-[#fff5f3]";
  return "border-[#d8d3c7] bg-[#faf9f3]";
}

function automationFlowStatusText(status?: AutomationFlowStatus | null) {
  if (status === "passed") return "text-[#17602a]";
  if (status === "warning") return "text-[#8a5a08]";
  if (status === "blocked") return "text-[#9f2f25]";
  return "text-[#5f5b52]";
}

function automationFlowStatusLabelKey(status?: AutomationFlowStatus | null) {
  if (
    status === "passed" ||
    status === "warning" ||
    status === "blocked" ||
    status === "no_data"
  ) {
    return `statuses.${status}`;
  }
  return "statuses.unknown";
}

function automationFlowStatusIcon(status?: AutomationFlowStatus | null) {
  if (status === "passed") return ShieldCheck;
  if (status === "warning") return TriangleAlert;
  if (status === "blocked") return AlertCircle;
  return SearchCheck;
}

function AutomationFlowGatePanel({
  summary,
  error,
}: {
  summary: AutomationQualitySummary | null;
  error: string | null;
}) {
  const t = useTranslations("awooop.runs.automationFlow");
  const flow = summary?.automation_flow_gates ?? null;
  const overallStatus = flow?.overall_status ?? "no_data";
  const OverallIcon = automationFlowStatusIcon(overallStatus);
  const cacheAge = Math.max(0, Math.round(summary?.cache?.age_seconds ?? 0));
  const cacheLabel = summary?.cache
    ? summary.cache.status === "hit"
      ? t("cacheHit", { age: cacheAge, ttl: summary.cache.ttl_seconds ?? 0 })
      : t("cacheMiss", { age: cacheAge, ttl: summary.cache.ttl_seconds ?? 0 })
    : null;
  const claimReady = Boolean(summary?.production_claim?.can_claim_full_auto_repair);
  const claimReason = summary?.production_claim?.reason ?? "unknown";
  const claimReasonKey = AUTOMATION_FLOW_CLAIM_REASON_KEYS[claimReason];
  const claimReasonLabel = claimReasonKey
    ? t(`claimReasons.${claimReasonKey}` as never)
    : claimReason;
  const gates = flow?.gates ?? [];
  const readiness = gates.length
    ? Math.round(gates.reduce((acc, gate) => acc + (gate.passed_percent ?? 0), 0) / gates.length)
    : 0;
  const statusCounts = gates.reduce(
    (acc, gate) => {
      if (gate.status === "passed") acc.passed += 1;
      else if (gate.status === "warning") acc.warning += 1;
      else if (gate.status === "blocked") acc.blocked += 1;
      return acc;
    },
    { passed: 0, warning: 0, blocked: 0 }
  );
  const blockedGates = gates.filter((gate) => gate.status === "blocked");
  const warningGates = gates.filter((gate) => gate.status === "warning");
  const firstAttentionGate = blockedGates[0] ?? warningGates[0] ?? null;
  const attentionGateLabelKey = firstAttentionGate
    ? AUTOMATION_FLOW_GATE_LABEL_KEYS[firstAttentionGate.gate]
    : null;
  const attentionActionKey = firstAttentionGate?.next_action
    ? AUTOMATION_FLOW_ACTION_KEYS[firstAttentionGate.next_action]
    : null;
  const attentionGateLabel = attentionGateLabelKey
    ? t(`gates.${attentionGateLabelKey}` as never)
    : firstAttentionGate?.gate ?? "--";
  const attentionActionLabel = attentionActionKey
    ? t(`actions.${attentionActionKey}` as never)
    : firstAttentionGate?.next_action ?? "--";

  return (
    <section id="automation-flow-gates" className="border border-[#e0ddd4] bg-white">
      <div className="flex flex-wrap items-center justify-between gap-3 border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
        <div className="flex items-center gap-2">
          <Waypoints className="h-4 w-4 text-[#1f5b9b]" aria-hidden="true" />
          <div>
            <h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
            <p className="text-xs text-[#77736a]">{t("subtitle")}</p>
          </div>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          {cacheLabel ? (
            <span className="border border-[#d8d3c7] bg-white px-2 py-0.5 text-xs font-semibold text-[#5f5b52]">
              {cacheLabel}
            </span>
          ) : null}
          <span
            className={cn(
              "inline-flex items-center gap-1.5 border px-2 py-0.5 text-xs font-semibold",
              automationFlowStatusClass(overallStatus)
            )}
          >
            <OverallIcon className="h-3.5 w-3.5" aria-hidden="true" />
            {t(automationFlowStatusLabelKey(overallStatus) as never)}
          </span>
        </div>
      </div>

      {error ? (
        <div className="px-4 py-4 text-sm text-[#9f2f25]">
          {t("error", { error })}
        </div>
      ) : !summary || !flow ? (
        <div className="px-4 py-4 text-sm text-[#5f5b52]">
          {t("empty")}
        </div>
      ) : (
        <>
          <div className="grid gap-px border-b border-[#e0ddd4] bg-[#e0ddd4] xl:grid-cols-[minmax(0,1.85fr)_minmax(330px,0.85fr)]">
            <div className="bg-white p-4">
              <div className="flex flex-wrap items-center justify-between gap-3">
                <div>
                  <p className="text-xs font-semibold uppercase tracking-[0.12em] text-[#77736a]">
                    {t("mapTitle")}
                  </p>
                  <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
                    {t("mapSubtitle")}
                  </p>
                </div>
                <div className="flex flex-wrap gap-1.5 text-xs">
                  {(["passed", "warning", "blocked"] as const).map((status) => (
                    <span
                      key={status}
                      className={cn(
                        "inline-flex items-center gap-1 border px-2 py-1 font-semibold",
                        automationFlowStatusClass(status)
                      )}
                    >
                      <span className={cn("h-2 w-2", automationFlowStatusFill(status))} />
                      {t("statusCount", {
                        status: t(automationFlowStatusLabelKey(status) as never),
                        count: statusCounts[status],
                      })}
                    </span>
                  ))}
                </div>
              </div>

              <div className="mt-4 overflow-x-auto pb-1">
                <div className="grid min-w-[920px] grid-cols-8 gap-px bg-[#d8d3c7]">
                  {gates.map((gate, index) => {
                    const StatusIcon = automationFlowStatusIcon(gate.status);
                    const gateLabelKey = AUTOMATION_FLOW_GATE_LABEL_KEYS[gate.gate];
                    const gateLabel = gateLabelKey
                      ? t(`gates.${gateLabelKey}` as never)
                      : gate.gate;
                    const passedPercent = Math.max(
                      0,
                      Math.min(100, Number.isFinite(gate.passed_percent) ? gate.passed_percent : 0)
                    );
                    return (
                      <div
                        key={gate.gate}
                        className={cn(
                          "relative min-h-[150px] border p-3",
                          automationFlowStatusSurface(gate.status)
                        )}
                      >
                        {index < gates.length - 1 ? (
                          <ArrowRight
                            className="absolute -right-3 top-1/2 z-10 h-5 w-5 -translate-y-1/2 bg-white text-[#77736a]"
                            aria-hidden="true"
                          />
                        ) : null}
                        <div className="flex items-start justify-between gap-2">
                          <span className="font-mono text-[11px] text-[#77736a]">
                            {String(index + 1).padStart(2, "0")}
                          </span>
                          <StatusIcon
                            className={cn("h-4 w-4", automationFlowStatusText(gate.status))}
                            aria-hidden="true"
                          />
                        </div>
                        <p className="mt-3 min-h-[34px] text-xs font-semibold leading-4 text-[#141413]">
                          {gateLabel}
                        </p>
                        <div className="mt-3 h-1.5 bg-white/80">
                          <div
                            className={cn("h-full", automationFlowStatusFill(gate.status))}
                            style={{ width: `${passedPercent}%` }}
                          />
                        </div>
                        <div className="mt-3 flex items-baseline justify-between gap-2">
                          <span className={cn("font-mono text-lg font-semibold", automationFlowStatusText(gate.status))}>
                            {passedPercent.toFixed(0)}%
                          </span>
                          <span className="text-[11px] font-semibold text-[#5f5b52]">
                            {t(automationFlowStatusLabelKey(gate.status) as never)}
                          </span>
                        </div>
                        <div className="mt-2 grid grid-cols-4 gap-px bg-[#e7e1d6] text-center font-mono text-[10px]">
                          <span className="bg-white px-1 py-1 text-[#17602a]">{gate.passed_total ?? 0}</span>
                          <span className="bg-white px-1 py-1 text-[#8a5a08]">{gate.warning_total ?? 0}</span>
                          <span className="bg-white px-1 py-1 text-[#9f2f25]">{gate.missing_total ?? 0}</span>
                          <span className="bg-white px-1 py-1 text-[#7d2018]">{gate.failed_total ?? 0}</span>
                        </div>
                      </div>
                    );
                  })}
                </div>
              </div>
            </div>

            <div className="bg-white p-4">
              <div
                className={cn(
                  "border p-4",
                  claimReady
                    ? "border-[#c8dfcb] bg-[#f4fbf5] text-[#17602a]"
                    : "border-[#eed2ce] bg-[#fff6f5] text-[#8f2c22]"
                )}
              >
                <div className="flex items-center gap-2 text-sm font-semibold">
                  {claimReady ? (
                    <ShieldCheck className="h-4 w-4" aria-hidden="true" />
                  ) : (
                    <AlertCircle className="h-4 w-4" aria-hidden="true" />
                  )}
                  <span>{claimReady ? t("claimReady") : t("claimBlocked")}</span>
                </div>
                <p className="mt-2 text-xs leading-5">{t("claimReason", { reason: claimReasonLabel })}</p>
              </div>

              <div className="mt-3 grid grid-cols-2 gap-px bg-[#e0ddd4]">
                {[
                  { label: t("metrics.evaluated"), value: flow.evaluated_total },
                  { label: t("metrics.verifiedRepair"), value: summary.verified_auto_repair_total ?? 0 },
                  { label: t("metrics.blockedGates"), value: blockedGates.length },
                  { label: t("metrics.readiness"), value: `${readiness}%` },
                ].map((item) => (
                  <div key={item.label} className="bg-white px-4 py-3">
                    <p className="text-[11px] font-semibold text-[#77736a]">{item.label}</p>
                    <p className="mt-1 font-mono text-2xl font-semibold text-[#141413]">{item.value}</p>
                  </div>
                ))}
              </div>

              <div className="mt-3 border border-[#e0ddd4] bg-[#faf9f3] p-3">
                <p className="text-xs font-semibold text-[#77736a]">{t("attentionTitle")}</p>
                <p className="mt-2 text-sm font-semibold text-[#141413]">{attentionGateLabel}</p>
                <p className="mt-1 text-xs leading-5 text-[#5f5b52]">
                  {t("attentionAction", { action: attentionActionLabel })}
                </p>
              </div>
            </div>
          </div>

          <div className="grid gap-px bg-[#e0ddd4] xl:grid-cols-[minmax(0,1.15fr)_minmax(320px,0.85fr)]">
            <div className="bg-white p-4">
              <div className="flex flex-wrap items-center justify-between gap-3">
                <p className="text-xs font-semibold uppercase tracking-[0.12em] text-[#77736a]">
                  {t("heatmapTitle")}
                </p>
                <div className="grid grid-cols-4 gap-px bg-[#e0ddd4] text-center text-[10px] font-semibold text-[#5f5b52]">
                  <span className="bg-white px-2 py-1">{t("heatmap.pass")}</span>
                  <span className="bg-white px-2 py-1">{t("heatmap.warn")}</span>
                  <span className="bg-white px-2 py-1">{t("heatmap.miss")}</span>
                  <span className="bg-white px-2 py-1">{t("heatmap.fail")}</span>
                </div>
              </div>
              <div className="mt-3 space-y-2">
                {gates.map((gate) => {
                  const gateLabelKey = AUTOMATION_FLOW_GATE_LABEL_KEYS[gate.gate];
                  const gateLabel = gateLabelKey
                    ? t(`gates.${gateLabelKey}` as never)
                    : gate.gate;
                  const total = Math.max(1, gate.evaluated_total ?? 1);
                  const segments = [
                    { key: "pass", value: gate.passed_total ?? 0, className: "bg-[#4f9d5f]" },
                    { key: "warn", value: gate.warning_total ?? 0, className: "bg-[#c58a24]" },
                    { key: "miss", value: gate.missing_total ?? 0, className: "bg-[#c65145]" },
                    { key: "fail", value: gate.failed_total ?? 0, className: "bg-[#7d2018]" },
                  ];
                  return (
                    <div key={gate.gate} className="grid gap-2 md:grid-cols-[180px_minmax(0,1fr)_110px] md:items-center">
                      <div className="flex items-center gap-2">
                        <span className={cn("h-2.5 w-2.5", automationFlowStatusFill(gate.status))} />
                        <span className="text-xs font-semibold text-[#141413]">{gateLabel}</span>
                      </div>
                      <div className="flex h-4 overflow-hidden bg-[#ece7dc]">
                        {segments.map((segment) => (
                          <div
                            key={segment.key}
                            className={segment.className}
                            style={{ width: `${(segment.value / total) * 100}%` }}
                            title={`${segment.key}: ${segment.value}`}
                          />
                        ))}
                      </div>
                      <div className="grid grid-cols-4 gap-px bg-[#e0ddd4] text-center font-mono text-[10px]">
                        <span className="bg-white py-1 text-[#17602a]">{gate.passed_total ?? 0}</span>
                        <span className="bg-white py-1 text-[#8a5a08]">{gate.warning_total ?? 0}</span>
                        <span className="bg-white py-1 text-[#9f2f25]">{gate.missing_total ?? 0}</span>
                        <span className="bg-white py-1 text-[#7d2018]">{gate.failed_total ?? 0}</span>
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>

            <div className="bg-white p-4">
              <p className="text-xs font-semibold uppercase tracking-[0.12em] text-[#77736a]">
                {t("bottleneckTitle")}
              </p>
              <div className="mt-3 space-y-2">
                {(blockedGates.length ? blockedGates : warningGates).slice(0, 4).map((gate) => {
                  const gateLabelKey = AUTOMATION_FLOW_GATE_LABEL_KEYS[gate.gate];
                  const gateLabel = gateLabelKey
                    ? t(`gates.${gateLabelKey}` as never)
                    : gate.gate;
                  const actionKey = gate.next_action
                    ? AUTOMATION_FLOW_ACTION_KEYS[gate.next_action]
                    : null;
                  const actionLabel = actionKey
                    ? t(`actions.${actionKey}` as never)
                    : gate.next_action ?? "--";
                  const example = gate.examples?.[0];
                  return (
                    <div
                      key={gate.gate}
                      className={cn("border p-3", automationFlowStatusSurface(gate.status))}
                    >
                      <div className="flex items-start justify-between gap-3">
                        <p className="text-xs font-semibold text-[#141413]">{gateLabel}</p>
                        <span
                          className={cn(
                            "border px-2 py-0.5 text-[11px] font-semibold",
                            automationFlowStatusClass(gate.status)
                          )}
                        >
                          {t(automationFlowStatusLabelKey(gate.status) as never)}
                        </span>
                      </div>
                      <p className="mt-2 text-xs leading-5 text-[#5f5b52]">
                        {t("nextAction", { action: actionLabel })}
                      </p>
                      {example ? (
                        <p className="mt-2 truncate font-mono text-[11px] text-[#77736a]">
                          {example.incident_id ?? "--"} / {example.verdict ?? "--"}
                        </p>
                      ) : null}
                    </div>
                  );
                })}
              </div>
            </div>
          </div>
        </>
      )}
    </section>
  );
}

function CallbackReplyEvidencePanel({
  events,
  total,
  summary,
  cache,
  loading,
  error,
}: {
  events: CallbackReplyEvent[];
  total: number;
  summary?: CallbackReplyAuditSummary | null;
  cache?: OperatorSummaryCacheInfo | null;
  loading: boolean;
  error: string | null;
}) {
  const t = useTranslations("awooop.callbackReply.events");
  const tCallback = useTranslations("awooop.callbackReply");
  const cacheAge = Math.max(0, Math.round(cache?.age_seconds ?? 0));
  const cacheLabel = cache
    ? cache.status === "hit"
      ? t("cacheHit", { age: cacheAge, ttl: cache.ttl_seconds ?? 0 })
      : t("cacheMiss", { age: cacheAge, ttl: cache.ttl_seconds ?? 0 })
    : null;

  return (
    <section id="tg-callback-evidence" className="border border-[#e0ddd4] bg-white">
      <div className="flex flex-wrap items-center justify-between gap-3 border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
        <div className="flex items-center gap-2">
          <Send className="h-4 w-4 text-[#1f5b9b]" aria-hidden="true" />
          <div>
            <h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
            <p className="text-xs text-[#77736a]">{t("subtitle")}</p>
          </div>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          {cacheLabel ? (
            <span className="border border-[#d8d3c7] bg-white px-2 py-0.5 text-xs font-semibold text-[#5f5b52]">
              {cacheLabel}
            </span>
          ) : null}
          <span className="border border-[#9bb6d9] bg-[#eef5ff] px-2 py-0.5 text-xs font-semibold text-[#1f5b9b]">
            {t("total", { count: total })}
          </span>
        </div>
      </div>

      <CallbackReplyAuditSummaryPanel summary={summary} />

      {error ? (
        <div className="px-4 py-4 text-sm text-[#9f2f25]">
          {t("error", { error })}
        </div>
      ) : events.length > 0 ? (
        <div className="grid gap-px bg-[#eee9dd] md:grid-cols-2 xl:grid-cols-3">
          {events.slice(0, 6).map((event) => {
            const status = normalizeCallbackReplyEventStatus(event.status);
            const config = CALLBACK_REPLY_CONFIG[status];
            const eventTime = event.event_at
              ? new Date(event.event_at).toLocaleTimeString("zh-TW", {
                  hour: "2-digit",
                  minute: "2-digit",
                })
              : "--";
            const runHref = event.run_detail_href
              ?? `/awooop/runs/${event.run_id}?project_id=${encodeURIComponent(event.project_id)}`;

            return (
              <article key={event.message_id} className="bg-white px-4 py-3">
                <div className="flex items-start justify-between gap-3">
                  <div className="min-w-0">
                    <p className="truncate font-mono text-xs font-semibold text-[#141413]">
                      {event.run_id.slice(0, 8)}
                    </p>
                    <p className="mt-1 text-xs text-[#77736a]">
                      {event.project_id} · {eventTime}
                    </p>
                  </div>
                  <span
                    className={cn(
                      "shrink-0 border px-2 py-0.5 text-xs font-semibold",
                      config.className
                    )}
                    title={tCallback(config.detailKey)}
                  >
                    {tCallback(config.labelKey)}
                  </span>
                </div>
                <div className="mt-3 space-y-1 text-xs leading-5 text-[#5f5b52]">
                  <p>{t("action", { action: event.action ?? "--" })}</p>
                  <p className="font-mono">
                    {t("incident", { incidentId: event.incident_id ?? "--" })}
                  </p>
                  <p>{t("sendStatus", { status: event.send_status })}</p>
                  {event.provider_message_id && (
                    <p className="truncate font-mono text-[#77736a]">
                      {t("providerMessage", { messageId: event.provider_message_id })}
                    </p>
                  )}
                </div>
                <p className="mt-3 line-clamp-2 whitespace-pre-line text-xs leading-5 text-[#77736a]">
                  {event.content_preview || t("previewEmpty")}
                </p>
                <AwoooPStatusChainPanel
                  chain={event.awooop_status_chain}
                  compact
                  className="mt-3"
                />
                <CallbackEvidenceCaptureStatusPanel
                  captureStatus={event.evidence_capture_status}
                />
                <CallbackAwoooPStatusChainSnapshot
                  chain={event.persisted_awooop_status_chain}
                />
                <CallbackKmCompletionSummary
                  summary={event.km_stale_completion_summary}
                />
                <CallbackKmCompletionSnapshot
                  snapshot={event.persisted_km_stale_completion_summary}
                />
                <Link
                  href={runHref as never}
                  className="mt-3 inline-flex items-center gap-1.5 border border-[#d8d3c7] bg-[#faf9f3] px-2 py-1 text-xs font-semibold text-[#2e2b26] hover:border-[#1f6feb] hover:bg-[#edf4ff] hover:text-[#0f4fa8]"
                >
                  <SearchCheck className="h-3.5 w-3.5" aria-hidden="true" />
                  {t("openRun")}
                </Link>
              </article>
            );
          })}
        </div>
      ) : loading ? (
        <div className="px-4 py-4 text-sm text-[#5f5b52]">
          {t("loading")}
        </div>
      ) : (
        <div className="px-4 py-4 text-sm text-[#5f5b52]">
          {t("empty")}
        </div>
      )}
    </section>
  );
}

function aiRouteHealthLabelKey(status?: string | null) {
  if (
    status === "healthy" ||
    status === "slow" ||
    status === "degraded" ||
    status === "offline" ||
    status === "not_checked"
  ) {
    return `health.${status}`;
  }
  return "health.unknown";
}

function aiRouteRoleLabelKey(role?: string | null) {
  if (
    role === "primary" ||
    role === "secondary" ||
    role === "local_fallback" ||
    role === "final_fallback"
  ) {
    return `roles.${role}`;
  }
  return "roles.ollama";
}

function aiRouteLaneModeLabelKey(mode?: string | null) {
  if (
    mode === "primary" ||
    mode === "degraded_failover" ||
    mode === "cloud_fallback" ||
    mode === "unavailable"
  ) {
    return `laneModes.${mode}`;
  }
  return "laneModes.unknown";
}

function aiRouteOperatorActionLabelKey(action?: string | null) {
  if (
    action === "monitor" ||
    action === "repair_skipped_primary_lane" ||
    action === "restore_ollama_lanes" ||
    action === "inspect_ai_router"
  ) {
    return `operatorActions.${action}`;
  }
  return "operatorActions.unknown";
}

function aiRouteSummaryTone(mode?: string | null) {
  if (mode === "primary") {
    return "border-[#b8d8bd] bg-[#f0faf2] text-[#17602a]";
  }
  if (mode === "cloud_fallback" || mode === "unavailable") {
    return "border-[#e1aaa2] bg-[#fff3f1] text-[#9f2f25]";
  }
  return "border-[#d9b36f] bg-[#fff7e8] text-[#6d4707]";
}

function aiRouteStandbySummary(status: AiRouteStatusResponse) {
  const standby = status.policy_order
    .filter((item) => item.provider_name !== status.selected_provider)
    .map((item) => item.provider_name)
    .slice(0, 3)
    .join(" -> ");
  const skipped = (status.skipped_lanes ?? [])
    .map((lane) => lane.provider_name)
    .filter(Boolean)
    .join(" -> ");
  return { standby: standby || "--", skipped: skipped || "--" };
}

const AI_ROUTE_REPAIR_BLOCKER_KEYS = new Set([
  "gcloud_compute_instances_get_missing",
  "gcloud_compute_instances_list_missing",
  "gcloud_projects_get_iam_policy_missing",
  "gcp_a_ssh_refused",
  "gcp_a_ollama_11434_refused",
  "proxy_110_11435_http_502",
]);

const AI_ROUTE_REPAIR_PROBE_KEYS = new Set([
  "gcp_a_ping",
  "gcp_a_ssh_22",
  "gcp_a_direct_22",
  "gcp_a_direct_11434",
  "gcp_b_direct_11434",
  "proxy_110_11435",
  "proxy_110_11436",
  "proxy_110_11437",
]);

const AI_ROUTE_REPAIR_SIDE_EFFECT_KEYS = [
  "incident_created",
  "telegram_sent",
  "approval_created",
  "runtime_route_changed",
] as const;

function aiRouteRepairBlockerLabelKey(blocker?: string | null) {
  return blocker && AI_ROUTE_REPAIR_BLOCKER_KEYS.has(blocker)
    ? `repairEvidence.blockers.${blocker}`
    : "repairEvidence.blockers.unknown";
}

function aiRouteRepairProbeLabelKey(probe?: string | null) {
  return probe && AI_ROUTE_REPAIR_PROBE_KEYS.has(probe)
    ? `repairEvidence.probes.${probe}`
    : "repairEvidence.probes.unknown";
}

function compactEvidenceId(value?: string | null) {
  if (!value) return "--";
  return value.length > 18 ? `${value.slice(0, 12)}...` : value;
}

function AiRouteStatusPanel({
  status,
  error,
}: {
  status: AiRouteStatusResponse | null;
  error: string | null;
}) {
  const t = useTranslations("awooop.aiRouteStatus");
  const policy = status?.policy_order ?? [];
  const selectedProvider = status?.selected_provider ?? null;
  const selectedModel = status?.selected_model ?? null;
  const laneMode = status?.lane_mode ?? null;
  const laneModeKey = aiRouteLaneModeLabelKey(laneMode);
  const operatorActionKey = aiRouteOperatorActionLabelKey(status?.operator_action?.action);
  const repairEvidence = status?.repair_evidence ?? null;
  const repairBlockers = repairEvidence?.access_blockers?.filter(Boolean).slice(0, 4) ?? [];
  const repairProbes = Object.entries(repairEvidence?.live_probe ?? {}).slice(0, 6);
  const skippedLanes = status?.skipped_lanes ?? [];
  const routeSummary = status ? aiRouteStandbySummary(status) : { standby: "--", skipped: "--" };
  const skippedProviderSet = new Set(
    skippedLanes
      .map((lane) => lane.provider_name)
      .filter((provider): provider is string => Boolean(provider))
  );
  const checkedAt = status?.checked_at
    ? new Date(status.checked_at).toLocaleTimeString("zh-TW", {
        hour: "2-digit",
        minute: "2-digit",
      })
    : "--";
  const repairEvidenceAt = repairEvidence?.received_at
    ? new Date(repairEvidence.received_at).toLocaleTimeString("zh-TW", {
        hour: "2-digit",
        minute: "2-digit",
      })
    : "--";

  return (
    <section className="border border-[#e0ddd4] bg-white">
      <div className="flex flex-wrap items-center justify-between gap-3 border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
        <div className="flex items-center gap-2">
          <Cpu className="h-4 w-4 text-[#1f5b9b]" aria-hidden="true" />
          <div>
            <h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
            <p className="text-xs text-[#77736a]">{t("subtitle")}</p>
          </div>
        </div>
        <span
          className={cn(
            "border px-2 py-0.5 text-xs font-semibold",
            laneMode === "primary"
              ? "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]"
              : "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]"
          )}
        >
          {selectedProvider
            ? t("selected", { provider: selectedProvider })
            : t("selectedEmpty")}
        </span>
      </div>

      {error ? (
        <div className="px-4 py-4 text-sm text-[#9f2f25]">
          {t("error", { error })}
        </div>
      ) : !status ? (
        <div className="px-4 py-4 text-sm text-[#5f5b52]">
          {t("empty")}
        </div>
      ) : (
        <>
          <div className={cn(
            "border-b px-4 py-3 text-sm",
            aiRouteSummaryTone(laneMode)
          )}>
            <p className="font-semibold text-[#141413]">
              {laneMode === "primary"
                ? t("summary.primaryTitle", { provider: selectedProvider ?? "--" })
                : t("summary.fallbackTitle", { provider: selectedProvider ?? "--" })}
            </p>
            <p className="mt-1 leading-5">
              {laneMode === "primary"
                ? t("summary.primaryDetail", {
                    standby: routeSummary.standby,
                  })
                : t("summary.fallbackDetail", {
                    skipped: routeSummary.skipped,
                    action: t(operatorActionKey as never),
                  })}
            </p>
          </div>

          {laneMode && laneMode !== "primary" && (
            <div className="flex items-start gap-3 border-b border-[#e0ddd4] bg-[#fff7e8] px-4 py-3 text-sm text-[#6d4707]">
              <TriangleAlert className="mt-0.5 h-4 w-4 shrink-0" aria-hidden="true" />
              <div className="min-w-0">
                <p className="font-semibold text-[#141413]">
                  {t(laneModeKey as never)}
                </p>
                <p className="mt-1 leading-5">
                  {t("degradedSummary", {
                    active: selectedProvider ?? "--",
                    skipped: skippedLanes
                      .map((lane) => lane.provider_name)
                      .filter(Boolean)
                      .join(" -> ") || "--",
                    action: t(operatorActionKey as never),
                  })}
                </p>
              </div>
            </div>
          )}

          {repairEvidence && (
            <div className="border-b border-[#e0ddd4] bg-[#fbfcfb] px-4 py-4">
              <div className="flex flex-wrap items-start justify-between gap-3">
                <div className="flex min-w-0 items-center gap-2">
                  <SearchCheck className="h-4 w-4 shrink-0 text-[#17602a]" aria-hidden="true" />
                  <div className="min-w-0">
                    <p className="text-sm font-semibold text-[#141413]">
                      {t("repairEvidence.title")}
                    </p>
                    <p className="mt-1 truncate font-mono text-xs text-[#77736a]">
                      {repairEvidence.provider_event_id ?? "--"}
                    </p>
                  </div>
                </div>
                <span className="border border-[#cbdccf] bg-[#f0faf2] px-2 py-0.5 text-xs font-semibold text-[#17602a]">
                  {t("repairEvidence.sourceRefs", {
                    count: repairEvidence.source_ref_count ?? 0,
                  })}
                </span>
              </div>

              <div className="mt-4 grid gap-3 lg:grid-cols-3">
                <div className="border border-[#e0ddd4] bg-white px-3 py-3">
                  <p className="text-xs font-semibold text-[#77736a]">
                    {t("repairEvidence.meta")}
                  </p>
                  <div className="mt-2 space-y-1 text-xs leading-5 text-[#5f5b52]">
                    <p>
                      {t("repairEvidence.target", {
                        target: repairEvidence.target_resource ?? "--",
                      })}
                    </p>
                    <p>
                      {t("repairEvidence.run", {
                        run: compactEvidenceId(repairEvidence.run_id),
                      })}
                    </p>
                    <p>
                      {t("repairEvidence.receivedAt", {
                        time: repairEvidenceAt,
                      })}
                    </p>
                  </div>
                </div>

                <div className="border border-[#e0ddd4] bg-white px-3 py-3">
                  <p className="text-xs font-semibold text-[#77736a]">
                    {t("repairEvidence.blockerTitle")}
                  </p>
                  <div className="mt-2 flex flex-wrap gap-1.5">
                    {repairBlockers.length > 0 ? repairBlockers.map((blocker) => (
                      <span
                        key={blocker}
                        className="border border-[#d9b36f] bg-[#fff7e8] px-2 py-1 text-xs font-medium text-[#6d4707]"
                        title={blocker}
                      >
                        {AI_ROUTE_REPAIR_BLOCKER_KEYS.has(blocker)
                          ? t(aiRouteRepairBlockerLabelKey(blocker) as never)
                          : t("repairEvidence.blockers.unknown", { blocker })}
                      </span>
                    )) : (
                      <span className="text-xs text-[#77736a]">
                        {t("repairEvidence.emptyValue")}
                      </span>
                    )}
                  </div>
                </div>

                <div className="border border-[#e0ddd4] bg-white px-3 py-3">
                  <p className="text-xs font-semibold text-[#77736a]">
                    {t("repairEvidence.sideEffectTitle")}
                  </p>
                  <div className="mt-2 space-y-1 text-xs leading-5 text-[#5f5b52]">
                    {AI_ROUTE_REPAIR_SIDE_EFFECT_KEYS.map((key) => {
                      const value = repairEvidence.side_effects?.[key];
                      const valueKey = value === true
                        ? "repairEvidence.values.yes"
                        : value === false
                          ? "repairEvidence.values.no"
                          : "repairEvidence.values.unknown";
                      return (
                        <p key={key}>
                          {t(`repairEvidence.sideEffects.${key}` as never)}
                          {t("repairEvidence.sideEffectSeparator")}
                          {t(valueKey as never)}
                        </p>
                      );
                    })}
                  </div>
                </div>
              </div>

              {repairProbes.length > 0 && (
                <div className="mt-3 grid gap-px bg-[#e0ddd4] md:grid-cols-2 xl:grid-cols-3">
                  {repairProbes.map(([probe, value]) => (
                    <div key={probe} className="bg-white px-3 py-2 text-xs leading-5">
                      <p className="font-semibold text-[#141413]">
                        {AI_ROUTE_REPAIR_PROBE_KEYS.has(probe)
                          ? t(aiRouteRepairProbeLabelKey(probe) as never)
                          : t("repairEvidence.probes.unknown", { probe })}
                      </p>
                      <p className="mt-1 truncate font-mono text-[#77736a]" title={String(value ?? "--")}>
                        {String(value ?? "--")}
                      </p>
                    </div>
                  ))}
                </div>
              )}
            </div>
          )}

          <div className="grid gap-px bg-[#e0ddd4] md:grid-cols-4">
            <div className="bg-white px-4 py-3">
              <p className="text-xs font-semibold text-[#77736a]">{t("fields.workload")}</p>
              <p className="mt-2 font-mono text-sm font-semibold text-[#141413]">
                {status.workload_type || "--"}
              </p>
              <p className="mt-2 text-xs leading-5 text-[#5f5b52]">
                {t("fields.checkedAt", { time: checkedAt })}
              </p>
            </div>
            <div className="bg-white px-4 py-3">
              <p className="text-xs font-semibold text-[#77736a]">{t("fields.laneMode")}</p>
              <p className="mt-2 text-sm font-semibold text-[#141413]">
                {t(laneModeKey as never)}
              </p>
              <p className="mt-2 text-xs leading-5 text-[#5f5b52]">
                {t(operatorActionKey as never)}
              </p>
            </div>
            <div className="bg-white px-4 py-3">
              <p className="text-xs font-semibold text-[#77736a]">{t("fields.primary")}</p>
              <p className="mt-2 truncate font-mono text-sm font-semibold text-[#141413]">
                {selectedProvider ?? "--"}
              </p>
              <p className="mt-2 text-xs leading-5 text-[#5f5b52]">
                {selectedModel
                  ? t("fields.model", { model: selectedModel })
                  : t("fields.modelEmpty")}
              </p>
            </div>
            <div className="bg-white px-4 py-3">
              <p className="text-xs font-semibold text-[#77736a]">{t("fields.reason")}</p>
              <p className="mt-2 line-clamp-2 text-xs leading-5 text-[#5f5b52]">
                {status.route_error
                  ? t("fields.routeError", { error: status.route_error })
                  : status.route_reason || "--"}
              </p>
              <p className="mt-2 font-mono text-xs text-[#77736a]">
                {status.route_source}
              </p>
            </div>
          </div>

          <div className="grid gap-px bg-[#eee9dd] md:grid-cols-2 xl:grid-cols-4">
            {policy.map((item) => {
              const health = status.health?.[item.provider_name];
              const healthKey = aiRouteHealthLabelKey(health?.status);
              const roleKey = aiRouteRoleLabelKey(item.role);
              const isSelected = selectedProvider === item.provider_name;
              const isSkipped = skippedProviderSet.has(item.provider_name);
              const latency = typeof health?.latency_ms === "number"
                ? `${health.latency_ms.toFixed(1)}ms`
                : "--";

              return (
                <article key={`${item.priority}-${item.provider_name}`} className="bg-white px-4 py-3">
                  <div className="flex items-start justify-between gap-3">
                    <div className="min-w-0">
                      <p className="truncate font-mono text-xs font-semibold text-[#141413]">
                        {item.provider_name}
                      </p>
                      <p className="mt-1 text-xs text-[#77736a]">
                        {t(roleKey as never)}
                      </p>
                    </div>
                    <span
                      className={cn(
                        "shrink-0 border px-2 py-0.5 text-xs font-semibold",
                        isSelected
                          ? "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]"
                          : isSkipped
                            ? "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]"
                          : item.runtime === "cloud"
                            ? "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]"
                            : "border-[#d8d3c7] bg-[#faf9f3] text-[#5f5b52]"
                      )}
                    >
                      {isSelected
                        ? t("badges.active")
                        : isSkipped
                          ? t("badges.skipped")
                          : t("badges.standby")}
                    </span>
                  </div>
                  <div className="mt-3 space-y-1 text-xs leading-5 text-[#5f5b52]">
                    <p>{t("fields.health", { status: t(healthKey as never) })}</p>
                    <p>{t("fields.latency", { latency })}</p>
                    <p className="truncate font-mono text-[#77736a]">
                      {item.url || t("fields.noUrl")}
                    </p>
                    <p className="line-clamp-2 text-[#77736a]">
                      {health?.reason || item.reason || "--"}
                    </p>
                  </div>
                </article>
              );
            })}
          </div>
        </>
      )}
    </section>
  );
}

// =============================================================================
// Main Component
// =============================================================================

export default function RunsPage() {
  const tEvidence = useTranslations("awooop.listEvidence");
  const tCallback = useTranslations("awooop.callbackReply");
  const [runs, setRuns] = useState<Run[]>([]);
  const [groupedEvents, setGroupedEvents] = useState<PlatformEvent[]>([]);
  const [dossierCoverage, setDossierCoverage] = useState<DossierCoverageResponse | null>(null);
  const [dossierCoverageError, setDossierCoverageError] = useState<string | null>(null);
  const [eventRecurrence, setEventRecurrence] = useState<EventRecurrenceResponse | null>(null);
  const [eventRecurrenceError, setEventRecurrenceError] = useState<string | null>(null);
  const [callbackEvents, setCallbackEvents] = useState<CallbackReplyEvent[]>([]);
  const [callbackEventsTotal, setCallbackEventsTotal] = useState(0);
  const [callbackAuditSummary, setCallbackAuditSummary] = useState<CallbackReplyAuditSummary | null>(null);
  const [callbackEventsLoading, setCallbackEventsLoading] = useState(true);
  const [callbackCacheInfo, setCallbackCacheInfo] = useState<OperatorSummaryCacheInfo | null>(null);
  const [callbackEventsError, setCallbackEventsError] = useState<string | null>(null);
  const [aiRouteStatus, setAiRouteStatus] = useState<AiRouteStatusResponse | null>(null);
  const [aiRouteStatusError, setAiRouteStatusError] = useState<string | null>(null);
  const [automationQualitySummary, setAutomationQualitySummary] =
    useState<AutomationQualitySummary | null>(null);
  const [automationQualityError, setAutomationQualityError] = useState<string | null>(null);
  const [tenants, setTenants] = useState<Tenant[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [projectFilter, setProjectFilter] = useState<string>("");
  const [statusFilter, setStatusFilter] = useState<string>("");
  const [evidenceFilter, setEvidenceFilter] = useState<"" | RemediationStatus>("");
  const [callbackFilter, setCallbackFilter] = useState<"" | CallbackReplyStatus>("");
  const [incidentFilter, setIncidentFilter] = useState<string>("");
  const [page, setPage] = useState(1);
  const [lastRefresh, setLastRefresh] = useState<Date | null>(null);
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);

  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const linkedProject = params.get("project_id") || "";
    const linkedIncident = params.get("incident_id") || "";
    const linkedCallbackStatus = params.get("callback_reply_status") || "";
    if (linkedProject) setProjectFilter(linkedProject);
    if (linkedIncident) setIncidentFilter(linkedIncident);
    if (
      CALLBACK_REPLY_FILTER_OPTIONS.includes(
        linkedCallbackStatus as CallbackReplyStatus
      )
    ) {
      setCallbackFilter(linkedCallbackStatus as CallbackReplyStatus);
    }
    if (linkedProject || linkedIncident || linkedCallbackStatus) setPage(1);
  }, []);

  // 取得租戶清單
  useEffect(() => {
    fetch(`${API_BASE}/api/v1/platform/tenants`)
      .then((r) => r.json())
      .then((data) => {
        const rows = Array.isArray(data.tenants) ? data.tenants : data.items;
        setTenants(Array.isArray(rows) ? rows : []);
      })
      .catch(() => {});
  }, []);

  const fetchAiRouteStatus = useCallback(async () => {
    try {
      const routeStatusRes = await fetch(
        `${API_BASE}/api/v1/platform/ai-route-status?workload_type=deep_rca`
      );
      if (routeStatusRes.ok) {
        const routeStatusData: AiRouteStatusResponse = await routeStatusRes.json();
        setAiRouteStatus(routeStatusData);
        setAiRouteStatusError(null);
      } else {
        setAiRouteStatus(null);
        setAiRouteStatusError(`HTTP ${routeStatusRes.status}`);
      }
    } catch (routeStatusError) {
      setAiRouteStatus(null);
      setAiRouteStatusError(
        routeStatusError instanceof Error ? routeStatusError.message : "route status failed"
      );
    }
  }, []);

  const fetchRuns = useCallback(async (options?: { refresh?: boolean }) => {
    try {
      setError(null);
      const params = new URLSearchParams();
      if (projectFilter) params.set("project_id", projectFilter);
      if (statusFilter) params.set("state", statusFilter);
      if (evidenceFilter) params.set("remediation_status", evidenceFilter);
      if (callbackFilter) params.set("callback_reply_status", callbackFilter);
      const normalizedIncidentFilter = incidentFilter.trim().toUpperCase();
      if (INCIDENT_ID_FILTER_RE.test(normalizedIncidentFilter)) {
        params.set("incident_id", normalizedIncidentFilter);
      }
      params.set("page", String(page));
      params.set("per_page", String(PER_PAGE));

      const res = await fetch(
        `${API_BASE}/api/v1/platform/runs/list?${params.toString()}`
      );
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data: RunsResponse = await res.json();
      const rows = Array.isArray(data.runs) ? data.runs : data.items;
      setRuns(Array.isArray(rows) ? rows : []);
      setTotal(data.total ?? 0);

      const eventParams = new URLSearchParams();
      eventParams.set("channel_type", "internal");
      eventParams.set("provider_prefix", "alert-group");
      eventParams.set("limit", "6");
      if (projectFilter) eventParams.set("project_id", projectFilter);

      const eventsRes = await fetch(
        `${API_BASE}/api/v1/platform/events/recent?${eventParams.toString()}`
      );
      if (eventsRes.ok) {
        const eventsData: RecentEventsResponse = await eventsRes.json();
        setGroupedEvents(Array.isArray(eventsData.events) ? eventsData.events : []);
      }

      const dossierCoverageParams = new URLSearchParams();
      dossierCoverageParams.set("limit", "100");
      if (projectFilter) dossierCoverageParams.set("project_id", projectFilter);
      const dossierCoverageRes = await fetch(
        `${API_BASE}/api/v1/platform/events/dossier/coverage?${dossierCoverageParams.toString()}`
      );
      if (dossierCoverageRes.ok) {
        const dossierCoverageData: DossierCoverageResponse = await dossierCoverageRes.json();
        setDossierCoverage(dossierCoverageData);
        setDossierCoverageError(null);
      } else {
        setDossierCoverage(null);
        setDossierCoverageError(`HTTP ${dossierCoverageRes.status}`);
      }

      const recurrenceParams = new URLSearchParams();
      recurrenceParams.set("limit", "100");
      if (projectFilter) recurrenceParams.set("project_id", projectFilter);
      const recurrenceRes = await fetch(
        `${API_BASE}/api/v1/platform/events/dossier/recurrence?${recurrenceParams.toString()}`
      );
      if (recurrenceRes.ok) {
        const recurrenceData: EventRecurrenceResponse = await recurrenceRes.json();
        setEventRecurrence(recurrenceData);
        setEventRecurrenceError(null);
      } else {
        setEventRecurrence(null);
        setEventRecurrenceError(`HTTP ${recurrenceRes.status}`);
      }

      const callbackParams = new URLSearchParams();
      callbackParams.set("per_page", "6");
      if (projectFilter) callbackParams.set("project_id", projectFilter);
      if (callbackFilter) {
        callbackParams.set("callback_reply_status", callbackFilter);
      }
      if (INCIDENT_ID_FILTER_RE.test(normalizedIncidentFilter)) {
        callbackParams.set("incident_id", normalizedIncidentFilter);
      }
      if (options?.refresh) {
        callbackParams.set("refresh", "true");
      }
      setCallbackEventsLoading(true);
      try {
        const callbackRes = await fetch(
          `${API_BASE}/api/v1/platform/runs/callback-replies?${callbackParams.toString()}`
        );
        if (callbackRes.ok) {
          const callbackData: CallbackRepliesResponse = await callbackRes.json();
          setCallbackEvents(Array.isArray(callbackData.items) ? callbackData.items : []);
          setCallbackEventsTotal(callbackData.total ?? 0);
          setCallbackAuditSummary(callbackData.summary ?? null);
          setCallbackCacheInfo(callbackData.cache ?? null);
          setCallbackEventsError(null);
        } else {
          setCallbackEvents([]);
          setCallbackEventsTotal(0);
          setCallbackAuditSummary(null);
          setCallbackCacheInfo(null);
          setCallbackEventsError(`HTTP ${callbackRes.status}`);
        }
      } catch (callbackError) {
        setCallbackEvents([]);
        setCallbackEventsTotal(0);
        setCallbackAuditSummary(null);
        setCallbackCacheInfo(null);
        setCallbackEventsError(
          callbackError instanceof Error ? callbackError.message : "callback evidence failed"
        );
      } finally {
        setCallbackEventsLoading(false);
      }

      try {
        const qualityParams = new URLSearchParams();
        qualityParams.set("project_id", projectFilter || "awoooi");
        qualityParams.set("hours", "24");
        qualityParams.set("limit", "30");
        if (options?.refresh) {
          qualityParams.set("refresh", "true");
        }
        const qualityRes = await fetch(
          `${API_BASE}/api/v1/platform/truth-chain/quality/summary?${qualityParams.toString()}`
        );
        if (qualityRes.ok) {
          const qualityData: AutomationQualitySummary = await qualityRes.json();
          setAutomationQualitySummary(qualityData);
          setAutomationQualityError(null);
        } else {
          setAutomationQualitySummary(null);
          setAutomationQualityError(`HTTP ${qualityRes.status}`);
        }
      } catch (qualityError) {
        setAutomationQualitySummary(null);
        setAutomationQualityError(
          qualityError instanceof Error ? qualityError.message : "automation quality failed"
        );
      }

      setLastRefresh(new Date());
    } catch (err) {
      setError(err instanceof Error ? err.message : "載入失敗");
      setCallbackEventsLoading(false);
    } finally {
      setLoading(false);
    }
  }, [projectFilter, statusFilter, evidenceFilter, callbackFilter, incidentFilter, page]);

  // 初次載入
  useEffect(() => {
    setLoading(true);
    fetchAiRouteStatus();
    fetchRuns();
  }, [fetchAiRouteStatus, fetchRuns]);

  // 30 秒自動刷新
  useEffect(() => {
    intervalRef.current = setInterval(() => {
      fetchAiRouteStatus();
      fetchRuns();
    }, AUTO_REFRESH_INTERVAL);
    return () => {
      if (intervalRef.current) clearInterval(intervalRef.current);
    };
  }, [fetchAiRouteStatus, fetchRuns]);

  const totalPages = Math.ceil(total / PER_PAGE);
  const laneSummary = useMemo(() => {
    const counts: Record<RunLane, number> = {
      intake: 0,
      diagnosis: 0,
      approval: 0,
      execution: 0,
      done: 0,
      manual: 0,
    };
    runs.forEach((run) => {
      counts[getRunLane(run.state)] += 1;
    });
    return counts;
  }, [runs]);
  const evidenceSummary = useMemo(() => {
    return {
      readOnly: runs.filter(
        (run) => normalizeRemediationStatus(run.remediation_summary) === "read_only_dry_run"
      ).length,
      mcpObserved: runs.filter(
        (run) => normalizeRemediationStatus(run.remediation_summary) === "mcp_observed"
      ).length,
      writeObserved: runs.filter(
        (run) => normalizeRemediationStatus(run.remediation_summary) === "write_observed"
      ).length,
      noEvidence: runs.filter(
        (run) => normalizeRemediationStatus(run.remediation_summary) === "no_evidence"
      ).length,
      manualGate: runs.filter((run) => run.remediation_summary?.human_gate_open).length,
      callbackObserved: runs.filter(
        (run) => normalizeCallbackReplyStatus(run.callback_reply_summary) !== "no_callback"
      ).length,
      callbackFailed: runs.filter(
        (run) => normalizeCallbackReplyStatus(run.callback_reply_summary) === "failed"
      ).length,
    };
  }, [runs]);
  const runIncidentIds = useMemo(() => {
    return Array.from(new Set(
      runs.flatMap((run) => linkedIncidentIds(run.remediation_summary))
    ));
  }, [runs]);
  const {
    statusChains: runStatusChains,
    isLoading: runStatusChainsLoading,
  } = useIncidentStatusChains({
    incidentIds: runIncidentIds,
    projectId: projectFilter || "awoooi",
    refreshKey: lastRefresh?.toISOString() ?? null,
    limit: PER_PAGE,
  });

  return (
    <div className="space-y-6">
      {/* Page Header */}
      <div className="flex items-center justify-between flex-wrap gap-3">
        <div className="flex items-center gap-3">
          <Activity className="w-5 h-5 text-brand-accent" aria-hidden="true" />
          <div>
            <h2 className="text-lg font-semibold text-foreground">Run 監控</h2>
            <p className="text-xs text-muted-foreground">
              {loading
                ? "載入中..."
                : `共 ${total} 筆 · 上次更新 ${
                    lastRefresh ? lastRefresh.toLocaleTimeString("zh-TW") : "--"
                  }`}
            </p>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <span className="text-xs text-muted-foreground">每 30 秒自動刷新</span>
          <button
            onClick={() => {
              setLoading(true);
              fetchAiRouteStatus();
              fetchRuns({ refresh: true });
            }}
            disabled={loading}
            className="flex items-center gap-2 rounded-button px-3 py-2 text-sm text-muted-foreground transition hover:bg-accent hover:text-foreground disabled:opacity-50"
            aria-label="立即重新整理"
          >
            <RefreshCw className={cn("w-4 h-4", loading && "animate-spin")} aria-hidden="true" />
            立即刷新
          </button>
        </div>
      </div>

      <section className="grid gap-px border border-[#e0ddd4] bg-[#e0ddd4] md:grid-cols-3 xl:grid-cols-6">
        {(Object.keys(LANE_CONFIG) as RunLane[]).map((lane) => {
          const config = LANE_CONFIG[lane];
          const Icon = config.icon;
          return (
            <div key={lane} className="bg-white px-4 py-3">
              <div className="flex items-start justify-between gap-3">
                <div>
                  <p className="text-xs font-semibold text-[#77736a]">{config.label}</p>
                  <p className="mt-1 text-xs leading-5 text-[#5f5b52]">{config.detail}</p>
                </div>
                <Icon className="h-4 w-4 text-[#87867f]" aria-hidden="true" />
              </div>
              <div className="mt-3 font-mono text-2xl font-semibold text-[#141413]">
                {laneSummary[lane]}
              </div>
            </div>
          );
        })}
      </section>

      <section className="grid gap-px border border-[#e0ddd4] bg-[#e0ddd4] md:grid-cols-2 xl:grid-cols-6">
        {[
          {
            label: tEvidence("summary.mcpObserved"),
            value: evidenceSummary.mcpObserved,
            detail: tEvidence("summary.mcpObservedDetail"),
            icon: SearchCheck,
            className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
          },
          {
            label: tEvidence("summary.readOnly"),
            value: evidenceSummary.readOnly,
            detail: tEvidence("summary.readOnlyDetail"),
            icon: SearchCheck,
            className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
          },
          {
            label: tEvidence("summary.manualGate"),
            value: evidenceSummary.manualGate,
            detail: tEvidence("summary.manualGateDetail"),
            icon: ShieldCheck,
            className: "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
          },
          {
            label: tEvidence("summary.writeObserved"),
            value: evidenceSummary.writeObserved,
            detail: tEvidence("summary.writeObservedDetail"),
            icon: TriangleAlert,
            className: "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]",
          },
          {
            label: tEvidence("summary.callbackObserved"),
            value: evidenceSummary.callbackObserved,
            detail: tEvidence("summary.callbackObservedDetail", {
              failed: evidenceSummary.callbackFailed,
            }),
            icon: Send,
            className: evidenceSummary.callbackFailed > 0
              ? "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]"
              : "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
          },
          {
            label: tEvidence("summary.noEvidence"),
            value: evidenceSummary.noEvidence,
            detail: tEvidence("summary.noEvidenceDetail"),
            icon: AlertCircle,
            className: "border-[#d8d3c7] bg-white text-[#5f5b52]",
          },
        ].map((item) => {
          const Icon = item.icon;
          return (
            <div key={item.label} className="bg-white px-4 py-3">
              <div className="flex items-start justify-between gap-3">
                <div>
                  <p className="text-xs font-semibold text-[#77736a]">{item.label}</p>
                  <div className="mt-2 font-mono text-2xl font-semibold text-[#141413]">
                    {item.value}
                  </div>
                </div>
                <span
                  className={cn(
                    "flex h-8 w-8 items-center justify-center border",
                    item.className
                  )}
                >
                  <Icon className="h-4 w-4" aria-hidden="true" />
                </span>
              </div>
              <p className="mt-2 text-xs leading-5 text-[#5f5b52]">{item.detail}</p>
            </div>
          );
        })}
      </section>

      <AutomationFlowGatePanel
        summary={automationQualitySummary}
        error={automationQualityError}
      />

      <SecurityRunStateCandidatePanel />

      <GitHubRunReadinessBoundaryPanel />

      <OwnerResponseValidationRunBoundaryPanel />

      <AiRouteStatusPanel
        status={aiRouteStatus}
        error={aiRouteStatusError}
      />

      <SourceDossierCoveragePanel
        coverage={dossierCoverage}
        error={dossierCoverageError}
      />

      <EventRecurrencePanel
        recurrence={eventRecurrence}
        error={eventRecurrenceError}
      />

      <GroupedAlertEventsPanel events={groupedEvents} />

      <CallbackReplyEvidencePanel
        events={callbackEvents}
        total={callbackEventsTotal}
        summary={callbackAuditSummary}
        cache={callbackCacheInfo}
        loading={callbackEventsLoading}
        error={callbackEventsError}
      />

      {/* Filters */}
      <div className="flex flex-wrap items-center gap-3 border border-[#e0ddd4] bg-white p-4">
        <Filter className="w-4 h-4 text-muted-foreground flex-shrink-0" aria-hidden="true" />
        <span className="text-sm text-muted-foreground">篩選：</span>

        {/* Project Filter */}
        <div className="relative">
          <select
            value={projectFilter}
            onChange={(e) => { setProjectFilter(e.target.value); setPage(1); }}
            className="appearance-none rounded-button border border-border bg-background py-1.5 pl-3 pr-8 text-sm text-foreground cursor-pointer focus:outline-none focus:ring-2 focus:ring-brand-accent/50"
            aria-label="選擇租戶"
          >
            <option value="">所有租戶</option>
            {tenants.map((t) => (
              <option key={t.project_id} value={t.project_id}>
                {t.display_name || t.project_id}
              </option>
            ))}
          </select>
          <ChevronDown className="absolute right-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground pointer-events-none" aria-hidden="true" />
        </div>

        {/* Status Filter */}
        <div className="relative">
          <select
            value={statusFilter}
            onChange={(e) => { setStatusFilter(e.target.value); setPage(1); }}
            className="appearance-none rounded-button border border-border bg-background py-1.5 pl-3 pr-8 text-sm text-foreground cursor-pointer focus:outline-none focus:ring-2 focus:ring-brand-accent/50"
            aria-label="選擇狀態"
          >
            <option value="">所有狀態</option>
            {(Object.keys(STATE_CONFIG) as RunState[]).map((s) => (
              <option key={s} value={s}>
                {STATE_CONFIG[s].label}
              </option>
            ))}
          </select>
          <ChevronDown className="absolute right-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground pointer-events-none" aria-hidden="true" />
        </div>

        {/* AI Evidence Filter */}
        <div className="relative">
          <select
            value={evidenceFilter}
            onChange={(e) => {
              setEvidenceFilter(e.target.value as "" | RemediationStatus);
              setPage(1);
            }}
            className="appearance-none rounded-button border border-border bg-background py-1.5 pl-3 pr-8 text-sm text-foreground cursor-pointer focus:outline-none focus:ring-2 focus:ring-brand-accent/50"
            aria-label={tEvidence("filters.label")}
          >
            <option value="">{tEvidence("filters.all")}</option>
            {REMEDIATION_FILTER_OPTIONS.map((status) => (
              <option key={status} value={status}>
                {tEvidence(REMEDIATION_STATUS_CONFIG[status].labelKey)}
              </option>
            ))}
          </select>
          <ChevronDown className="absolute right-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground pointer-events-none" aria-hidden="true" />
        </div>

        {/* TG Callback Filter */}
        <div className="relative">
          <select
            value={callbackFilter}
            onChange={(e) => {
              setCallbackFilter(e.target.value as "" | CallbackReplyStatus);
              setPage(1);
            }}
            className="appearance-none rounded-button border border-border bg-background py-1.5 pl-3 pr-8 text-sm text-foreground cursor-pointer focus:outline-none focus:ring-2 focus:ring-brand-accent/50"
            aria-label={tCallback("filters.label")}
          >
            <option value="">{tCallback("filters.all")}</option>
            {CALLBACK_REPLY_FILTER_OPTIONS.map((status) => (
              <option key={status} value={status}>
                {tCallback(CALLBACK_REPLY_CONFIG[status].labelKey)}
              </option>
            ))}
          </select>
          <ChevronDown className="absolute right-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground pointer-events-none" aria-hidden="true" />
        </div>

        {/* Incident Filter */}
        <input
          value={incidentFilter}
          onChange={(e) => {
            setIncidentFilter(e.target.value.trim().toUpperCase());
            setPage(1);
          }}
          className="min-w-[260px] rounded-button border border-border bg-background px-3 py-1.5 font-mono text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-brand-accent/50"
          aria-label={tEvidence("filters.incidentLabel")}
          placeholder={tEvidence("filters.incidentPlaceholder")}
        />
      </div>

      {/* Error State */}
      {error && (
        <div className="flex items-start gap-3 rounded-card border border-red-800/40 bg-red-900/20 p-4">
          <AlertCircle className="w-5 h-5 text-red-400 flex-shrink-0 mt-0.5" aria-hidden="true" />
          <div>
            <p className="text-sm font-medium text-red-300">無法載入 Run 資料</p>
            <p className="text-xs text-red-400 mt-1">{error}</p>
          </div>
        </div>
      )}

      {/* Table */}
      <div className="overflow-hidden border border-[#e0ddd4] bg-white shadow-[0_1px_4px_rgba(0,0,0,0.05)]">
        <div className="overflow-x-auto">
          <table className="w-full" role="table" aria-label="Run 清單">
            <thead>
              <tr className="border-b border-border bg-muted/50">
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  Run ID
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  Project ID
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  {tEvidence("incident.column")}
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  Agent
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  狀態
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  處置 Lane
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  {tEvidence("column")}
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  {tEvidence("callbackColumn")}
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  {tEvidence("sourceFlow.column")}
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  Shadow
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  成本 / Steps
                </th>
                <th className="text-left px-4 py-3 text-xs font-medium text-muted-foreground uppercase tracking-wider">
                  建立時間
                </th>
              </tr>
            </thead>
            <tbody>
              {loading ? (
                Array.from({ length: 8 }).map((_, i) => (
                  <tr key={i} className="border-b border-border">
                    {Array.from({ length: 12 }).map((_, j) => (
                      <td key={j} className="px-4 py-3">
                        <div className="h-5 bg-muted animate-pulse rounded w-20" />
                      </td>
                    ))}
                  </tr>
                ))
              ) : runs.length === 0 && !error ? (
                <tr>
                  <td colSpan={12} className="px-4 py-16 text-center">
                    <Activity className="w-10 h-10 text-muted-foreground/30 mx-auto mb-3" aria-hidden="true" />
                    <p className="text-sm text-muted-foreground">尚無 Run 資料</p>
                  </td>
                </tr>
              ) : (
                runs.map((run) => {
                  const incidentIds = linkedIncidentIds(run.remediation_summary);
                  const statusChain = incidentIds
                    .map((incidentId) => runStatusChains[incidentId])
                    .find((chain): chain is AwoooPStatusChain => Boolean(chain));
                  return (
                    <RunRow
                      key={run.run_id}
                      run={run}
                      statusChain={statusChain}
                      sourceFlowLoading={runStatusChainsLoading}
                    />
                  );
                })
              )}
            </tbody>
          </table>
        </div>

        {/* Pagination */}
        {totalPages > 1 && (
          <div className="flex items-center justify-between px-4 py-3 border-t border-border bg-muted/30">
            <span className="text-xs text-muted-foreground">
              第 {page} / {totalPages} 頁，共 {total} 筆
            </span>
            <div className="flex items-center gap-2">
              <button
                onClick={() => setPage((p) => Math.max(1, p - 1))}
                disabled={page <= 1 || loading}
                className="p-1.5 hover:bg-accent rounded transition disabled:opacity-50"
                aria-label="上一頁"
              >
                <ChevronLeft className="w-4 h-4" aria-hidden="true" />
              </button>
              <button
                onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
                disabled={page >= totalPages || loading}
                className="p-1.5 hover:bg-accent rounded transition disabled:opacity-50"
                aria-label="下一頁"
              >
                <ChevronRight className="w-4 h-4" aria-hidden="true" />
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
