/**
 * Onboarding Service - Mirror backend onboarding endpoints
 * Frontend and backend step names now match directly!
 */
import { apiClient } from '../client';
import { UserProgress, UpdateStepRequest, SaveStepDraftRequest, StepDraftResponse } from '../types/onboarding';

// Backend onboarding steps (full list from backend - UPDATED to match refactored flow)
// NOTE: poi-detection removed - now happens automatically in background during tenant registration
export const BACKEND_ONBOARDING_STEPS = [
  'user_registered',          // Phase 0: User account created (auto-completed)
  'bakery-type-selection',    // Phase 1: Choose bakery type
  'setup',                    // Phase 2: Basic bakery setup and tenant creation
  'upload-sales-data',        // Phase 2b: File upload, validation, AI classification
  'inventory-review',         // Phase 2b: Review AI-detected products with type selection
  'initial-stock-entry',      // Phase 2b: Capture initial stock levels
  'product-categorization',   // Phase 2c: Advanced categorization (optional)
  'suppliers-setup',          // Phase 2d: Suppliers configuration
  'recipes-setup',            // Phase 3: Production recipes (optional)
  'quality-setup',            // Phase 3: Quality standards (optional)
  'team-setup',               // Phase 3: Team members (optional)
  'ml-training',              // Phase 4: AI model training
  'setup-review',             // Phase 4: Review all configuration
  'completion'                // Phase 4: Onboarding completed
];

// Frontend step order for navigation (excludes user_registered as it's auto-completed)
// NOTE: poi-detection removed - now happens automatically in background during tenant registration
export const FRONTEND_STEP_ORDER = [
  'bakery-type-selection',    // Phase 1: Choose bakery type
  'setup',                    // Phase 2: Basic bakery setup and tenant creation
  'upload-sales-data',        // Phase 2b: File upload and AI classification
  'inventory-review',         // Phase 2b: Review AI-detected products
  'initial-stock-entry',      // Phase 2b: Initial stock levels
  'product-categorization',   // Phase 2c: Advanced categorization (optional)
  'suppliers-setup',          // Phase 2d: Suppliers configuration
  'recipes-setup',            // Phase 3: Production recipes (optional)
  'quality-setup',            // Phase 3: Quality standards (optional)
  'team-setup',               // Phase 3: Team members (optional)
  'ml-training',              // Phase 4: AI model training
  'setup-review',             // Phase 4: Review configuration
  'completion'                // Phase 4: Onboarding completed
];

export class OnboardingService {
  private readonly baseUrl = '/auth/me/onboarding';

  async getUserProgress(userId: string): Promise<UserProgress> {
    // Backend uses current user from auth token, so userId parameter is ignored
    return apiClient.get<UserProgress>(`${this.baseUrl}/progress`);
  }

  async updateStep(userId: string, stepData: UpdateStepRequest): Promise<UserProgress> {
    // Backend uses current user from auth token, so userId parameter is ignored
    return apiClient.put<UserProgress>(`${this.baseUrl}/step`, stepData);
  }

  async markStepCompleted(
    userId: string, 
    stepName: string, 
    data?: Record<string, any>
  ): Promise<UserProgress> {
    // Backend uses current user from auth token, so userId parameter is ignored
    // Backend expects UpdateStepRequest format for completion
    const requestBody = {
      step_name: stepName,
      completed: true,
      data: data,
    };
    
    console.log(`🔄 API call to mark step "${stepName}" as completed:`, requestBody);
    
    try {
      const response = await apiClient.put<UserProgress>(`${this.baseUrl}/step`, requestBody);
      console.log(`✅ Step "${stepName}" marked as completed successfully:`, response);
      return response;
    } catch (error) {
      console.error(`❌ API error marking step "${stepName}" as completed:`, error);
      throw error;
    }
  }

  async resetProgress(userId: string): Promise<UserProgress> {
    // Note: Backend doesn't have a reset endpoint, this might need to be implemented
    // For now, we'll throw an error
    throw new Error('Reset progress functionality not implemented in backend');
  }

  async getStepDetails(stepName: string): Promise<{
    name: string;
    description: string;
    dependencies: string[];
    estimated_time_minutes: number;
  }> {
    // This endpoint doesn't exist in backend, we'll need to implement it or mock it
    throw new Error('getStepDetails functionality not implemented in backend');
  }

  async getAllSteps(): Promise<Array<{
    name: string;
    description: string;
    dependencies: string[];
    estimated_time_minutes: number;
  }>> {
    // This endpoint doesn't exist in backend, we'll need to implement it or mock it
    throw new Error('getAllSteps functionality not implemented in backend');
  }

  async getNextStep(): Promise<{ step: string; completed?: boolean }> {
    // This endpoint exists in backend
    return apiClient.get(`${this.baseUrl}/next-step`);
  }

  async canAccessStep(stepName: string): Promise<{ can_access: boolean; reason?: string }> {
    // This endpoint exists in backend
    return apiClient.get(`${this.baseUrl}/can-access/${stepName}`);
  }

  async completeOnboarding(): Promise<{ success: boolean; message: string }> {
    // This endpoint exists in backend
    return apiClient.post(`${this.baseUrl}/complete`);
  }

  /**
   * Helper method to mark a step as completed (now direct mapping)
   */
  async markStepAsCompleted(
    stepId: string, 
    data?: Record<string, any>
  ): Promise<UserProgress> {
    try {
      return await this.markStepCompleted('', stepId, data);
    } catch (error) {
      console.error(`Error marking step ${stepId} as completed:`, error);
      throw error;
    }
  }

  /**
   * Helper method to get the next step based on backend progress
   */
  async getNextStepId(): Promise<string> {
    try {
      const result = await this.getNextStep();
      return result.step || 'setup';
    } catch (error) {
      console.error('Error getting next step:', error);
      return 'setup';
    }
  }

  /**
   * Helper method to determine which step the user should resume from
   */
  async getResumeStep(): Promise<{ stepId: string; stepIndex: number }> {
    try {
      const progress = await this.getUserProgress('');

      // If fully completed, go to completion
      if (progress.fully_completed) {
        return { stepId: 'completion', stepIndex: FRONTEND_STEP_ORDER.indexOf('completion') };
      }

      // Get the current step from backend
      const currentStep = progress.current_step;

      // If current step is user_registered, start from setup
      const resumeStep = currentStep === 'user_registered' ? 'setup' : currentStep;

      // Find the step index in our frontend order
      let stepIndex = FRONTEND_STEP_ORDER.indexOf(resumeStep);
      if (stepIndex === -1) {
        stepIndex = 0; // Default to first step
      }

      return { stepId: FRONTEND_STEP_ORDER[stepIndex], stepIndex };
    } catch (error) {
      console.error('Error determining resume step:', error);
      return { stepId: 'setup', stepIndex: 0 };
    }
  }

  /**
   * Save in-progress step data without marking the step as complete.
   * This allows users to save their work and resume later.
   */
  async saveStepDraft(stepName: string, draftData: Record<string, any>): Promise<{ success: boolean }> {
    const requestBody: SaveStepDraftRequest = {
      step_name: stepName,
      draft_data: draftData,
    };

    console.log(`💾 Saving draft for step "${stepName}":`, draftData);

    try {
      const response = await apiClient.put<{ success: boolean }>(`${this.baseUrl}/step-draft`, requestBody);
      console.log(`✅ Draft saved for step "${stepName}"`);
      return response;
    } catch (error) {
      console.error(`❌ Error saving draft for step "${stepName}":`, error);
      throw error;
    }
  }

  /**
   * Get saved draft data for a specific step.
   * Returns null if no draft exists or the step is already completed.
   */
  async getStepDraft(stepName: string): Promise<StepDraftResponse> {
    console.log(`📖 Getting draft for step "${stepName}"`);

    try {
      const response = await apiClient.get<StepDraftResponse>(`${this.baseUrl}/step-draft/${stepName}`);
      if (response.draft_data) {
        console.log(`✅ Found draft for step "${stepName}":`, response.draft_data);
      } else {
        console.log(`ℹ️ No draft found for step "${stepName}"`);
      }
      return response;
    } catch (error) {
      console.error(`❌ Error getting draft for step "${stepName}":`, error);
      throw error;
    }
  }

  /**
   * Delete saved draft data for a specific step.
   * Called after step is completed to clean up draft data.
   */
  async deleteStepDraft(stepName: string): Promise<{ success: boolean }> {
    console.log(`🗑️ Deleting draft for step "${stepName}"`);

    try {
      const response = await apiClient.delete<{ success: boolean }>(`${this.baseUrl}/step-draft/${stepName}`);
      console.log(`✅ Draft deleted for step "${stepName}"`);
      return response;
    } catch (error) {
      console.error(`❌ Error deleting draft for step "${stepName}":`, error);
      throw error;
    }
  }
}

export const onboardingService = new OnboardingService();