/**
 * Workflow Engine Service
 * Handles document workflow execution and step management
 */

import {
  createDocumentWorkflow,
  getDocumentWorkflow,
  getWorkflowSteps,
  updateWorkflowStatus,
  updateWorkflowStepStatus,
  getPendingWorkflowsForUser,
  getWorkflowProgress,
} from '@the-order/database';
import { createDocumentAuditLog } from '@the-order/database';

export interface WorkflowStepResult {
  step_id: string;
  status: 'approved' | 'rejected';
  comments?: string;
}

/**
 * Execute workflow step
 */
export async function executeWorkflowStep(
  step_id: string,
  result: WorkflowStepResult,
  user_id: string
): Promise<void> {
  const step = await updateWorkflowStepStatus(step_id, result.status, result.comments);
  if (!step) {
    throw new Error('Workflow step not found');
  }

  // Get workflow to check if all steps are complete
  const workflow = await getDocumentWorkflow(step.workflow_id);
  if (!workflow) {
    throw new Error('Workflow not found');
  }

  const allSteps = await getWorkflowSteps(workflow.id);
  const allComplete = allSteps.every(
    (s) => s.status === 'approved' || s.status === 'rejected' || s.status === 'skipped'
  );

  if (allComplete) {
    // Determine overall workflow status
    const hasRejected = allSteps.some((s) => s.status === 'rejected');
    const finalStatus = hasRejected ? 'rejected' : 'completed';

    await updateWorkflowStatus(workflow.id, finalStatus);

    await createDocumentAuditLog({
      document_id: workflow.document_id,
      action: finalStatus === 'completed' ? 'approved' : 'rejected',
      performed_by: user_id,
      details: { workflow_id: workflow.id, workflow_type: workflow.workflow_type },
    });
  } else {
    // Move to next pending step
    const nextStep = allSteps.find((s) => s.status === 'pending');
    if (nextStep) {
      await updateWorkflowStepStatus(nextStep.id, 'in_progress');
    }
  }
}

/**
 * Get user's pending workflows
 */
export async function getUserPendingWorkflows(
  user_id: string,
  role?: string
): Promise<Array<{
  step: any;
  workflow: any;
  document: any;
}>> {
  const steps = await getPendingWorkflowsForUser(user_id, role);

  // Enrich with workflow and document info
  const enriched = await Promise.all(
    steps.map(async (step) => {
      const workflow = await getDocumentWorkflow(step.workflow_id);
      if (!workflow) return null;

      const { getDocumentById } = await import('@the-order/database');
      const document = await getDocumentById(workflow.document_id);

      return {
        step,
        workflow,
        document,
      };
    })
  );

  return enriched.filter((e) => e !== null) as any[];
}

/**
 * Get workflow progress
 */
export async function getWorkflowProgressForDocument(
  document_id: string
): Promise<any> {
  const { getDocumentWorkflows } = await import('@the-order/database');
  const workflows = await getDocumentWorkflows(document_id);

  if (workflows.length === 0) {
    return null;
  }

  // Get progress for the most recent workflow
  const latestWorkflow = workflows[0];
  return getWorkflowProgress(latestWorkflow.id);
}

