import * as plugins from '../../plugins.js';
import type { IIntegrationEntity } from '../../core/types.js';
import type { IRokuSnapshot } from './roku.types.js';

export class RokuMapper {
  public static toDevices(snapshotArg: IRokuSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
    const updatedAt = new Date().toISOString();
    return [{
      id: this.deviceId(snapshotArg),
      integrationDomain: 'roku',
      name: this.deviceName(snapshotArg),
      protocol: 'http',
      manufacturer: snapshotArg.deviceInfo.vendorName || 'Roku',
      model: snapshotArg.deviceInfo.modelName || snapshotArg.deviceInfo.modelNumber,
      online: true,
      features: [
        { id: 'power', capability: 'media', name: 'Power', readable: true, writable: true },
        { id: 'active_app', capability: 'media', name: 'Active app', readable: true, writable: true },
        { id: 'remote_key', capability: 'media', name: 'Remote key', readable: false, writable: true },
      ],
      state: [
        { featureId: 'power', value: this.powerState(snapshotArg), updatedAt },
        { featureId: 'active_app', value: snapshotArg.activeApp?.name || null, updatedAt },
      ],
      metadata: {
        serialNumber: snapshotArg.deviceInfo.serialNumber,
        deviceId: snapshotArg.deviceInfo.deviceId,
        deviceType: snapshotArg.deviceInfo.deviceType,
        softwareVersion: snapshotArg.deviceInfo.softwareVersion,
        apps: snapshotArg.apps.map((appArg) => ({ id: appArg.id, name: appArg.name })),
      },
    }];
  }

  public static toEntities(snapshotArg: IRokuSnapshot): IIntegrationEntity[] {
    return [{
      id: `media_player.${this.slug(this.deviceName(snapshotArg))}`,
      uniqueId: `roku_${this.slug(snapshotArg.deviceInfo.deviceId || snapshotArg.deviceInfo.serialNumber || this.deviceName(snapshotArg))}`,
      integrationDomain: 'roku',
      deviceId: this.deviceId(snapshotArg),
      platform: 'media_player',
      name: this.deviceName(snapshotArg),
      state: this.mediaState(snapshotArg),
      attributes: {
        source: snapshotArg.activeApp?.name,
        appId: snapshotArg.activeApp?.id,
        sourceList: ['Home', ...snapshotArg.apps.map((appArg) => appArg.name)],
        powerMode: snapshotArg.deviceInfo.powerMode,
      },
      available: true,
    }];
  }

  private static mediaState(snapshotArg: IRokuSnapshot): string {
    if (this.powerState(snapshotArg) === 'off') {
      return 'off';
    }
    const activeName = snapshotArg.activeApp?.name;
    if (!activeName || activeName === 'Power Saver' || activeName === 'Roku') {
      return 'idle';
    }
    return 'on';
  }

  private static powerState(snapshotArg: IRokuSnapshot): string {
    const powerMode = snapshotArg.deviceInfo.powerMode?.toLowerCase() || '';
    if (powerMode.includes('off') || powerMode.includes('standby') || powerMode.includes('suspend')) {
      return 'off';
    }
    return 'on';
  }

  private static deviceId(snapshotArg: IRokuSnapshot): string {
    return `roku.device.${this.slug(snapshotArg.deviceInfo.deviceId || snapshotArg.deviceInfo.serialNumber || this.deviceName(snapshotArg))}`;
  }

  private static deviceName(snapshotArg: IRokuSnapshot): string {
    return snapshotArg.deviceInfo.userDeviceName || snapshotArg.deviceInfo.friendlyDeviceName || snapshotArg.deviceInfo.modelName || 'Roku';
  }

  private static slug(valueArg: string): string {
    return valueArg.toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '') || 'roku';
  }
}
