esphome:
  name: test-ha-api
  friendly_name: Home Assistant API Test

host:

api:
  services:
    - service: trigger_all_tests
      then:
        - logger.log: "=== Starting Home Assistant API Tests ==="
        - button.press: test_basic_service
        - button.press: test_templated_service
        - button.press: test_empty_string_service
        - button.press: test_multiple_fields_service
        - button.press: test_complex_lambda_service
        - button.press: test_all_empty_service
        - button.press: test_rapid_service_calls
        - button.press: test_read_ha_states
        - button.press: test_action_response_error
        - number.set:
            id: ha_number
            value: 42.5
        - switch.turn_on: ha_switch
        - switch.turn_off: ha_switch
        - logger.log: "=== All tests completed ==="

logger:
  level: DEBUG

# Time component for templated values
time:
  - platform: homeassistant
    id: homeassistant_time

# Global variables for testing
globals:
  - id: test_brightness
    type: int
    initial_value: '75'
  - id: test_string
    type: std::string
    initial_value: '"test_value"'

# Sensors for testing state reading
sensor:
  - platform: template
    name: "Test Sensor"
    id: test_sensor
    lambda: return 42.0;
    update_interval: 0.1s

  # Home Assistant sensor that reads external state
  - platform: homeassistant
    name: "HA Temperature"
    entity_id: sensor.external_temperature
    id: ha_temperature
    on_value:
      then:
        - logger.log:
            format: "HA Temperature state updated: %.1f"
            args: ['x']

  # Test multiple HA state sensors
  - platform: homeassistant
    name: "HA Humidity"
    entity_id: sensor.external_humidity
    id: ha_humidity
    on_value:
      then:
        - logger.log:
            format: "HA Humidity state updated: %.1f"
            args: ['x']

# Binary sensor from Home Assistant
binary_sensor:
  - platform: homeassistant
    name: "HA Motion"
    entity_id: binary_sensor.external_motion
    id: ha_motion
    on_state:
      then:
        - logger.log:
            format: "HA Motion state changed: %s"
            args: ['x ? "ON" : "OFF"']

# Text sensor from Home Assistant
text_sensor:
  - platform: homeassistant
    name: "HA Weather"
    entity_id: weather.home
    attribute: condition
    id: ha_weather
    on_value:
      then:
        - logger.log:
            format: "HA Weather condition updated: %s"
            args: ['x.c_str()']

  # Test empty state handling
  - platform: homeassistant
    name: "HA Empty State"
    entity_id: sensor.nonexistent_sensor
    id: ha_empty_state
    on_value:
      then:
        - logger.log:
            format: "HA Empty state updated: %s"
            args: ['x.c_str()']

  # Test long attribute handling (>255 characters)
  # HA states are limited to 255 chars, but attributes are not
  - platform: homeassistant
    name: "HA Long Attribute"
    entity_id: sensor.long_data
    attribute: long_value
    id: ha_long_attribute
    on_value:
      then:
        - logger.log:
            format: "HA Long attribute received, length: %d"
            args: ['x.size()']
        # Log the first 50 and last 50 chars to verify no truncation
        - lambda: |-
            if (x.size() >= 100) {
              ESP_LOGI("test", "Long attribute first 50 chars: %.50s", x.c_str());
              ESP_LOGI("test", "Long attribute last 50 chars: %s", x.c_str() + x.size() - 50);
            }

# Number component for testing HA number control
number:
  - platform: template
    name: "HA Controlled Number"
    id: ha_number
    min_value: 0
    max_value: 100
    step: 1
    optimistic: true
    set_action:
      - logger.log:
          format: "Setting HA number to: %.1f"
          args: ['x']
      - homeassistant.action:
          action: input_number.set_value
          data:
            entity_id: input_number.test_number
            value: !lambda 'return to_string(x);'

# Switch component for testing HA switch control
switch:
  - platform: template
    name: "HA Controlled Switch"
    id: ha_switch
    optimistic: true
    turn_on_action:
      - logger.log: "Toggling HA switch: switch.test_switch ON"
      - homeassistant.action:
          action: switch.turn_on
          data:
            entity_id: switch.test_switch
    turn_off_action:
      - logger.log: "Toggling HA switch: switch.test_switch OFF"
      - homeassistant.action:
          action: switch.turn_off
          data:
            entity_id: switch.test_switch

# Buttons for testing various service call scenarios
button:
  # Test 1: Basic service call with static values
  - platform: template
    name: "Test Basic Service"
    id: test_basic_service
    on_press:
      - logger.log: "Sending HomeAssistant service call: light.turn_off"
      - homeassistant.action:
          action: light.turn_off
          data:
            entity_id: light.test_light
      - logger.log: "Service data: entity_id=light.test_light"

  # Test 2: Service call with templated/lambda values (main bug fix test)
  - platform: template
    name: "Test Templated Service"
    id: test_templated_service
    on_press:
      - logger.log: "Testing templated service call"
      - lambda: |-
          int brightness_percent = id(test_brightness);
          std::string computed = to_string(brightness_percent * 255 / 100);
          ESP_LOGI("test", "Lambda computed value: %s", computed.c_str());
      - homeassistant.action:
          action: light.turn_on
          data:
            entity_id: light.test_light
            # This creates a temporary string - the main test case
            brightness: !lambda 'return to_string(id(test_brightness) * 255 / 100);'
          data_template:
            color_name: !lambda 'return id(test_string);'
          variables:
            transition: !lambda 'return "2.5";'

  # Test 3: Service call with empty string values
  - platform: template
    name: "Test Empty String Service"
    id: test_empty_string_service
    on_press:
      - logger.log: "Testing empty string values"
      - homeassistant.action:
          action: notify.test
          data:
            message: "Test message"
            title: ""
          data_template:
            target: !lambda 'return "";'
          variables:
            sound: !lambda 'return "";'

      - logger.log: "Empty value for key: title"
      - logger.log: "Empty value for key: target"
      - logger.log: "Empty value for key: sound"

  # Test 4: Service call with multiple data fields
  - platform: template
    name: "Test Multiple Fields Service"
    id: test_multiple_fields_service
    on_press:
      - logger.log: "Testing multiple data fields"
      - homeassistant.action:
          action: climate.set_temperature
          data:
            entity_id: climate.test_climate
            temperature: "22"
            hvac_mode: "heat"
          data_template:
            target_temp_high: !lambda 'return "24";'
            target_temp_low: !lambda 'return "20";'
          variables:
            preset_mode: !lambda 'return "comfort";'

  # Test 5: Complex lambda with string operations
  - platform: template
    name: "Test Complex Lambda Service"
    id: test_complex_lambda_service
    on_press:
      - logger.log: "Testing complex lambda expressions"
      - homeassistant.action:
          action: script.test_script
          data:
            entity_id: !lambda |-
              std::string base = "light.";
              std::string room = "living_room";
              return base + room;
            brightness_pct: !lambda |-
              float sensor_val = id(test_sensor).state;
              int pct = (int)(sensor_val * 2.38);  // 42 * 2.38 ≈ 100
              return to_string(pct);
          data_template:
            message: !lambda |-
              char buffer[50];
              snprintf(buffer, sizeof(buffer), "Sensor: %.1f, Time: %02d:%02d",
                       id(test_sensor).state,
                       id(homeassistant_time).now().hour,
                       id(homeassistant_time).now().minute);
              return std::string(buffer);

  # Test 6: Service with only empty strings to verify size calculation
  - platform: template
    name: "Test All Empty Service"
    id: test_all_empty_service
    on_press:
      - logger.log: "Testing all empty string values"
      - homeassistant.action:
          action: test.empty
          data:
            field1: ""
            field2: ""
          data_template:
            field3: !lambda 'return "";'
          variables:
            field4: !lambda 'return "";'
      - logger.log: "All empty service call completed"

  # Test 7: Rapid successive service calls
  - platform: template
    name: "Test Rapid Service Calls"
    id: test_rapid_service_calls
    on_press:
      - logger.log: "Testing rapid service calls"
      - repeat:
          count: 5
          then:
            - homeassistant.action:
                action: counter.increment
                data:
                  entity_id: counter.test_counter
            - delay: 10ms
      - logger.log: "Rapid service calls completed"

  # Test 8: Log current HA states
  - platform: template
    name: "Test Read HA States"
    id: test_read_ha_states
    on_press:
      - logger.log: "Reading current HA states"
      - lambda: |-
          if (id(ha_temperature).has_state()) {
            ESP_LOGI("test", "Current HA Temperature: %.1f", id(ha_temperature).state);
          } else {
            ESP_LOGI("test", "HA Temperature has no state");
          }

          if (id(ha_humidity).has_state()) {
            ESP_LOGI("test", "Current HA Humidity: %.1f", id(ha_humidity).state);
          } else {
            ESP_LOGI("test", "HA Humidity has no state");
          }

          ESP_LOGI("test", "Current HA Motion: %s", id(ha_motion).state ? "ON" : "OFF");

          if (id(ha_weather).has_state()) {
            ESP_LOGI("test", "Current HA Weather: %s", id(ha_weather).state.c_str());
          } else {
            ESP_LOGI("test", "HA Weather has no state");
          }

          if (id(ha_empty_state).has_state()) {
            ESP_LOGI("test", "HA Empty State value: %s", id(ha_empty_state).state.c_str());
          } else {
            ESP_LOGI("test", "HA Empty State has no value (expected)");
          }

  # Test 9: Action response error handling (tests StringRef error message)
  - platform: template
    name: "Test Action Response Error"
    id: test_action_response_error
    on_press:
      - logger.log: "Testing action response error handling"
      - homeassistant.action:
          action: nonexistent.action_for_error_test
          data:
            test_field: "test_value"
          on_error:
            - lambda: |-
                // This tests that StringRef error message works correctly
                // The error variable is std::string (converted from StringRef)
                ESP_LOGI("test", "Action error received: %s", error.c_str());
            - logger.log:
                format: "Action failed with error message length: %d"
                args: ['error.size()']
          on_success:
            - logger.log: "Action succeeded unexpectedly"
