import type * as shxInterfaces from '@smarthome.exchange/interfaces';
import { SimpleLocalMapper, type IIntegrationEntity, type IIntegrationEvent, type ISimpleLocalSnapshot, type ISimpleLocalSnapshotOptions, type TSimpleLocalRawData } from '../../core/index.js';
import type { IPilightConfig } from './pilight.types.js';
import { pilightProfile } from './pilight.types.js';

export class PilightMapper {
  public static toSnapshot(optionsArg: Omit<ISimpleLocalSnapshotOptions<IPilightConfig>, 'profile'>): ISimpleLocalSnapshot {
    return SimpleLocalMapper.toSnapshot({ ...optionsArg, profile: pilightProfile });
  }

  public static toSnapshotFromRaw(configArg: IPilightConfig, rawDataArg: TSimpleLocalRawData): ISimpleLocalSnapshot {
    return SimpleLocalMapper.toSnapshot({ profile: pilightProfile, config: configArg, rawData: rawDataArg, online: true, source: 'manual' });
  }

  public static toDevices(snapshotArg: ISimpleLocalSnapshot): shxInterfaces.data.IDeviceDefinition[] {
    return SimpleLocalMapper.toDevices(pilightProfile, snapshotArg);
  }

  public static toEntities(snapshotArg: ISimpleLocalSnapshot): IIntegrationEntity[] {
    return SimpleLocalMapper.toEntities(pilightProfile, snapshotArg);
  }

  public static toIntegrationEvent(messageArg: Record<string, unknown>): IIntegrationEvent {
    return {
      type: 'state_changed',
      integrationDomain: pilightProfile.domain,
      data: this.flattenReceivedMessage(messageArg),
      timestamp: Date.now(),
    };
  }

  public static flattenReceivedMessage(messageArg: Record<string, unknown>): Record<string, unknown> {
    const message = messageArg.message && typeof messageArg.message === 'object' && !Array.isArray(messageArg.message) ? messageArg.message as Record<string, unknown> : {};
    return cleanAttributes({
      protocol: messageArg.protocol ?? message.protocol,
      uuid: messageArg.uuid,
      origin: messageArg.origin,
      repeats: messageArg.repeats,
      ...message,
      raw: messageArg,
    });
  }

  public static slug(valueArg: unknown): string {
    return SimpleLocalMapper.slug(valueArg);
  }
}

const cleanAttributes = (attributesArg: Record<string, unknown>): Record<string, unknown> => {
  return Object.fromEntries(Object.entries(attributesArg).filter(([, valueArg]) => valueArg !== undefined));
};
