import { UserRole } from '../enums';

export interface RequestContext {
  correlationId: string;
  userId?: string;
  departmentId?: string;
  departmentCode?: string;
  role?: UserRole;
  ipAddress?: string;
  userAgent?: string;
}

export interface JwtPayload {
  sub: string;
  email?: string;
  role: UserRole;
  departmentCode?: string;
  iat?: number;
  exp?: number;
}

export interface ApiKeyPayload {
  departmentId: string;
  departmentCode: string;
}

export interface PaginatedResult<T> {
  data: T[];
  meta: {
    page: number;
    limit: number;
    total: number;
    totalPages: number;
    hasNext: boolean;
    hasPrev: boolean;
  };
}

export interface PaginationMetadata {
  page: number;
  limit: number;
  total: number;
  totalPages: number;
  hasNextPage: boolean;
  hasPreviousPage: boolean;
}

export interface WorkflowDefinition {
  workflowId: string;
  workflowType: string;
  version: number;
  isActive: boolean;
  stages: WorkflowStage[];
  createdAt: Date;
  updatedAt: Date;
}

export interface WorkflowStage {
  stageId: string;
  stageName: string;
  stageOrder: number;
  executionType: 'SEQUENTIAL' | 'PARALLEL';
  requiredApprovals: DepartmentApproval[];
  completionCriteria: 'ALL' | 'ANY' | 'THRESHOLD';
  threshold?: number;
  timeoutDays?: number;
  onTimeout: 'NOTIFY' | 'ESCALATE' | 'AUTO_REJECT';
  onRejection: 'FAIL_REQUEST' | 'RETRY_STAGE' | 'ESCALATE';
}

export interface DepartmentApproval {
  departmentCode: string;
  departmentName: string;
  requiredDocuments: string[];
  isMandatory: boolean;
}

export interface TimelineEvent {
  eventId: string;
  eventType: string;
  description: string;
  actor: {
    type: string;
    id?: string;
    name?: string;
  };
  metadata?: Record<string, unknown>;
  transactionHash?: string;
  timestamp: Date;
}

export interface WebhookPayload {
  event: string;
  timestamp: string;
  data: Record<string, unknown>;
  signature?: string;
}

export interface BlockchainReceipt {
  transactionHash: string;
  blockNumber: number;
  gasUsed: bigint;
  status: boolean;
}
