import { DiscoveryDescriptor } from '../../core/classes.discoverydescriptor.js';
import type {
  IDiscoveryCandidate,
  IDiscoveryContext,
  IDiscoveryMatch,
  IDiscoveryMatcher,
  IDiscoveryProbe,
  IDiscoveryProbeResult,
  IDiscoveryValidator,
} from '../../core/types.js';
import type { IHueMdnsRecord } from './hue.types.js';

export class HueBrokerDiscoveryProbe implements IDiscoveryProbe {
  public id = 'hue-broker-probe';
  public source = 'broker' as const;
  public description = 'Return Hue bridge candidates from the Hue discovery broker.';

  public async probe(contextArg: IDiscoveryContext): Promise<IDiscoveryProbeResult> {
    if (contextArg.abortSignal?.aborted) {
      return { candidates: [] };
    }
    return {
      candidates: [
        {
          source: 'broker',
          integrationDomain: 'hue',
          id: '001788fffe123456',
          host: '192.168.1.42',
          port: 443,
          manufacturer: 'Signify',
          model: 'Philips Hue Bridge',
        },
      ],
    };
  }
}

export class HueMdnsMatcher implements IDiscoveryMatcher<IHueMdnsRecord> {
  public id = 'hue-mdns-match';
  public source = 'mdns' as const;
  public description = 'Recognize Hue bridge mDNS records by bridgeid TXT data.';

  public async matches(recordArg: IHueMdnsRecord): Promise<IDiscoveryMatch> {
    const bridgeId = recordArg.txt?.bridgeid;
    if (!bridgeId) {
      return {
        matched: false,
        confidence: 'low',
        reason: 'No Hue bridge ID found.',
      };
    }

    return {
      matched: true,
      confidence: 'certain',
      reason: 'mDNS record contains Hue bridge ID.',
      normalizedDeviceId: bridgeId,
      candidate: {
        source: 'mdns',
        integrationDomain: 'hue',
        id: bridgeId,
        host: recordArg.host,
        port: recordArg.port,
        manufacturer: 'Signify',
        model: recordArg.txt?.modelid,
      },
    };
  }
}

export class HueBridgeValidator implements IDiscoveryValidator {
  public id = 'hue-bridge-validator';
  public description = 'Confirm a candidate has enough Hue bridge metadata to start setup.';

  public async validate(candidateArg: IDiscoveryCandidate): Promise<IDiscoveryMatch> {
    const isHue = candidateArg.integrationDomain === 'hue' || candidateArg.manufacturer === 'Signify';
    if (!isHue || !candidateArg.host) {
      return {
        matched: false,
        confidence: 'low',
        reason: 'Candidate lacks Hue metadata or host information.',
      };
    }
    return {
      matched: true,
      confidence: candidateArg.id ? 'certain' : 'high',
      reason: 'Candidate can be configured as a Hue bridge.',
      candidate: candidateArg,
      normalizedDeviceId: candidateArg.id,
    };
  }
}

export const createHueDiscoveryDescriptor = (): DiscoveryDescriptor => {
  return new DiscoveryDescriptor({
    integrationDomain: 'hue',
    displayName: 'Philips Hue',
  })
    .addProbe(new HueBrokerDiscoveryProbe())
    .addMatcher(new HueMdnsMatcher())
    .addValidator(new HueBridgeValidator());
};
