import { expect, tap } from '@git.zone/tstest/tapbundle';
import { BoschShcIntegration } from '../../ts/integrations/bosch_shc/index.js';
import type { IBoschShcModeledCommand, IBoschShcSnapshot } from '../../ts/integrations/bosch_shc/index.js';

const snapshot: IBoschShcSnapshot = {
  host: '192.168.1.10',
  devices: [
    { id: 'hdm:ZigBee:plug', rootDeviceId: 'AA:BB:CC:DD:EE:FF', deviceModel: 'PSM', manufacturer: 'BOSCH', serial: 'PSM123', name: 'Kitchen Plug', status: 'AVAILABLE', profile: 'GENERIC', deviceServiceIds: ['PowerSwitch'] },
    { id: 'shutter:living', rootDeviceId: 'AA:BB:CC:DD:EE:FF', deviceModel: 'BBL', manufacturer: 'BOSCH', serial: 'BBL123', name: 'Living Shutter', status: 'AVAILABLE', profile: 'GENERIC', deviceServiceIds: ['ShutterControl'] },
  ],
  services: [
    { id: 'PowerSwitch', deviceId: 'hdm:ZigBee:plug', state: { '@type': 'powerSwitchState', switchState: 'ON', automaticPowerOffTime: 0 } },
    { id: 'ShutterControl', deviceId: 'shutter:living', state: { '@type': 'shutterControlState', operationState: 'STOPPED', level: 0.5, calibrated: true } },
  ],
};

tap.test('runs modeled Bosch SHC service commands through an injected executor', async () => {
  const calls: IBoschShcModeledCommand[] = [];
  const runtime = await new BoschShcIntegration().setup({
    host: '192.168.1.10',
    snapshot,
    executor: async (commandArg) => {
      calls.push(commandArg);
      return { ok: true };
    },
  }, {});

  const result = await runtime.callService?.({
    domain: 'switch',
    service: 'turn_off',
    target: { entityId: 'switch.kitchen_plug' },
  });
  expect(result?.success).toBeTrue();
  expect(calls[0].action).toEqual('put_device_service_state');
  expect(calls[0].path).toEqual('/devices/hdm:ZigBee:plug/services/PowerSwitch/state');
  expect(calls[0].body).toEqual({ '@type': 'powerSwitchState', switchState: 'OFF' });

  const coverResult = await runtime.callService?.({
    domain: 'cover',
    service: 'set_cover_position',
    target: { entityId: 'cover.living_shutter' },
    data: { position: 75 },
  });
  expect(coverResult?.success).toBeTrue();
  expect(calls[1].body).toEqual({ '@type': 'shutterControlState', level: 0.75 });
  await runtime.destroy();
});

tap.test('returns clear unsupported errors without executor for writes and pairing', async () => {
  const runtime = await new BoschShcIntegration().setup({ host: '192.168.1.10', snapshot }, {});
  const result = await runtime.callService?.({
    domain: 'switch',
    service: 'turn_on',
    target: { entityId: 'switch.kitchen_plug' },
  });
  expect(result?.success).toBeFalse();
  expect(result?.error).toContain('requires config.snapshot or an injected executor');

  const pairResult = await runtime.callService?.({
    domain: 'bosch_shc',
    service: 'pair_client',
    target: {},
    data: { system_password: 'secret' },
  });
  expect(pairResult?.success).toBeFalse();
  expect(pairResult?.error).toContain('pairing transport');
  await runtime.destroy();
});

tap.test('models Bosch SHC pairing only through an injected executor', async () => {
  const calls: IBoschShcModeledCommand[] = [];
  const runtime = await new BoschShcIntegration().setup({
    host: '192.168.1.10',
    executor: async (commandArg) => {
      calls.push(commandArg);
      return { token: 'token:bosch-shc' };
    },
  }, {});
  const result = await runtime.callService?.({
    domain: 'bosch_shc',
    service: 'pair_client',
    target: {},
    data: { system_password: 'secret', client_id: 'homeassistant', client_name: 'HomeAssistant' },
  });

  expect(result?.success).toBeTrue();
  expect(calls[0].action).toEqual('pair_client');
  expect(calls[0].sensitiveFields).toEqual(['systemPassword', 'certificatePem']);
  expect(calls[0].body?.clientName).toEqual('HomeAssistant');
  await runtime.destroy();
});

export default tap.start();
