import type {
  FallbackFailureType,
  JudgeResponseType,
  JudgeReviewDecision,
  MessageFeedback,
  MessageRole,
  RoutingMode,
  StreamEventType,
  VisibleProgressActorType,
  VisibleProgressStageStatus,
} from '@/enums';
import type { ResearchMode } from '@/enums/research-mode.enum';

export type ChatThread = {
  id: string;
  userId: string;
  title: string | null;
  routingMode: RoutingMode;
  lastProvider: string | null;
  lastModel: string | null;
  preferredProvider: string | null;
  preferredModel: string | null;
  contextPackIds: string[];
  isPinned: boolean;
  isArchived: boolean;
  systemPrompt: string | null;
  temperature: number | null;
  maxTokens: number | null;
  judgeEnabled: boolean;
  judgeModel: string | null;
  qualityThreshold: number | null;
  maxReRouteAttempts: number | null;
  // Integration V2 — per-thread toggles
  useMemory: boolean;
  useContext: boolean;
  createdAt: string;
  updatedAt: string;
  _count?: { messages: number };
};

export type ChatMessage = {
  id: string;
  threadId: string;
  role: MessageRole;
  content: string;
  provider: string | null;
  model: string | null;
  routingMode: RoutingMode | null;
  routerModel: string | null;
  usedFallback: boolean;
  inputTokens: number | null;
  outputTokens: number | null;
  feedback: MessageFeedback | null;
  latencyMs: number | null;
  metadata: Record<string, unknown> | null;
  createdAt: string;
};

export type JudgeReview = {
  version: 1;
  judgeDecision: JudgeReviewDecision;
  judgeModel: string;
  judgeDisplayName: string;
  judgeConfidence: number;
  judgeReasoning: string;
  judgeSummary: string;
  judgeResponse: string;
  judgeResponseType: JudgeResponseType;
  criticModel: string;
  criticDisplayName: string;
  criticFeedback: string[];
  criticScore: number;
  originalExecutionModel: string;
  originalExecutionDisplayName: string;
  originalAnswerSnapshot: string;
  revisedAnswer: string | null;
  escalatedAnswer: string | null;
  judgeLatencyMs: number;
  criticLatencyMs: number;
  judgeTotalLatencyMs: number;
  judgeMetadata: {
    category: string;
    recommendedChanges: string[];
  };
  judgeDialogAvailable: boolean;
  generatedAt: string;
};

export type CreateThreadRequest = {
  title?: string;
  systemPrompt?: string;
  temperature?: number;
  maxTokens?: number;
  preferredProvider?: string;
  preferredModel?: string;
  contextPackIds?: string[];
};
export type UpdateThreadRequest = {
  isPinned?: boolean;
  isArchived?: boolean;
  title?: string;
  systemPrompt?: string | null;
  temperature?: number | null;
  maxTokens?: number | null;
  preferredProvider?: string | null;
  preferredModel?: string | null;
  contextPackIds?: string[];
  judgeEnabled?: boolean;
  judgeModel?: string | null;
  qualityThreshold?: number | null;
  maxReRouteAttempts?: number | null;
  // Integration V2 — per-thread toggles
  useMemory?: boolean;
  useContext?: boolean;
};
export type CreateMessageRequest = {
  threadId: string;
  content: string;
  routingMode?: RoutingMode;
  provider?: string;
  model?: string;
  modelDisplayName?: string;
  fileIds?: string[];
  researchMode?: ResearchMode;
  researchProviderId?: string;
};

export type PinThreadParams = {
  id: string;
  isPinned: boolean;
};

export type ArchiveThreadParams = {
  id: string;
  isArchived: boolean;
};

export type UpdateThreadMutationParams = {
  id: string;
  data: UpdateThreadRequest;
};
export type SetFeedbackParams = {
  messageId: string;
  feedback: MessageFeedback | null;
};

export type ThreadsListResponse = {
  data: ChatThread[];
  meta: { total: number; page: number; limit: number; totalPages: number };
};
export type MessagesListResponse = {
  data: ChatMessage[];
  meta: { total: number; page: number; limit: number; totalPages: number };
};

export type StreamEvent = {
  eventId?: string;
  threadId: string;
  type: StreamEventType;
  sequence?: number;
  stageId?: string;
  status?: VisibleProgressStageStatus;
  createdAt?: string;
  content?: string;
  provider?: string;
  model?: string;
  error?: string;
  label?: string;
  description?: string;
  actorType?: VisibleProgressActorType;
  actorName?: string;
  failedProvider?: string;
  failedModel?: string;
  attempt?: number;
  totalCandidates?: number;
  nextProvider?: string;
  nextModel?: string;
  criticModel?: string;
  judgeModel?: string;
};

export type VisibleProgressStage = {
  id: string;
  type: StreamEventType;
  label: string;
  description?: string;
  actorType?: VisibleProgressActorType;
  actorName?: string;
  provider?: string;
  model?: string;
  status: VisibleProgressStageStatus;
  timestamp: number;
  sequence?: number;
  createdAt?: string;
};

export type SseConnection = {
  close: () => void;
};

export type FallbackAttemptInfo = {
  failedProvider: string;
  failedModel: string;
  error: string;
  attempt: number;
  totalCandidates: number;
  nextProvider?: string;
  nextModel?: string;
  timestamp: number;
  failureType?: FallbackFailureType;
};

export type UseEditableTitleReturn = {
  isEditing: boolean;
  editValue: string;
  setEditValue: (value: string) => void;
  isPending: boolean;
  startEditing: () => void;
  cancelEditing: () => void;
  saveTitle: () => void;
  handleKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
};

export type UseVirtualizedMessagesReturn = {
  messages: ChatMessage[];
  isLoading: boolean;
  isFetchingPreviousPage: boolean;
  isFetchingNextPage: boolean;
  hasPreviousPage: boolean;
  hasNextPage: boolean;
  fetchPreviousPage: () => void;
  fetchNextPage: () => void;
  totalCount: number;
  firstItemIndex: number;
};

export type JudgeModelOption = {
  value: string | null;
  label: string;
};

export type MessageRenderItem =
  | { kind: 'single'; message: ChatMessage }
  | { kind: 'parallel'; messages: ChatMessage[] };

export type ParallelExpandedMessage = {
  message: ChatMessage;
  isFastest: boolean;
};

export type UseVirtualizedThreadsReturn = {
  threads: ChatThread[];
  isLoading: boolean;
  isFetchingNextPage: boolean;
  hasNextPage: boolean;
  fetchNextPage: () => void;
  totalCount: number;
};
