List<String> _mockInputQueue = [
  '1',        // Toggle Lights (OFF -> ON)
  '2',        // Choose Set Thermostat option
  '25.0',     // Set valid temperature (25.0°C - multiple of 5) -> "Warm Day"
  '3',        // Toggle Security System (DISARMED -> ARMED)
  '2',        // Choose Set Thermostat option again
  '21.0',     // Try to set valid temperature (21.0°C - multiple of 3) -> "Cool Day"
  '2',        // Choose Set Thermostat option again
  '15.0',     // Set valid temperature (15.0°C - multiple of 3 & 5) -> "Perfect Day"
  '2',        // Choose Set Thermostat option
  '10.0',     // Try to set invalid temperature (outside range)
  '4',        // View System Status (should show 15.0°C and "Perfect Day")
  '5',        // Exit the program
];
int _mockInputIndex = 0;

// Replaces stdin.readLineSync()
String _readInput() {
  if (_mockInputIndex < _mockInputQueue.length) {
    String input = _mockInputQueue[_mockInputIndex++];
    // Print the mock input to make the execution flow visible in the console.
    print('(Mock Input Received: "$input")');
    return input;
  }
  // If the mock input queue is exhausted, force an exit to prevent an infinite loop.
  print('(Mock Input Queue Exhausted, forcing exit)');
  return '5'; // Send '5' to trigger program exit
}

// Replaces stdout.write()
void _writeOutput(String message) {
  // Using 'print' as a substitute for stdout.write() in DartPad
  print(message);
}

// --- Device Classes for better state management ---

// A base class for on/off devices
class SmartDevice {
  final String name;
  bool isOn;

  SmartDevice(this.name, {this.isOn = false});

  // Toggles the device state and prints the change
  void toggle() {
    isOn = !isOn;
    // Requirement 6: Use string interpolation to show the new state
    print('$name is now ${isOn ? 'ON' : 'OFF'}.');
  }
}

// Class for the Thermostat with min/max bounds
class Thermostat {
  double temperature;
  // Requirement 7: Use const for constant values
  static const double minTemp = 15.0; // Minimum allowed temperature
  static const double maxTemp = 30.0; // Maximum allowed temperature

  Thermostat({this.temperature = 20.0}); // Default value 20°C

  // Input Validation and state update
  void setTemperature(double newTemp) {
    // Requirement 4 & 8: Use logical (&&) and relational (>=, <=) operators for validation
    if (newTemp >= minTemp && newTemp <= maxTemp) {
      temperature = newTemp;
      print('Thermostat set to ${temperature.toStringAsFixed(1)}°C.');
    } else {
      // Display error for invalid input
      print('Invalid temperature. Please choose a value between ${minTemp.toStringAsFixed(1)}°C and ${maxTemp.toStringAsFixed(1)}°C.');
    }
  }
}

// Function to display the status of all devices
void viewStatus(SmartDevice lights, Thermostat thermostat, SmartDevice security) {
  print('\n--- System Status ---');

  // Lights Status (Requirement 6: String Interpolation)
  print('Lights: ${lights.isOn ? 'ON' : 'OFF'}');

  // Thermostat Status with FizzBuzz Logic (Requirement 5)
  // We round to the nearest whole number to check for multiples
  final tempInt = thermostat.temperature.round();
  String moodMessage = '';

  if (tempInt % 3 == 0 && tempInt % 5 == 0) {
    moodMessage = ' (Perfect Day)'; // Multiple of 3 and 5
  } else if (tempInt % 3 == 0) {
    moodMessage = ' (Cool Day)'; // Multiple of 3 only
  } else if (tempInt % 5 == 0) {
    moodMessage = ' (Warm Day)'; // Multiple of 5 only
  }

  print('Thermostat: ${thermostat.temperature.toStringAsFixed(1)}°C$moodMessage');

  // Security Status (Requirement 6: String Interpolation & Operation)
  // Ensures the status is shown in uppercase using .toUpperCase()
  final securityStatus = security.isOn ? 'ARMED' : 'DISARMED';
  print('Security System: ${securityStatus.toUpperCase()}');

  print('---------------------\n');
}

// 1. Main Method - Program Entry Point (Requirement 1)
void main() {
  // 2. Device Status: Initialize devices with default values (Requirement 2)
  final lights = SmartDevice('Lights', isOn: false);         // Lights off
  final thermostat = Thermostat(temperature: 20.0);       // 20°C
  final securitySystem = SmartDevice('Security System', isOn: false); // Disarmed

  print('Welcome to the Smart Home Automation CLI! (Running in mock mode for DartPad)');

  // 3. User Interaction: Main loop (Control Flow & Loops) (Requirement 3)
  var isRunning = true;
  while (isRunning) {
    print('\nPlease choose an option:');

    // Menu options using String Interpolation (Requirement 6)
    print('1. Toggle Lights (Current: ${lights.isOn ? 'ON' : 'OFF'})');
    print('2. Set Thermostat Temperature (Current: ${thermostat.temperature.toStringAsFixed(1)}°C)');
    print('3. Toggle Security System (Current: ${securitySystem.isOn ? 'ARMED' : 'DISARMED'})');
    print('4. View System Status');
    print('5. Exit the program');

    _writeOutput('Your choice: '); // Prompt for choice
    final choice = _readInput(); // Read mock choice

    // 5. Control Flow: Use a switch statement to handle menu options (Requirement 5)
    switch (choice) {
      case '1':
        lights.toggle();
        break;

      case '2':
        _writeOutput('Enter new temperature (${Thermostat.minTemp.toStringAsFixed(1)}°C - ${Thermostat.maxTemp.toStringAsFixed(1)}°C): ');
        final tempInput = _readInput();
        final newTemp = double.tryParse(tempInput);

        // Input Validation (Requirement 4)
        if (newTemp != null) {
          thermostat.setTemperature(newTemp);
        } else {
          print('Invalid input. Please enter a numerical value for the temperature.');
        }
        break;

      case '3':
        securitySystem.toggle();
        break;

      case '4':
        viewStatus(lights, thermostat, securitySystem);
        break;

      case '5':
        isRunning = false;
        print('Exiting the program. Goodbye!');
        break;

      default:
        print('Invalid choice. Please select an option from the menu (1-5).');
        break;
    }
  }
}