// TypeScript types mirroring the Rust API structs

/**
 * Object-variant form of a DataType as serialized by Rust serde.
 * Tuple variants like `Vec(T)` become `{"Vec": T}`, `Custom(s)` becomes `{"Custom": s}`.
 */
export type DataTypeMetaDataObject = { Vec: DataTypeMetaData } | { Custom: string };

/**
 * Raw DataType as received from the backend — either a plain string (unit variant)
 * or a JSON object (tuple variant). Mirrors the Rust `DataType` enum.
 *
 * Unit variants:  "Any" | "String" | "Integer" | "Float" | "Boolean" | "Json" | "Binary" |
 *                 "Password" | "MessageEvent" | "Sender" | "OpenAIMessage" | "QQMessage" | "FunctionTools" |
 *                 "BotAdapterRef" | "S3Ref" | "RedisRef" | "MySqlRef" | "TavilyRef" |
 *                 "SessionStateRef" | "OpenAIMessageSessionCacheRef" | "LLModel" | "LoopControlRef"
 * Tuple variants: { Vec: DataTypeMetaData } | { Custom: string }
 */
export type DataTypeMetaData = string | DataTypeMetaDataObject;

export interface PortInfo {
  name: string;
  data_type: string;
  description: string | null;
  required: boolean;
  hidden: boolean;
}

export interface NodeConfigFieldInfo {
  key: string;
  data_type: string;
  description: string | null;
  required: boolean;
  widget: string;
  connection_kind: string | null;
}

export interface NodeTypeInfo {
  type_id: string;
  display_name: string;
  category: string;
  description: string;
  input_ports: PortInfo[];
  output_ports: PortInfo[];
  has_dynamic_input_ports: boolean;
  has_dynamic_output_ports: boolean;
  is_event_producer: boolean;
  config_fields: NodeConfigFieldInfo[];
}

export interface RegistryResponse {
  types: NodeTypeInfo[];
  categories: string[];
}

export interface GraphPosition {
  x: number;
  y: number;
}

export interface GraphSize {
  width: number;
  height: number;
}

export interface Port {
  name: string;
  data_type: DataTypeMetaData;
  description: string | null;
  required: boolean;
  hidden?: boolean;
}

export interface PortBinding {
  kind: "hyperparameter" | "variable";
  name: string;
}

export interface NodeDefinition {
  id: string;
  name: string;
  description: string | null;
  node_type: string;
  input_ports: Port[];
  output_ports: Port[];
  dynamic_input_ports: boolean;
  dynamic_output_ports: boolean;
  position: GraphPosition | null;
  size: GraphSize | null;
  inline_values: Record<string, unknown>;
  port_bindings: Record<string, PortBinding>;
  has_error: boolean;
  has_cycle: boolean;
  disabled?: boolean;
}

export interface EdgeDefinition {
  from_node_id: string;
  from_port: string;
  to_node_id: string;
  to_port: string;
}

export interface HyperParameter {
  name: string;
  data_type: string;
  group: string;
  required: boolean;
  description: string | null;
}

export interface GraphVariable {
  name: string;
  data_type: DataTypeMetaData;
  initial_value: unknown | null;
}

export interface GraphMetadata {
  name: string | null;
  description: string | null;
  version: string | null;
}

export interface GraphPortDef {
  name: string;
  data_type: DataTypeMetaData;
  description?: string;
}

export interface NodeGraphDefinition {
  nodes: NodeDefinition[];
  edges: EdgeDefinition[];
  graph_inputs: GraphPortDef[];
  graph_outputs: GraphPortDef[];
  hyperparameter_groups: string[];
  hyperparameters: HyperParameter[];
  variables: GraphVariable[];
  metadata: GraphMetadata;
}

export interface GraphTabInfo {
  id: string;
  name: string;
  file_path: string | null;
  dirty: boolean;
  node_count: number;
  edge_count: number;
}

export interface ValidationIssue {
  severity: "error" | "warning";
  message: string;
}

export interface ValidationResult {
  issues: ValidationIssue[];
  cycle_nodes: string[];
  has_errors: boolean;
}

export interface TaskEntry {
  id: string;
  task_type: "node_graph" | "agent_service";
  graph_name: string;
  graph_session_id: string;
  file_path: string | null;
  is_workflow_set: boolean;
  start_time: string;
  is_running: boolean;
  end_time: string | null;
  duration_ms: number | null;
  user_ip: string | null;
  status: "running" | "success" | "failed" | "stopped";
  error_message: string | null;
  result_summary: string | null;
  log_path: string | null;
  can_rerun: boolean;
}

export interface TaskLogEntry {
  timestamp: string;
  level: string;
  message: string;
}

// WebSocket message types
import type { QQMessageItem } from "../ui/dialogs/types";

export type ServerMessage =
  | { type: "TaskStarted"; task_id: string; graph_name: string; graph_session_id: string }
  | { type: "TaskFinished"; task_id: string; success: boolean; error?: string }
  | { type: "TaskStopped"; task_id: string }
  | { type: "LogMessage"; level: string; message: string; timestamp: string }
  | { type: "GraphValidationResult"; graph_id: string; issues: ValidationIssue[] }
  | {
      type: "NodePreviewQQMessages";
      task_id: string;
      graph_session_id: string;
      node_id: string;
      messages: QQMessageItem[];
    };

export type ClientMessage =
  | { type: "Subscribe"; graph_id: string }
  | { type: "Unsubscribe"; graph_id: string }
  | { type: "Ping" };
