import { createServer } from 'node:http';
import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DoorbirdClient, DoorbirdIntegration } from '../../ts/integrations/doorbird/index.js';

tap.test('reads DoorBird data and executes relay/light over native local HTTP', async () => {
  const requests: Array<{ url: string; method?: string; authorization?: string }> = [];
  const server = createServer((requestArg, responseArg) => {
    requests.push({ url: requestArg.url || '', method: requestArg.method, authorization: requestArg.headers.authorization });
    if (!requestArg.headers.authorization) {
      responseArg.statusCode = 401;
      responseArg.setHeader('www-authenticate', 'Basic realm="DoorBird"');
      responseArg.end('auth required');
      return;
    }
    if (requestArg.headers.authorization !== `Basic ${Buffer.from('user:secret').toString('base64')}`) {
      responseArg.statusCode = 401;
      responseArg.end('bad credentials');
      return;
    }

    if (requestArg.url === '/bha-api/info.cgi') {
      responseArg.setHeader('content-type', 'application/json');
      responseArg.end(JSON.stringify({ BHA: { RETURNCODE: '1', VERSION: [{ FIRMWARE: '000122', BUILD_NUMBER: '42', 'DEVICE-TYPE': 'D1101V', PRIMARY_MAC_ADDR: '1CCAE3AABBCC', RELAYS: ['1', '2'] }] } }));
      return;
    }
    if (requestArg.url === '/bha-api/monitor.cgi?check=doorbell') {
      responseArg.setHeader('content-type', 'text/plain');
      responseArg.end('doorbell=1');
      return;
    }
    if (requestArg.url === '/bha-api/monitor.cgi?check=motionsensor') {
      responseArg.setHeader('content-type', 'text/plain');
      responseArg.end('motionsensor=0');
      return;
    }
    if (requestArg.url === '/bha-api/favorites.cgi') {
      responseArg.setHeader('content-type', 'application/json');
      responseArg.end(JSON.stringify({ http: { '1': { title: 'Home Assistant (front_door_doorbell)', value: 'http://ha/api/doorbird/front?token=abc' } } }));
      return;
    }
    if (requestArg.url === '/bha-api/schedule.cgi') {
      responseArg.setHeader('content-type', 'application/json');
      responseArg.end(JSON.stringify([{ input: 'doorbell', param: '', output: [{ enabled: '1', event: 'http', param: '1', schedule: { weekdays: [{ from: '104400', to: '104399' }] } }] }]));
      return;
    }
    if (requestArg.url === '/bha-api/image.cgi') {
      responseArg.setHeader('content-type', 'image/jpeg');
      responseArg.end(Buffer.from([1, 2, 3, 4]));
      return;
    }
    if (requestArg.url === '/bha-api/open-door.cgi?r=2') {
      responseArg.setHeader('content-type', 'application/json');
      responseArg.end(JSON.stringify({ BHA: { RETURNCODE: '1' } }));
      return;
    }
    if (requestArg.url === '/bha-api/light-on.cgi') {
      responseArg.setHeader('content-type', 'application/json');
      responseArg.end(JSON.stringify({ BHA: { RETURNCODE: '1' } }));
      return;
    }
    responseArg.statusCode = 404;
    responseArg.end('not found');
  });

  await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve));
  try {
    const address = server.address();
    const port = typeof address === 'object' && address ? address.port : 0;
    const supported = await DoorbirdClient.verifySupportedDevice('127.0.0.1', port, 1000);
    const client = new DoorbirdClient({ host: '127.0.0.1', port, username: 'user', password: 'secret', timeoutMs: 1000, snapshotTimeoutMs: 1000, name: 'Front Door' });
    const snapshot = await client.getSnapshot();
    const image = await client.getSnapshotImage('live');
    const relay = await client.execute({ action: 'energize_relay', relay: '2' });
    const light = await client.execute({ action: 'turn_light_on' });

    expect(supported).toBeTrue();
    expect(snapshot.online).toBeTrue();
    expect(snapshot.source).toEqual('http');
    expect(snapshot.deviceInfo.macAddress).toEqual('1ccae3aabbcc');
    expect(snapshot.status.doorbell).toBeTrue();
    expect(snapshot.status.motion).toBeFalse();
    expect(snapshot.favorites?.http?.['1'].title).toContain('Home Assistant');
    expect(snapshot.schedule?.[0].input).toEqual('doorbell');
    expect(image.contentType).toEqual('image/jpeg');
    expect(Buffer.from(image.data).toString('hex')).toEqual('01020304');
    expect(relay).toEqual({ ok: true, relay: '2' });
    expect(light).toEqual({ ok: true });
    expect(requests.some((requestArg) => requestArg.url === '/bha-api/monitor.cgi?check=doorbell' && !requestArg.authorization)).toBeTrue();
    expect(requests.some((requestArg) => requestArg.url === '/bha-api/info.cgi' && requestArg.authorization?.startsWith('Basic '))).toBeTrue();
    await client.destroy();
  } finally {
    await new Promise<void>((resolve, reject) => server.close((errorArg) => errorArg ? reject(errorArg) : resolve()));
  }
});

tap.test('runtime status/snapshot services use snapshots without claiming command success', async () => {
  const runtime = await new DoorbirdIntegration().setup({ rawInfo: { PRIMARY_MAC_ADDR: '1CCAE3AABBCC', RELAYS: ['1'] }, status: { doorbell: false, motion: false }, name: 'Manual DoorBird' }, {});
  const status = await runtime.callService?.({ domain: 'doorbird', service: 'status', target: {} });
  const command = await runtime.callService?.({ domain: 'doorbird', service: 'turn_light_on', target: {} });

  expect(status?.success).toBeTrue();
  expect((status?.data as { doorbell?: boolean }).doorbell).toBeFalse();
  expect(command?.success).toBeFalse();
  expect(command?.error).toContain('config.host');
  await runtime.destroy();
});

export default tap.start();
