import { expect, tap } from '@git.zone/tstest/tapbundle';
import { BleboxIntegration } from '../../ts/integrations/blebox/index.js';
import type { IBleboxSnapshot } from '../../ts/integrations/blebox/index.js';

const switchSnapshot: IBleboxSnapshot = {
  device: {
    id: '1afe34e750b8',
    type: 'switchBoxD',
    deviceName: 'Kitchen Switch',
    fv: '0.200',
    hv: '0.7',
    apiLevel: 20200831,
  },
  state: {
    relays: [
      { relay: 0, state: 0, name: 'Counter' },
      { relay: 1, state: 0, name: 'Sink' },
    ],
  },
};

tap.test('runs safe BleBox switch commands through modeled local HTTP paths', async () => {
  const originalFetch = globalThis.fetch;
  const calls: Array<{ url: string; method?: string }> = [];
  globalThis.fetch = (async (urlArg: URL | RequestInfo, initArg?: RequestInit) => {
    calls.push({ url: String(urlArg), method: initArg?.method });
    return new Response('{}', { status: 200, headers: { 'content-type': 'application/json' } });
  }) as typeof globalThis.fetch;

  try {
    const runtime = await new BleboxIntegration().setup({ host: '192.168.1.50', snapshot: switchSnapshot }, {});
    const result = await runtime.callService?.({
      domain: 'switch',
      service: 'turn_on',
      target: { entityId: 'switch.kitchen_switch_relay_1' },
    });
    expect(result?.success).toBeTrue();
    expect(calls[0].url).toEqual('http://192.168.1.50/s/1/1');
    await runtime.destroy();
  } finally {
    globalThis.fetch = originalFetch;
  }
});

tap.test('rejects unsafe BleBox light service payloads before HTTP commands', async () => {
  const runtime = await new BleboxIntegration().setup({ host: '192.168.1.50', snapshot: {
    device: {
      id: '2bee34e750b8',
      type: 'wLightBox',
      deviceName: 'Cabinet Light',
      fv: '0.993',
      hv: '4.3',
      apiLevel: 20200229,
    },
    extendedState: { rgbw: { desiredColor: 'fa00203a', colorMode: 4, effectID: 0 } },
  } }, {});
  const result = await runtime.callService?.({
    domain: 'light',
    service: 'turn_on',
    target: { entityId: 'light.cabinet_light_color' },
    data: { brightness: 999 },
  });
  expect(result?.success).toBeFalse();
  expect(result?.error).toContain('brightness');
  await runtime.destroy();
});

tap.test('config flow returns a local HTTP config and validates credentials', async () => {
  const integration = new BleboxIntegration();
  const step = await integration.configFlow.start({ source: 'manual', integrationDomain: 'blebox', host: '192.168.1.50' }, {});
  const incomplete = await step.submit?.({ host: '192.168.1.50', port: 80, username: 'admin' });
  expect(incomplete?.kind).toEqual('error');
  const done = await step.submit?.({ host: '192.168.1.50', port: 80, username: 'admin', password: 'secret' });
  expect(done?.kind).toEqual('done');
  expect(done?.config?.host).toEqual('192.168.1.50');
  expect(done?.config?.protocol).toEqual('http');
});

export default tap.start();
