import { expect, tap } from '@git.zone/tstest/tapbundle';
import {
  HarmanKardonAvrIntegration,
  HomeAssistantHarmanKardonAvrIntegration,
  createHarmanKardonAvrDiscoveryDescriptor,
  type IHarmanKardonAvrSnapshot,
} from '../../ts/integrations/harman_kardon_avr/index.js';

const snapshot: IHarmanKardonAvrSnapshot = {
  deviceInfo: {
    name: 'Static AVR',
    manufacturer: 'Harman Kardon',
    model: 'AVR-151S',
    serialNumber: 'HK12345',
    zone: 'Main Zone',
  },
  state: {
    power: 'ON',
    state: 'on',
    muted: false,
    source: 'TV',
    sourceList: ['Disc', 'TV', 'USB'],
  },
  online: true,
  available: true,
  source: 'manual',
};

tap.test('matches manual Harman Kardon AVR entries and creates config flow output', async () => {
  const descriptor = createHarmanKardonAvrDiscoveryDescriptor();
  const manualMatcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'harman-kardon-avr-manual-match');
  const match = await manualMatcher!.matches({ name: 'Harman AVR import', snapshot }, {});

  expect(match.matched).toBeTrue();
  expect(match.normalizedDeviceId).toEqual('HK12345');
  expect(match.candidate?.integrationDomain).toEqual('harman_kardon_avr');

  const validation = await descriptor.getValidators()[0].validate(match.candidate!, {});
  expect(validation.matched).toBeTrue();

  const integration = new HarmanKardonAvrIntegration();
  const done = await (await integration.configFlow.start(match.candidate!, {})).submit!({});
  expect(done.kind).toEqual('done');
  expect(done.config?.name).toEqual('Static AVR');
  expect(done.config?.port).toEqual(10025);
  expect(done.config?.snapshot?.state.source).toEqual('TV');
  expect(new HomeAssistantHarmanKardonAvrIntegration() instanceof HarmanKardonAvrIntegration).toBeTrue();
});

tap.test('does not report command success for read-only static snapshots', async () => {
  const runtime = await new HarmanKardonAvrIntegration().setup({ snapshot }, {});
  const result = await runtime.callService?.({ domain: 'media_player', service: 'turn_off', target: { entityId: 'media_player.static_avr' }, data: {} });

  expect(result?.success).toBeFalse();
  expect(result?.error).toContain('Static snapshots/manual data are read-only');
  await runtime.destroy();
});

tap.test('delegates AVR media commands to an injected executor', async () => {
  const requests: unknown[] = [];
  const runtime = await new HarmanKardonAvrIntegration().setup({
    snapshot,
    commandExecutor: {
      execute: async (requestArg) => {
        requests.push(requestArg);
        return ['HTTP/1.1 200 OK'];
      },
    },
  }, {});

  const power = await runtime.callService?.({ domain: 'media_player', service: 'turn_on', target: {}, data: {} });
  const source = await runtime.callService?.({ domain: 'media_player', service: 'select_source', target: {}, data: { source: 'USB' } });

  expect(power?.success).toBeTrue();
  expect(source?.success).toBeTrue();
  expect((requests[0] as { rawCommand?: string }).rawCommand).toEqual('power-on');
  expect((requests[1] as { rawCommand?: string; parameter?: string }).rawCommand).toEqual('source-selection');
  expect((requests[1] as { parameter?: string }).parameter).toEqual('USB');
  expect((requests[0] as { body?: string }).body).toContain('<name>power-on</name>');
  await runtime.destroy();
});

export default tap.start();
