/**
 * Workflow API module — TypeScript types and React Query hooks.
 * Matches backend endpoints from /api/v1/workflows.
 *
 * Backend: app/routes/workflows.py, app/models/workflow.py, app/schemas/workflow.py
 */

import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiGet, apiPost, apiPatch, apiDelete } from './client';
import type { PaginatedResponse } from './types';

// ── Types ──

export interface WorkflowStep {
  name: string;
  type: 'action' | 'approval' | 'notification' | 'condition';
  config: Record<string, unknown>;
  description?: string | null;
}

export interface Workflow {
  id: string;
  name: string;
  description?: string | null;
  trigger_event?: string | null;
  steps: WorkflowStep[];
  is_active: boolean;
  created_by?: string | null;
  created_at?: string | null;
  updated_at?: string | null;
}

export interface WorkflowListResponse extends PaginatedResponse<Workflow> {}

export interface WorkflowCreateInput {
  name: string;
  description?: string | null;
  trigger_event?: string | null;
  steps: WorkflowStep[];
  is_active?: boolean;
}

export interface WorkflowUpdateInput {
  name?: string;
  description?: string | null;
  trigger_event?: string | null;
  steps?: WorkflowStep[];
  is_active?: boolean;
}

export type InstanceStatus =
  | 'pending'
  | 'in_progress'
  | 'completed'
  | 'rejected'
  | 'cancelled';

export interface WorkflowInstance {
  id: string;
  workflow_id: string;
  status: InstanceStatus;
  current_step_index: number;
  context: Record<string, unknown>;
  initiated_by?: string | null;
  completed_at?: string | null;
  timeout_hours?: number | null;
  timeout_at?: string | null;
  created_at?: string | null;
  updated_at?: string | null;
}

export interface StepHistoryEntry {
  id: string;
  instance_id: string;
  step_index: number;
  step_type: string;
  action: string;
  actor_id?: string | null;
  details?: Record<string, unknown> | null;
  created_at?: string | null;
}

export interface WorkflowInstanceDetail extends WorkflowInstance {
  history: StepHistoryEntry[];
  workflow_name?: string | null;
}

export interface InstanceListResponse extends PaginatedResponse<WorkflowInstance> {}

export interface InstanceCreateInput {
  context?: Record<string, unknown>;
  timeout_hours?: number | null;
}

export interface AdvanceRequest {
  decision: 'approve' | 'reject';
  comment?: string | null;
}

// ── Workflow Definition Hooks ──

export function useWorkflows(page = 1, pageSize = 20, isActive?: boolean) {
  const params = new URLSearchParams({
    page: String(page),
    page_size: String(pageSize),
  });
  if (isActive !== undefined) params.set('is_active', String(isActive));
  return useQuery({
    queryKey: ['workflows', page, pageSize, isActive],
    queryFn: () =>
      apiGet<WorkflowListResponse>(`/workflows?${params.toString()}`),
  });
}

export function useWorkflow(id?: string) {
  return useQuery({
    queryKey: ['workflows', id],
    queryFn: () => apiGet<Workflow>(`/workflows/${id}`),
    enabled: !!id,
  });
}

export function useCreateWorkflow() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (data: WorkflowCreateInput) =>
      apiPost<Workflow>('/workflows', data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['workflows'] });
    },
  });
}

export function useUpdateWorkflow() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ({
      id,
      data,
    }: {
      id: string;
      data: WorkflowUpdateInput;
    }) => apiPatch<Workflow>(`/workflows/${id}`, data),
    onSuccess: (_data, variables) => {
      queryClient.invalidateQueries({ queryKey: ['workflows'] });
      queryClient.invalidateQueries({
        queryKey: ['workflows', variables.id],
      });
    },
  });
}

export function useDeleteWorkflow() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (id: string) => apiDelete(`/workflows/${id}`),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['workflows'] });
    },
  });
}

// ── Workflow Instance Hooks ──

export function useWorkflowInstances(
  page = 1,
  pageSize = 20,
  statusFilter?: InstanceStatus
) {
  const params = new URLSearchParams({
    page: String(page),
    page_size: String(pageSize),
  });
  if (statusFilter) params.set('status', statusFilter);
  return useQuery({
    queryKey: ['workflowInstances', page, pageSize, statusFilter],
    queryFn: () =>
      apiGet<InstanceListResponse>(
        `/workflows/instances?${params.toString()}`
      ),
  });
}

export function useWorkflowInstance(id?: string) {
  return useQuery({
    queryKey: ['workflowInstances', id],
    queryFn: () =>
      apiGet<WorkflowInstanceDetail>(`/workflows/instances/${id}`),
    enabled: !!id,
  });
}

export function useCreateWorkflowInstance() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ({
      workflowId,
      data,
    }: {
      workflowId: string;
      data: InstanceCreateInput;
    }) =>
      apiPost<WorkflowInstance>(
        `/workflows/${workflowId}/instances`,
        data
      ),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['workflowInstances'] });
    },
  });
}

export function useAdvanceWorkflowInstance() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ({
      instanceId,
      data,
    }: {
      instanceId: string;
      data: AdvanceRequest;
    }) =>
      apiPost<WorkflowInstance>(
        `/workflows/instances/${instanceId}/advance`,
        data
      ),
    onSuccess: (_data, variables) => {
      queryClient.invalidateQueries({ queryKey: ['workflowInstances'] });
      queryClient.invalidateQueries({
        queryKey: ['workflowInstances', variables.instanceId],
      });
    },
  });
}

export function useCancelWorkflowInstance() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (instanceId: string) =>
      apiPost<WorkflowInstance>(
        `/workflows/instances/${instanceId}/cancel`
      ),
    onSuccess: (_data, instanceId) => {
      queryClient.invalidateQueries({ queryKey: ['workflowInstances'] });
      queryClient.invalidateQueries({
        queryKey: ['workflowInstances', instanceId],
      });
    },
  });
}
