import { expect, tap } from '@git.zone/tstest/tapbundle';
import { BondConfigFlow, BondIntegration, BondMapper, bondActions, bondDeviceTypes, type IBondCommandRequest } from '../../ts/integrations/bond/index.js';

const snapshot = BondMapper.toSnapshot({
  config: {},
  source: 'manual',
  online: true,
  rawData: {
    version: { bondid: 'ZZ12345', make: 'Olibra', target: 'zermatt' },
    bridge: { name: 'Patio Bond' },
    devices: [{
      deviceId: 'relay-device',
      attrs: {
        name: 'Generic Relay',
        type: bondDeviceTypes.genericDevice,
        actions: [bondActions.turnOn, bondActions.turnOff],
      },
      state: { power: 0 },
    }],
  },
});

tap.test('does not fake control success for snapshot-only Bond configs', async () => {
  const runtime = await new BondIntegration().setup({ snapshot }, {});
  const status = await runtime.callService!({ domain: 'bond', service: 'snapshot', target: {} });
  const control = await runtime.callService!({ domain: 'switch', service: 'turn_on', target: { entityId: 'switch.generic_relay' } });

  expect(status.success).toBeTrue();
  expect(control.success).toBeFalse();
  expect(control.error!.includes('Static snapshots/manual data are read-only')).toBeTrue();
});

tap.test('uses injected commandExecutor for Bond controls', async () => {
  const calls: IBondCommandRequest[] = [];
  const runtime = await new BondIntegration().setup({
    snapshot,
    commandExecutor: {
      execute: async (commandArg) => {
        calls.push(commandArg);
        return { ok: true };
      },
    },
  }, {});
  const result = await runtime.callService!({ domain: 'switch', service: 'turn_off', target: { entityId: 'switch.generic_relay' } });

  expect(result.success).toBeTrue();
  expect(calls[0].deviceId).toEqual('relay-device');
  expect(calls[0].action).toEqual(bondActions.turnOff);
});

tap.test('builds Bond config from manual config flow input', async () => {
  const flow = new BondConfigFlow();
  const step = await flow.start({ source: 'manual', host: '192.168.1.45', name: 'Patio Bond' }, {});
  const done = await step.submit!({ accessToken: 'token' });

  expect(done.kind).toEqual('done');
  expect(done.config?.host).toEqual('192.168.1.45');
  expect(done.config?.accessToken).toEqual('token');
});

export default tap.start();
