import { expect, tap } from '@git.zone/tstest/tapbundle';
import { HunterDouglasPowerViewIntegration, HunterDouglasPowerViewMapper, HomeAssistantHunterdouglasPowerviewIntegration, type IHunterDouglasPowerViewCommandRequest } from '../../ts/integrations/hunterdouglas_powerview/index.js';

const snapshot = HunterDouglasPowerViewMapper.toSnapshot({
  config: { name: 'Patio PowerView' },
  source: 'manual',
  online: true,
  rawData: {
    apiVersion: 2,
    hub: {
      userData: {
        hubName: Buffer.from('Patio PowerView').toString('base64'),
        serialNumber: 'PVHUB123',
        macAddress: '002674123456',
        firmware: { mainProcessor: { revision: 2, subRevision: 4, build: 5, name: 'PV Hub2.0' } },
      },
    },
    rooms: [{ id: 7, name: Buffer.from('Office').toString('base64') }],
    scenes: [{ id: 9, roomId: 7, name: Buffer.from('Morning').toString('base64') }],
    shades: [{
      id: 3,
      roomId: 7,
      name: Buffer.from('Office Shade').toString('base64'),
      type: 1,
      capabilities: 0,
      batteryKind: 1,
      positions: { posKind1: 1, position1: 32768 },
    }],
  },
});

tap.test('maps PowerView snapshots to devices, cover entities, and scene buttons', async () => {
  const devices = HunterDouglasPowerViewMapper.toDevices(snapshot);
  const entities = HunterDouglasPowerViewMapper.toEntities(snapshot);

  expect(devices[0].id).toEqual('hunterdouglas_powerview.hub.pvhub123');
  expect(devices.some((deviceArg) => deviceArg.id === 'hunterdouglas_powerview.shade.pvhub123_3')).toBeTrue();
  expect(entities.find((entityArg) => entityArg.id === 'cover.office_shade')?.state).toEqual('open');
  expect(entities.find((entityArg) => entityArg.id === 'cover.office_shade')?.attributes?.currentPosition).toEqual(50);
  expect(entities.find((entityArg) => entityArg.id === 'button.morning_scene')?.attributes?.sceneId).toEqual('9');
});

tap.test('maps cover and scene services to local PowerView commands', async () => {
  const coverCommand = HunterDouglasPowerViewMapper.commandForService(snapshot, {
    domain: 'cover',
    service: 'set_cover_position',
    target: { entityId: 'cover.office_shade' },
    data: { position: 80 },
  });
  const sceneCommand = HunterDouglasPowerViewMapper.commandForService(snapshot, {
    domain: 'scene',
    service: 'turn_on',
    target: { entityId: 'scene.morning' },
  });

  expect(coverCommand?.action).toEqual('move_shade');
  expect(coverCommand?.shadeId).toEqual('3');
  expect(coverCommand?.positions?.primary).toEqual(80);
  expect(sceneCommand?.action).toEqual('activate_scene');
  expect(sceneCommand?.sceneId).toEqual('9');
});

tap.test('does not fake command success for snapshot-only PowerView configs', async () => {
  const runtime = await new HunterDouglasPowerViewIntegration().setup({ snapshot }, {});
  const status = await runtime.callService!({ domain: 'hunterdouglas_powerview', service: 'snapshot', target: {} });
  const control = await runtime.callService!({ domain: 'cover', service: 'open_cover', target: { entityId: 'cover.office_shade' } });

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

tap.test('uses injected commandExecutor and preserves generated Home Assistant export', async () => {
  const calls: IHunterDouglasPowerViewCommandRequest[] = [];
  const integration = new HomeAssistantHunterdouglasPowerviewIntegration();
  const runtime = await integration.setup({
    snapshot,
    commandExecutor: {
      execute: async (commandArg) => {
        calls.push(commandArg);
        return { ok: true };
      },
    },
  }, {});
  const result = await runtime.callService!({ domain: 'cover', service: 'close_cover', target: { entityId: 'cover.office_shade' } });

  expect(integration.domain).toEqual('hunterdouglas_powerview');
  expect(result.success).toBeTrue();
  expect(calls[0].action).toEqual('move_shade');
  expect(calls[0].positions?.primary).toEqual(0);
});

export default tap.start();
