import type {
  SystemInfo,
  SystemStatus,
  Recipe,
  RecipeCreate,
  RecipeUpdate,
  RecipeList,
  ProcessStatus,
  ProcessStartRequest,
  ProcessActionResponse,
  HardwareStatus,
  SafetyStatus,
  User,
  UserCreate,
  UserUpdate,
} from '../types'

// Mock data
const mockSystemInfo: SystemInfo = {
  name: 'Chocolate Tempering Machine',
  version: '2.0.0-mock',
  environment: 'mock',
  api_version: '1.0.0',
  features: {
    recipe_management: true,
    process_control: true,
    hardware_monitoring: false, // Disabled in mock mode
    safety_monitoring: true,
    user_management: true,
    real_time_monitoring: true,
  },
  endpoints: {
    recipes: '/api/v1/recipes',
    process: '/api/v1/process',
    hardware: '/api/v1/hardware',
    users: '/api/v1/users',
    system: '/api/v1/system',
    health: '/health',
  },
}

const mockSystemStatus: SystemStatus = {
  system_status: 'warning', // Warning due to mock mode
  process_status: 'idle',
  hardware_status: 'disconnected', // No hardware in mock mode
  safety_status: 'safe',
  active_alarms: 0,
  uptime_seconds: 3600,
  last_updated: new Date().toISOString(),
}

const mockRecipes: Recipe[] = [
  {
    id: 1,
    name: 'Dark Chocolate 70%',
    description: 'Premium dark chocolate tempering recipe',
    chocolate_type: 'dark',
    target_temperature_c: 31.0,
    heating_duration_min: 5,
    cooling_duration_min: 3,
    stirring_speed_rpm: 50,
    total_time_min: 10,
    is_active: true,
    created_at: '2024-01-01T00:00:00Z',
    updated_at: '2024-01-01T00:00:00Z',
  },
  {
    id: 2,
    name: 'Milk Chocolate',
    description: 'Creamy milk chocolate tempering recipe',
    chocolate_type: 'milk',
    target_temperature_c: 29.0,
    heating_duration_min: 4,
    cooling_duration_min: 2,
    stirring_speed_rpm: 45,
    total_time_min: 8,
    is_active: true,
    created_at: '2024-01-02T00:00:00Z',
    updated_at: '2024-01-02T00:00:00Z',
  },
  {
    id: 3,
    name: 'White Chocolate',
    description: 'Delicate white chocolate tempering recipe',
    chocolate_type: 'white',
    target_temperature_c: 28.0,
    heating_duration_min: 3,
    cooling_duration_min: 2,
    stirring_speed_rpm: 40,
    total_time_min: 7,
    is_active: true,
    created_at: '2024-01-03T00:00:00Z',
    updated_at: '2024-01-03T00:00:00Z',
  },
]

const mockProcessStatus: ProcessStatus = {
  session_id: null,
  recipe_id: null,
  recipe_name: null,
  status: 'idle',
  current_phase: null,
  started_at: null,
  duration_seconds: null,
  started_by: null,
  current_temperature: 22.5,
  target_temperature: null,
  temperature_error: null,
  error_count: 0,
  warning_count: 0,
  is_running: false,
}

const mockHardwareStatus: HardwareStatus = {
  connection_status: 'disconnected',
  modbus_status: 'offline',
  temperature_sensors: [
    {
      id: 'tank_bottom',
      name: 'Tank Bottom',
      current_temp_c: 22.5,
      status: 'normal',
      last_reading: new Date().toISOString(),
    },
    {
      id: 'tank_wall',
      name: 'Tank Wall',
      current_temp_c: 22.3,
      status: 'normal',
      last_reading: new Date().toISOString(),
    },
    {
      id: 'pump',
      name: 'Pump',
      current_temp_c: 22.1,
      status: 'normal',
      last_reading: new Date().toISOString(),
    },
    {
      id: 'fountain',
      name: 'Fountain',
      current_temp_c: 22.0,
      status: 'normal',
      last_reading: new Date().toISOString(),
    },
  ],
  motors: [
    {
      id: 'mixer',
      name: 'Mixer Motor',
      is_running: false,
      current_speed_rpm: 0,
      target_speed_rpm: 0,
      current_amps: 0,
      status: 'normal',
    },
    {
      id: 'pump',
      name: 'Pump Motor',
      is_running: false,
      current_speed_rpm: 0,
      target_speed_rpm: 0,
      current_amps: 0,
      status: 'normal',
    },
  ],
  last_communication: new Date().toISOString(),
}

const mockSafetyStatus: SafetyStatus = {
  overall_status: 'safe',
  emergency_stop_active: false,
  temperature_alarms: [],
  motor_alarms: [],
  system_alarms: [],
  active_alarm_count: 0,
}

const mockUsers: User[] = [
  {
    id: '1',
    username: 'admin',
    email: 'admin@example.com',
    role: 'admin',
    full_name: 'System Administrator',
    is_active: true,
    created_at: '2024-01-01T00:00:00Z',
    last_login: new Date().toISOString(),
  },
  {
    id: '2',
    username: 'operator',
    email: 'operator@example.com',
    role: 'operator',
    full_name: 'Machine Operator',
    is_active: true,
    created_at: '2024-01-01T00:00:00Z',
    last_login: '2024-01-15T08:30:00Z',
  },
]

// Helper function to simulate API delays
const delay = (ms: number = 500) => new Promise(resolve => setTimeout(resolve, ms))

// Mock API service class
class MockApiService {
  private recipes: Recipe[] = [...mockRecipes]
  private processStatus: ProcessStatus = { ...mockProcessStatus }
  private hardwareStatus: HardwareStatus = { ...mockHardwareStatus }

  // System endpoints
  async getSystemInfo(): Promise<SystemInfo> {
    await delay(300)
    return mockSystemInfo
  }

  async getSystemStatus(): Promise<SystemStatus> {
    await delay(200)
    return mockSystemStatus
  }

  async getHealthCheck(): Promise<{ status: string }> {
    await delay(100)
    return { status: 'healthy' }
  }

  // Recipe endpoints
  async getRecipes(params?: {
    skip?: number
    limit?: number
    active_only?: boolean
    search?: string
  }): Promise<RecipeList> {
    await delay(300)
    
    let filteredRecipes = [...this.recipes]
    
    if (params?.active_only) {
      filteredRecipes = filteredRecipes.filter(r => r.is_active)
    }
    
    if (params?.search) {
      const search = params.search.toLowerCase()
      filteredRecipes = filteredRecipes.filter(r => 
        r.name.toLowerCase().includes(search) || 
        (r.description && r.description.toLowerCase().includes(search))
      )
    }
    
    const skip = params?.skip || 0
    const limit = params?.limit || 10
    
    return {
      recipes: filteredRecipes.slice(skip, skip + limit),
      total: filteredRecipes.length,
      skip,
      limit,
    }
  }

  async getRecipe(id: number): Promise<Recipe> {
    await delay(200)
    const recipe = this.recipes.find(r => r.id === id)
    if (!recipe) {
      throw new Error(`Recipe with id ${id} not found`)
    }
    return recipe
  }

  async createRecipe(recipe: RecipeCreate): Promise<Recipe> {
    await delay(500)
    const newRecipe: Recipe = {
      ...recipe,
      id: Math.max(...this.recipes.map(r => r.id)) + 1,
      is_active: true,
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
    }
    this.recipes.push(newRecipe)
    return newRecipe
  }

  async updateRecipe(id: number, recipe: RecipeUpdate): Promise<Recipe> {
    await delay(500)
    const index = this.recipes.findIndex(r => r.id === id)
    if (index === -1) {
      throw new Error(`Recipe with id ${id} not found`)
    }
    
    this.recipes[index] = {
      ...this.recipes[index],
      ...recipe,
      updated_at: new Date().toISOString(),
    }
    
    return this.recipes[index]
  }

  async deleteRecipe(id: number): Promise<void> {
    await delay(300)
    const index = this.recipes.findIndex(r => r.id === id)
    if (index === -1) {
      throw new Error(`Recipe with id ${id} not found`)
    }
    this.recipes.splice(index, 1)
  }

  // Process control endpoints
  async getProcessStatus(): Promise<ProcessStatus> {
    await delay(200)
    // Simulate temperature fluctuations if process is running
    if (this.processStatus.is_running && this.processStatus.current_temperature !== null) {
      this.processStatus.current_temperature += (Math.random() - 0.5) * 0.2
    }
    return { ...this.processStatus }
  }

  async startProcess(request: ProcessStartRequest): Promise<ProcessActionResponse> {
    await delay(800)
    const recipe = this.recipes.find(r => r.id === request.recipe_id)
    if (!recipe) {
      throw new Error(`Recipe with id ${request.recipe_id} not found`)
    }
    
    this.processStatus = {
      ...this.processStatus,
      is_running: true,
      status: 'running',
      current_phase: 'heating',
      recipe_id: recipe.id,
      recipe_name: recipe.name,
      target_temperature: recipe.target_temperature_c,
      duration_seconds: 0,
      session_id: `mock-session-${Date.now()}`,
      started_at: new Date().toISOString(),
      started_by: request.user_id || 'mock-user',
    }
    
    return {
      success: true,
      message: `Started tempering process with recipe: ${recipe.name}`,
      session_id: this.processStatus.session_id!,
    }
  }

  async pauseProcess(): Promise<ProcessActionResponse> {
    await delay(300)
    this.processStatus.status = 'paused'
    return {
      success: true,
      message: 'Process paused successfully',
    }
  }

  async resumeProcess(): Promise<ProcessActionResponse> {
    await delay(300)
    this.processStatus.status = 'running'
    return {
      success: true,
      message: 'Process resumed successfully',
    }
  }

  async stopProcess(): Promise<ProcessActionResponse> {
    await delay(500)
    this.processStatus = {
      ...mockProcessStatus,
      session_id: null,
    }
    return {
      success: true,
      message: 'Process stopped successfully',
    }
  }

  async emergencyStop(): Promise<ProcessActionResponse> {
    await delay(100)
    this.processStatus = {
      ...mockProcessStatus,
      session_id: null,
      status: 'error',
    }
    return {
      success: true,
      message: 'Emergency stop activated',
    }
  }

  // Hardware endpoints
  async getHardwareStatus(): Promise<HardwareStatus> {
    await delay(300)
    return { ...this.hardwareStatus }
  }

  async getTemperatures(): Promise<any[]> {
    await delay(200)
    return this.hardwareStatus.temperature_sensors.map(sensor => ({
      sensor: sensor.id,
      temperature: sensor.current_temp_c,
      timestamp: new Date().toISOString(),
    }))
  }

  async getMotorStatus(): Promise<any[]> {
    await delay(200)
    return this.hardwareStatus.motors.map(motor => ({
      motor: motor.id,
      name: motor.name,
      is_running: motor.is_running,
      current_speed_rpm: motor.current_speed_rpm,
      target_speed_rpm: motor.target_speed_rpm,
      current_amps: motor.current_amps,
      status: motor.status,
    }))
  }

  async setMotorSpeed(motorId: string, speed: number): Promise<void> {
    await delay(400)
    const motor = this.hardwareStatus.motors.find(m => m.id === motorId)
    if (motor) {
      motor.target_speed_rpm = speed
      motor.current_speed_rpm = speed
      motor.is_running = speed > 0
    }
  }

  // Safety endpoints
  async getSafetyStatus(): Promise<SafetyStatus> {
    await delay(200)
    return mockSafetyStatus
  }

  async acknowledgeAlarm(_alarmId: string): Promise<void> {
    await delay(300)
    // Mock alarm acknowledgment
  }

  async clearAlarms(): Promise<void> {
    await delay(500)
    // Mock alarm clearing
  }

  // User management endpoints
  async getUsers(params?: {
    skip?: number
    limit?: number
    active_only?: boolean
  }): Promise<{ users: User[]; total: number }> {
    await delay(300)
    
    let filteredUsers = [...mockUsers]
    
    if (params?.active_only) {
      filteredUsers = filteredUsers.filter(u => u.is_active)
    }
    
    const skip = params?.skip || 0
    const limit = params?.limit || 10
    
    return {
      users: filteredUsers.slice(skip, skip + limit),
      total: filteredUsers.length,
    }
  }

  async getUser(id: string): Promise<User> {
    await delay(200)
    const user = mockUsers.find(u => u.id === id)
    if (!user) {
      throw new Error(`User with id ${id} not found`)
    }
    return user
  }

  async createUser(user: UserCreate): Promise<User> {
    await delay(500)
    const newUser: User = {
      ...user,
      id: (mockUsers.length + 1).toString(),
      is_active: true,
      created_at: new Date().toISOString(),
      last_login: undefined,
    }
    mockUsers.push(newUser)
    return newUser
  }

  async updateUser(id: string, user: UserUpdate): Promise<User> {
    await delay(500)
    const index = mockUsers.findIndex(u => u.id === id)
    if (index === -1) {
      throw new Error(`User with id ${id} not found`)
    }
    
    mockUsers[index] = {
      ...mockUsers[index],
      ...user,
    }
    
    return mockUsers[index]
  }

  async deleteUser(id: string): Promise<void> {
    await delay(300)
    const index = mockUsers.findIndex(u => u.id === id)
    if (index === -1) {
      throw new Error(`User with id ${id} not found`)
    }
    mockUsers.splice(index, 1)
  }

  // Authentication endpoints
  async login(username: string, password: string): Promise<{ access_token: string; token_type: string; user: User }> {
    await delay(800)
    
    // Mock authentication - accept any user from mockUsers with password "password"
    const user = mockUsers.find(u => u.username === username)
    if (!user || password !== 'password') {
      throw new Error('Invalid username or password')
    }
    
    const token = `mock-token-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
    
    // Store token
    localStorage.setItem('auth_token', token)
    
    return {
      access_token: token,
      token_type: 'bearer',
      user,
    }
  }

  async logout(): Promise<void> {
    await delay(200)
    localStorage.removeItem('auth_token')
  }

  async refreshToken(): Promise<{ access_token: string }> {
    await delay(300)
    const token = `mock-token-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
    localStorage.setItem('auth_token', token)
    return { access_token: token }
  }

  // Data export endpoints
  async exportProcessData(sessionId: string, format: 'csv' | 'json' = 'csv'): Promise<Blob> {
    await delay(1000)
    const mockData = format === 'csv' 
      ? 'timestamp,temperature,phase\n2024-01-01T00:00:00Z,25.0,heating\n2024-01-01T00:01:00Z,26.0,heating'
      : JSON.stringify({ session: sessionId, data: [] })
    
    return new Blob([mockData], { 
      type: format === 'csv' ? 'text/csv' : 'application/json' 
    })
  }

  async getProcessMetrics(_days: number = 30): Promise<any> {
    await delay(500)
    return {
      total_sessions: 42,
      successful_sessions: 38,
      average_duration: 3600,
      temperature_stability: 98.5,
      efficiency_rating: 94.2,
    }
  }
}

export const mockApi = new MockApiService()
