<?php

app_require('classes/shelly_relay_inventory.php');

use classes\shelly_relay_inventory;

it('normalizes owned Shelly devices into relay select options', function (): void {
    $inventory = (new shelly_relay_inventory())
        ->setInventoryFetcher(static function (): array {
            return [
                'isok' => true,
                'data' => [
                    'devices_status' => [
                        'device-key-1' => [
                            '_dev_info' => [
                                'id' => 'shelly-plus-01',
                                'code' => 'SPSW-001PE16EU',
                                'model' => 'Shelly Plus 1PM',
                                'online' => 1,
                            ],
                            'name' => 'Entry Gate',
                            'wifi_sta' => [
                                'ip' => '10.32.0.11',
                            ],
                            'status' => [
                                'switch:0' => [
                                    'output' => false,
                                    'name' => 'Entrance Relay',
                                ],
                            ],
                        ],
                        'device-key-2' => [
                            '_dev_info' => [
                                'id' => 'shelly-pro-03',
                                'code' => 'SPSW-201XE16EU',
                                'model' => 'Shelly Pro 2PM',
                            ],
                            'name' => 'Machine Cabinet',
                            'status' => [
                                'eth' => [
                                    'ip' => '10.32.0.12',
                                ],
                            ],
                            'relays' => [
                                ['ison' => false, 'name' => 'Program Picker'],
                            ],
                        ],
                        'device-key-3' => [
                            '_dev_info' => [
                                'id' => 'shelly-legacy-02',
                                'code' => 'SHSW-1',
                                'model' => 'Shelly 1',
                                'online' => 0,
                            ],
                            'relays' => [
                                ['ison' => false],
                            ],
                        ],
                        'device-key-4' => [
                            '_dev_info' => [
                                'id' => 'shelly-sensor-01',
                                'code' => 'SHHT-1',
                                'model' => 'Shelly H&T',
                                'online' => 1,
                            ],
                            'sensor' => [
                                'temperature' => 21.5,
                            ],
                        ],
                    ],
                ],
            ];
        })
        ->setDeviceListFetcher(static function (): array {
            return [
                'isok' => true,
                'data' => [
                    'devices' => [
                        'shelly-plus-01' => [
                            'id' => 'shelly-plus-01',
                            'name' => 'Gate From Shelly Cloud',
                            'type' => 'SPSW-001PE16EU',
                            'cloud_online' => true,
                        ],
                        'shelly-pro-03' => [
                            'id' => 'shelly-pro-03',
                            'name' => 'Program Picker From Shelly Cloud',
                            'type' => 'SPSW-201XE16EU',
                            'cloud_online' => false,
                        ],
                    ],
                ],
            ];
        });

    expect($inventory->listRelayOptions())->toBe([
        [
            'id' => 'shelly-plus-01',
            'name' => 'Gate From Shelly Cloud (Shelly Plus 1PM)',
            'device_id' => 'shelly-plus-01',
            'device_name' => 'Gate From Shelly Cloud',
            'cloud_name' => 'Gate From Shelly Cloud',
            'device_type' => 'Shelly Plus 1PM',
            'code' => 'SPSW-001PE16EU',
            'device_model' => 'SPSW-001PE16EU',
            'device_generation' => 2,
            'control_type' => 'Switch',
            'control_name' => 'Entrance Relay',
            'status_color' => 'Green',
            'online' => true,
        ],
        [
            'id' => 'shelly-pro-03',
            'name' => 'Program Picker From Shelly Cloud (Shelly Pro 2PM)',
            'device_id' => 'shelly-pro-03',
            'device_name' => 'Program Picker From Shelly Cloud',
            'cloud_name' => 'Program Picker From Shelly Cloud',
            'device_type' => 'Shelly Pro 2PM',
            'code' => 'SPSW-201XE16EU',
            'device_model' => 'SPSW-201XE16EU',
            'device_generation' => 2,
            'control_type' => 'Relay',
            'control_name' => 'Program Picker',
            'status_color' => 'Red',
            'online' => false,
        ],
        [
            'id' => 'shelly-legacy-02',
            'name' => 'shelly-legacy-02 (Shelly 1)',
            'device_id' => 'shelly-legacy-02',
            'device_name' => null,
            'cloud_name' => null,
            'device_type' => 'Shelly 1',
            'code' => 'SHSW-1',
            'device_model' => 'SHSW-1',
            'device_generation' => 1,
            'control_type' => 'Relay',
            'control_name' => null,
            'status_color' => 'Red',
            'online' => false,
        ],
    ]);
});

it('falls back to local device and control names when Shelly cloud list metadata is unavailable', function (): void {
    $inventory = (new shelly_relay_inventory())
        ->setInventoryFetcher(static function (): array {
            return [
                'isok' => true,
                'data' => [
                    'devices_status' => [
                        'device-key-1' => [
                            '_dev_info' => [
                                'id' => 'shelly-plus-01',
                                'code' => 'SPSW-001PE16EU',
                                'model' => 'Shelly Plus 1PM',
                                'online' => 1,
                            ],
                            'ip' => '10.32.0.21',
                            'name' => 'Entry Gate',
                            'status' => [
                                'switch:0' => [
                                    'output' => false,
                                    'name' => 'Entrance Relay',
                                ],
                            ],
                        ],
                    ],
                ],
            ];
        })
        ->setDeviceListFetcher(static function (): array {
            return [
                'isok' => false,
                'errors' => [
                    '404' => 'Requested method was not found',
                ],
            ];
        });

    expect($inventory->listRelayOptions())->toBe([
        [
            'id' => 'shelly-plus-01',
            'name' => 'Entry Gate / Entrance Relay (Shelly Plus 1PM)',
            'device_id' => 'shelly-plus-01',
            'device_name' => 'Entry Gate',
            'cloud_name' => null,
            'device_type' => 'Shelly Plus 1PM',
            'code' => 'SPSW-001PE16EU',
            'device_model' => 'SPSW-001PE16EU',
            'device_generation' => 2,
            'control_type' => 'Switch',
            'control_name' => 'Entrance Relay',
            'status_color' => 'Green',
            'online' => true,
        ],
    ]);
});

it('keeps Shelly 1 Mini Gen3 type, model, and generation aligned with Shelly metadata', function (): void {
    $inventory = (new shelly_relay_inventory())
        ->setInventoryFetcher(static function (): array {
            return [
                'isok' => true,
                'data' => [
                    'devices_status' => [
                        'device-key-1' => [
                            '_dev_info' => [
                                'id' => 'e4b3231f6410',
                                'model' => 'S3SW-001X8EU',
                                'type' => 'Shelly 1 Mini Gen3',
                                'online' => 1,
                            ],
                            'name' => 'Roskilde indkørselsport',
                            'wifi_sta' => [
                                'ip' => '192.168.1.2',
                            ],
                            'status' => [
                                'switch:0' => [
                                    'output' => false,
                                ],
                            ],
                        ],
                    ],
                ],
            ];
        })
        ->setDeviceListFetcher(static function (): array {
            return [
                'isok' => true,
                'data' => [
                    'devices' => [
                        'e4b3231f6410' => [
                            'id' => 'e4b3231f6410',
                            'name' => 'Roskilde indkørselsport',
                            'type' => 'S3SW-001X8EU',
                            'cloud_online' => true,
                        ],
                    ],
                ],
            ];
        });

    expect($inventory->listRelayOptions())->toBe([[
        'id' => 'e4b3231f6410',
        'name' => 'Roskilde indkørselsport (Shelly 1 Mini Gen3)',
        'device_id' => 'e4b3231f6410',
        'device_name' => 'Roskilde indkørselsport',
        'cloud_name' => 'Roskilde indkørselsport',
        'device_type' => 'Shelly 1 Mini Gen3',
        'code' => 'S3SW-001X8EU',
        'device_model' => 'S3SW-001X8EU',
        'device_generation' => 3,
        'control_type' => 'Switch',
        'control_name' => null,
        'status_color' => 'Green',
        'online' => true,
    ]]);
});

it('only includes local IP addresses for internal relay option lookups', function (): void {
    $inventory = (new shelly_relay_inventory())
        ->setInventoryFetcher(static function (): array {
            return [
                'isok' => true,
                'data' => [
                    'devices_status' => [
                        'device-key-1' => [
                            '_dev_info' => [
                                'id' => 'shelly-plus-01',
                                'code' => 'SPSW-001PE16EU',
                                'model' => 'Shelly Plus 1PM',
                                'online' => 1,
                            ],
                            'wifi_sta' => [
                                'ip' => '10.32.0.11',
                            ],
                            'status' => [
                                'switch:0' => [
                                    'output' => false,
                                ],
                            ],
                        ],
                    ],
                ],
            ];
        })
        ->setDeviceListFetcher(static function (): array {
            return [
                'isok' => true,
                'data' => [
                    'devices' => [],
                ],
            ];
        });

    $publicOptions = $inventory->listRelayOptions();
    $internalOptions = $inventory->listRelayOptions(true);

    expect($publicOptions[0])->not->toHaveKey('local_ip');
    expect($internalOptions[0])->toHaveKey('local_ip');
    expect($internalOptions[0]['local_ip'])->toBe('10.32.0.11');
});

it('fails fast when Shelly inventory does not include owned devices status', function (): void {
    $inventory = (new shelly_relay_inventory())->setInventoryFetcher(static function (): array {
        return [
            'isok' => true,
            'data' => [],
        ];
    });

    expect(fn() => $inventory->listRelayOptions())
        ->toThrow(Exception::class, 'Shelly relay inventory response was missing devices_status');
});
