import { expect, tap } from '@git.zone/tstest/tapbundle';
import { PiHoleMapper, type IPiHoleSnapshot } from '../../ts/integrations/pi_hole/index.js';

const v5Snapshot: IPiHoleSnapshot = PiHoleMapper.toSnapshot({
  config: {
    host: '192.168.1.2',
    port: 80,
    name: 'Home DNS',
    apiVersion: 5,
    rawData: {
      v5Summary: {
        status: 'enabled',
        ads_blocked_today: 42,
        ads_percentage_today: 21.55,
        clients_ever_seen: 8,
        dns_queries_today: 200,
        domains_being_blocked: 150000,
        queries_cached: 50,
        queries_forwarded: 120,
        unique_clients: 5,
        unique_domains: 90,
      },
      v5Versions: {
        core_current: 'v5.18.3',
        core_latest: 'v5.18.4',
        core_update: true,
        web_current: 'v5.21',
        web_latest: 'v5.21',
        web_update: false,
        FTL_current: 'v5.25.2',
        FTL_latest: 'v5.25.2',
        FTL_update: false,
      },
    },
  },
  online: true,
  source: 'manual',
});

tap.test('maps Pi-hole v5 status, statistics, updates, and switch control', async () => {
  const devices = PiHoleMapper.toDevices(v5Snapshot);
  const entities = PiHoleMapper.toEntities(v5Snapshot);

  expect(devices[0].id).toEqual('pi_hole.service.192_168_1_2_80');
  expect(devices[0].online).toBeTrue();
  expect(entities.find((entityArg) => entityArg.id === 'switch.home_dns')?.state).toEqual('on');
  expect(entities.find((entityArg) => entityArg.id === 'binary_sensor.home_dns_status')?.state).toEqual('on');
  expect(entities.find((entityArg) => entityArg.id === 'sensor.home_dns_ads_blocked_today')?.state).toEqual(42);
  expect(entities.find((entityArg) => entityArg.id === 'sensor.home_dns_ads_percentage_blocked_today')?.state).toEqual(21.6);
  expect(entities.find((entityArg) => entityArg.id === 'sensor.home_dns_dns_queries_today')?.state).toEqual(200);
  expect(entities.find((entityArg) => entityArg.id === 'update.home_dns_core_update_available')?.attributes?.latestVersion).toEqual('v5.18.4');
});

tap.test('models Pi-hole enable, disable, and refresh commands without secrets', async () => {
  const disableCommand = PiHoleMapper.commandForService(v5Snapshot, {
    domain: 'switch',
    service: 'turn_off',
    target: { entityId: 'switch.home_dns' },
    data: { duration: '00:10:00' },
  });
  const enableCommand = PiHoleMapper.commandForService(v5Snapshot, {
    domain: 'pi_hole',
    service: 'enable',
    target: { deviceId: 'pi_hole.service.192_168_1_2_80' },
  });
  const refreshCommand = PiHoleMapper.commandForService(v5Snapshot, {
    domain: 'pi_hole',
    service: 'refresh',
    target: {},
  });

  expect(Boolean(disableCommand && !('error' in disableCommand))).toBeTrue();
  if (disableCommand && !('error' in disableCommand)) {
    expect(disableCommand.type).toEqual('disable');
    expect(disableCommand.path).toEqual('/admin/api.php');
    expect(disableCommand.query).toEqual({ disable: 600 });
    expect(JSON.stringify(disableCommand).includes('auth')).toBeFalse();
  }
  expect(Boolean(enableCommand && !('error' in enableCommand))).toBeTrue();
  if (enableCommand && !('error' in enableCommand)) {
    expect(enableCommand.query).toEqual({ enable: 'True' });
  }
  expect(refreshCommand && !('error' in refreshCommand) ? refreshCommand.type : undefined).toEqual('refresh');
});

tap.test('maps Pi-hole v6 nested summary and version payloads', async () => {
  const snapshot = PiHoleMapper.toSnapshot({
    config: {
      host: 'pihole.local',
      name: 'Family DNS',
      apiVersion: 6,
      rawData: {
        v6Blocking: { blocking: 'disabled' },
        v6Summary: {
          queries: { blocked: 12, percent_blocked: 24.123, total: 50, cached: 8, forwarded: 30, unique_domains: 40 },
          clients: { total: 6, active: 3 },
          gravity: { domains_being_blocked: 180000 },
        },
        v6Versions: {
          version: {
            core: { local: { version: 'v6.0', hash: 'a' }, remote: { version: 'v6.1', hash: 'b' } },
            web: { local: { version: 'v6.0', hash: 'c' }, remote: { version: 'v6.0', hash: 'c' } },
            ftl: { local: { version: 'v6.0', hash: 'd' }, remote: { version: 'v6.0', hash: 'd' } },
          },
        },
      },
    },
    online: true,
    source: 'manual',
  });
  const entities = PiHoleMapper.toEntities(snapshot);

  expect(entities.find((entityArg) => entityArg.id === 'switch.family_dns')?.state).toEqual('off');
  expect(entities.find((entityArg) => entityArg.id === 'sensor.family_dns_ads_blocked')?.state).toEqual(12);
  expect(entities.find((entityArg) => entityArg.id === 'sensor.family_dns_ads_percentage_blocked')?.state).toEqual(24.12);
  expect(entities.find((entityArg) => entityArg.id === 'sensor.family_dns_dns_queries')?.state).toEqual(50);
  expect(entities.find((entityArg) => entityArg.id === 'update.family_dns_core_update_available')?.state).toEqual('on');
});

export default tap.start();
