import { expect, tap } from '@git.zone/tstest/tapbundle';
import { FroniusMapper, type IFroniusRawData } from '../../ts/integrations/fronius/index.js';

export const froniusRawData: Partial<IFroniusRawData> = {
  apiVersion: { APIVersion: 1, BaseURL: '/solar_api/v1/' },
  loggerInfo: {
    Head: { Status: { Code: 0, Reason: 'OK' }, Timestamp: '2026-01-01T00:00:00+00:00' },
    Body: { Data: { UniqueID: 'LOGGER123', SWVersion: '1.2.3', HWVersion: '4.5', ProductID: 'Datalogger Web', TimezoneName: 'UTC' } },
  },
  inverterInfo: {
    Head: { Status: { Code: 0, Reason: 'OK' } },
    Body: { Data: { '1': { DT: 1, PVPower: 5000, StatusCode: 7, UniqueID: 'INV123', CustomName: 'Roof Inverter', Show: 1 } } },
  },
  inverterDeviceData: {
    '1': {
      Head: { Status: { Code: 0, Reason: 'OK' } },
      Body: { Data: { DAY_ENERGY: { Value: 1234, Unit: 'Wh' }, TOTAL_ENERGY: { Value: 555000, Unit: 'Wh' }, PAC: { Value: 4200, Unit: 'W' }, UDC: { Value: 610, Unit: 'V' }, DeviceStatus: { StatusCode: 7, ErrorCode: 0 } } },
    },
  },
  powerFlow: {
    Head: { Status: { Code: 0, Reason: 'OK' } },
    Body: { Data: { Site: { E_Day: 1234, E_Total: 555000, E_Year: 120000, P_Grid: -700, P_Load: -3500, P_PV: 4200, rel_Autonomy: 80, rel_SelfConsumption: 65 }, Inverters: { '1': { SOC: 71, Battery_Mode: 'normal' } } } },
  },
  systemMeter: {
    Head: { Status: { Code: 0, Reason: 'OK' } },
    Body: { Data: { '0': { PowerReal_P_Sum: -700, EnergyReal_WAC_Sum_Consumed: 2000, EnergyReal_WAC_Sum_Produced: 1000, Details: { Manufacturer: 'Fronius', Model: 'Smart Meter', Serial: 'METER123' } } } },
  },
  fetchedAt: '2026-01-01T00:00:00.000Z',
};

tap.test('maps Fronius Solar API data to devices and entities', async () => {
  const snapshot = FroniusMapper.toSnapshot({ config: { host: '192.168.1.10', name: 'Garage SolarNet' }, rawData: froniusRawData, online: true, source: 'manual' });
  const devices = FroniusMapper.toDevices(snapshot);
  const entities = FroniusMapper.toEntities(snapshot);

  expect(snapshot.system.uniqueId).toEqual('LOGGER123');
  expect(snapshot.inverters[0].uniqueId).toEqual('INV123');
  expect(snapshot.inverters[0].model).toEqual('Gen24');
  expect(devices.some((deviceArg) => deviceArg.id === 'fronius.inverter.inv123')).toBeTrue();
  expect(devices.some((deviceArg) => deviceArg.id === 'fronius.meter.meter123')).toBeTrue();
  expect(devices[0].features.some((featureArg) => featureArg.id === 'power_photovoltaics')).toBeTrue();
  expect(entities.find((entityArg) => entityArg.id === 'sensor.garage_solarnet_power_photovoltaics')?.state).toEqual(4200);
  expect(entities.find((entityArg) => entityArg.id === 'sensor.roof_inverter_power_ac')?.attributes?.nativeUnitOfMeasurement).toEqual('W');
  expect(entities.find((entityArg) => entityArg.id === 'sensor.meter_0_power_real')?.state).toEqual(-700);
});

tap.test('maps Fronius custom service requests to delegated commands', async () => {
  const snapshot = FroniusMapper.toSnapshot({ config: {}, rawData: froniusRawData, online: true, source: 'manual' });
  const command = FroniusMapper.commandForService(snapshot, {
    domain: 'fronius',
    service: 'set_power_limit',
    target: { deviceId: snapshot.system.id },
    data: { watts: 3000 },
  });

  expect(command?.action).toEqual('set_power_limit');
  expect(command?.data?.watts).toEqual(3000);
});

export default tap.start();
