import { 
  InteractionWorkflow, 
  InteractionStep, 
  QuestionStep, 
  ConfirmationStep,
  ReviewStep,
  WorkflowResult 
} from './types.js';

export class InteractionManager {
  private workflows: Map<string, InteractionWorkflow> = new Map();

  createWorkflow(name: string, description: string, steps: InteractionStep[]): InteractionWorkflow {
    const workflow: InteractionWorkflow = {
      id: `workflow-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      name,
      description,
      steps,
      currentStep: 0,
      responses: {},
      state: 'active',
      createdAt: new Date(),
      updatedAt: new Date()
    };
    
    this.workflows.set(workflow.id, workflow);
    return workflow;
  }

  getWorkflow(workflowId: string): InteractionWorkflow | undefined {
    return this.workflows.get(workflowId);
  }

  getCurrentStep(workflowId: string): InteractionStep | undefined {
    const workflow = this.workflows.get(workflowId);
    if (!workflow || workflow.state !== 'active') return undefined;
    
    return workflow.steps[workflow.currentStep];
  }

  async processResponse(workflowId: string, response: any): Promise<{
    valid: boolean;
    message?: string;
    nextStep?: InteractionStep;
    completed?: boolean;
  }> {
    const workflow = this.workflows.get(workflowId);
    if (!workflow || workflow.state !== 'active') {
      return { valid: false, message: 'Workflow not found or inactive' };
    }

    const currentStep = workflow.steps[workflow.currentStep];
    
    // Validate response
    if (currentStep.validation) {
      const validationResult = currentStep.validation(response, workflow.responses);
      if (validationResult !== true) {
        return { 
          valid: false, 
          message: typeof validationResult === 'string' ? validationResult : 'Invalid response' 
        };
      }
    }

    // Store response
    workflow.responses[currentStep.id] = response;
    workflow.updatedAt = new Date();

    // Move to next step
    workflow.currentStep++;
    
    if (workflow.currentStep >= workflow.steps.length) {
      workflow.state = 'completed';
      return { valid: true, completed: true };
    }

    return { 
      valid: true, 
      nextStep: workflow.steps[workflow.currentStep],
      completed: false 
    };
  }

  completeWorkflow(workflowId: string): WorkflowResult | undefined {
    const workflow = this.workflows.get(workflowId);
    if (!workflow) return undefined;

    const result: WorkflowResult = {
      workflowId: workflow.id,
      completed: workflow.state === 'completed',
      responses: workflow.responses,
      finalData: this.compileFinalData(workflow)
    };

    // Clean up completed workflow
    this.workflows.delete(workflowId);
    
    return result;
  }

  cancelWorkflow(workflowId: string): boolean {
    const workflow = this.workflows.get(workflowId);
    if (!workflow) return false;

    workflow.state = 'cancelled';
    this.workflows.delete(workflowId);
    return true;
  }

  private compileFinalData(workflow: InteractionWorkflow): any {
    // Compile responses into final data structure
    // This can be customized based on workflow type
    return workflow.responses;
  }

  formatStepPrompt(step: InteractionStep): string {
    let prompt = step.prompt;
    
    if (step.helpText) {
      prompt += `\n\n💡 ${step.helpText}`;
    }

    if (step.type === 'question') {
      const questionStep = step as QuestionStep;
      
      if (questionStep.questionType === 'multipleChoice' && questionStep.options) {
        prompt += '\n\nOptions:';
        questionStep.options.forEach((option, index) => {
          prompt += `\n${index + 1}. ${option}`;
        });
      }
      
      if (questionStep.questionType === 'yesNo') {
        prompt += '\n\nPlease answer: Yes or No';
      }
      
      if (questionStep.required) {
        prompt += '\n\n⚠️ This field is required';
      }
      
      if (questionStep.defaultValue !== undefined) {
        prompt += `\n\nDefault: ${questionStep.defaultValue}`;
      }
    }

    if (step.type === 'confirmation') {
      const confirmStep = step as ConfirmationStep;
      prompt += '\n\n📋 Summary:';
      
      Object.entries(confirmStep.summary).forEach(([key, value]) => {
        const isEditable = confirmStep.editableFields?.includes(key);
        prompt += `\n${key}: ${value}${isEditable ? ' (editable)' : ''}`;
      });
      
      prompt += '\n\nDo you want to proceed with these settings? (Yes/No/Edit)';
    }

    if (step.type === 'review') {
      const reviewStep = step as ReviewStep;
      
      reviewStep.sections.forEach(section => {
        prompt += `\n\n### ${section.title}\n${section.content}`;
        if (section.editable) {
          prompt += ' ✏️';
        }
      });
    }

    return prompt;
  }
}