import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DaikinMapper, type IDaikinRawData } from '../../ts/integrations/daikin/index.js';

const rawData: Partial<IDaikinRawData> = {
  variant: 'airbase',
  basicInfo: {
    name: 'Living%20Daikin',
    mac: 'AABBCCDDEEFF',
    model: 'FTXM35R',
    ver: '1_2_3',
  },
  controlInfo: {
    pow: '1',
    mode: '2',
    stemp: '23',
    shum: '45',
    f_rate: '3',
    f_dir: '1',
  },
  sensorInfo: {
    htemp: '21.5',
    otemp: '7',
    hhum: '44',
    cmpfreq: '22',
  },
  notify: {
    adv: '12',
  },
  holiday: {
    en_hol: '0',
  },
  dayPowerEx: {
    curr_day_cool: '1/2/3',
    curr_day_heat: '4/5',
  },
  weekPower: {
    datas: '0/100/250',
  },
  zoneSetting: {
    zone_name: 'Living%20Room;Bedroom;-',
    zone_onoff: '1;0;0',
    lztemp_c: '23;22;20',
    lztemp_h: '21;20;19',
    en_zone: '2',
  },
};

tap.test('maps Daikin raw API data to snapshot, devices, entities, and zones', async () => {
  const snapshot = DaikinMapper.toSnapshot({ config: { host: 'daikin.local' }, rawData, online: true, source: 'manual' });
  const devices = DaikinMapper.toDevices(snapshot);
  const entities = DaikinMapper.toEntities(snapshot);

  expect(snapshot.device.macAddress).toEqual('aa:bb:cc:dd:ee:ff');
  expect(snapshot.device.name).toEqual('Living Daikin');
  expect(snapshot.device.apiVariant).toEqual('airbase');
  expect(snapshot.climate.hvacMode).toEqual('cool');
  expect(snapshot.climate.hvacAction).toEqual('cooling');
  expect(snapshot.climate.targetTemperature).toEqual(23);
  expect(snapshot.climate.fanMode).toEqual('Mid');
  expect(snapshot.climate.swingMode).toEqual('Vertical');
  expect(snapshot.climate.presetMode).toEqual('eco');
  expect(snapshot.energy.energyToday).toEqual(1.5);
  expect(snapshot.energy.totalEnergyToday).toEqual(0.25);
  expect(snapshot.zones[0].name).toEqual('Living Room');
  expect(snapshot.zones[0].enabled).toBeTrue();
  expect(snapshot.zones[1].targetTemperature).toEqual(22);
  expect(devices[0].id).toEqual('daikin.ac.aa_bb_cc_dd_ee_ff');
  expect(devices[0].metadata?.macAddress).toEqual('aa:bb:cc:dd:ee:ff');
  expect(entities.find((entityArg) => entityArg.attributes?.key === 'climate')?.state).toEqual('cool');
  expect(entities.find((entityArg) => entityArg.attributes?.key === 'inside_temperature')?.state).toEqual(21.5);
  expect(entities.find((entityArg) => entityArg.attributes?.key === 'zone')?.state).toEqual('on');
  expect(entities.find((entityArg) => entityArg.attributes?.key === 'zone_temperature')?.attributes?.zoneId).toEqual(0);
});

tap.test('maps Home Assistant style services to real Daikin command shapes', async () => {
  const snapshot = DaikinMapper.toSnapshot({ config: { host: 'daikin.local' }, rawData, online: true, source: 'manual' });
  const setTemperature = DaikinMapper.commandForService(snapshot, { domain: 'climate', service: 'set_temperature', target: { entityId: 'climate.living_daikin' }, data: { temperature: 23.5, hvac_mode: 'heat' } });
  const powerOff = DaikinMapper.commandForService(snapshot, { domain: 'switch', service: 'turn_off', target: { entityId: 'switch.living_daikin_power' }, data: {} });
  const zoneOff = DaikinMapper.commandForService(snapshot, { domain: 'switch', service: 'turn_off', target: { entityId: 'switch.living_daikin_zone_1' }, data: {} });
  const preset = DaikinMapper.commandForService(snapshot, { domain: 'climate', service: 'set_preset_mode', target: {}, data: { preset_mode: 'none' } });

  expect(setTemperature?.action).toEqual('set_control');
  expect(setTemperature?.settings?.stemp).toEqual('23.5');
  expect(setTemperature?.settings?.mode).toEqual('hot');
  expect(powerOff?.settings?.mode).toEqual('off');
  expect(zoneOff?.action).toEqual('set_zone');
  expect(zoneOff?.zoneId).toEqual(1);
  expect(zoneOff?.zoneValue).toEqual('0');
  expect(preset?.action).toEqual('set_advanced_mode');
  expect(preset?.enabled).toBeFalse();
});

export default tap.start();
