import * as plugins from '../../plugins.js';
import type { IIntegrationEntity } from '../../core/types.js';
import type { ICastApplication, ICastMediaMetadata, ICastSnapshot } from './cast.types.js';

export class CastMapper {
  public static toDevices(snapshotArg: ICastSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
    const updatedAt = new Date().toISOString();
    const volume = snapshotArg.receiverStatus?.volume;
    const media = snapshotArg.mediaStatus?.media;
    return [{
      id: this.deviceId(snapshotArg),
      integrationDomain: 'cast',
      name: this.deviceName(snapshotArg),
      protocol: 'http',
      manufacturer: snapshotArg.deviceInfo.manufacturer || 'Google',
      model: snapshotArg.deviceInfo.modelName,
      online: true,
      features: [
        { id: 'playback', capability: 'media', name: 'Playback', readable: true, writable: true },
        { id: 'volume', capability: 'media', name: 'Volume', readable: true, writable: true, unit: '%' },
        { id: 'muted', capability: 'media', name: 'Muted', readable: true, writable: true },
        { id: 'active_app', capability: 'media', name: 'Active app', readable: true, writable: true },
        { id: 'current_title', capability: 'media', name: 'Current title', readable: true, writable: false },
      ],
      state: [
        { featureId: 'playback', value: this.mediaState(snapshotArg), updatedAt },
        { featureId: 'volume', value: typeof volume?.level === 'number' ? Math.round(volume.level * 100) : null, updatedAt },
        { featureId: 'muted', value: typeof volume?.muted === 'boolean' ? volume.muted : null, updatedAt },
        { featureId: 'active_app', value: this.activeApp(snapshotArg)?.displayName || null, updatedAt },
        { featureId: 'current_title', value: this.metadata(snapshotArg).title || media?.contentId || null, updatedAt },
      ],
      metadata: {
        uuid: snapshotArg.deviceInfo.uuid,
        castType: snapshotArg.deviceInfo.castType,
        buildVersion: snapshotArg.deviceInfo.buildVersion,
        firmwareVersion: snapshotArg.deviceInfo.firmwareVersion,
        appId: this.activeApp(snapshotArg)?.appId,
      },
    }];
  }

  public static toEntities(snapshotArg: ICastSnapshot): IIntegrationEntity[] {
    const media = snapshotArg.mediaStatus?.media;
    const metadata = this.metadata(snapshotArg);
    return [{
      id: `media_player.${this.slug(this.deviceName(snapshotArg))}`,
      uniqueId: `cast_${this.slug(snapshotArg.deviceInfo.uuid || this.deviceName(snapshotArg))}`,
      integrationDomain: 'cast',
      deviceId: this.deviceId(snapshotArg),
      platform: 'media_player',
      name: this.deviceName(snapshotArg),
      state: this.mediaState(snapshotArg),
      attributes: {
        volumeLevel: snapshotArg.receiverStatus?.volume?.level,
        muted: snapshotArg.receiverStatus?.volume?.muted,
        appId: this.activeApp(snapshotArg)?.appId,
        appName: this.activeApp(snapshotArg)?.displayName,
        mediaTitle: metadata.title,
        mediaArtist: metadata.artist,
        mediaAlbumName: metadata.albumName,
        mediaContentId: media?.contentId,
        mediaContentType: media?.contentType,
        mediaDuration: media?.duration,
        mediaPosition: snapshotArg.mediaStatus?.currentTime,
        mediaImageUrl: metadata.images?.[0]?.url || media?.images?.[0]?.url,
        source: this.activeApp(snapshotArg)?.displayName,
      },
      available: true,
    }];
  }

  private static mediaState(snapshotArg: ICastSnapshot): string {
    if (snapshotArg.receiverStatus?.isActiveInput === false) {
      return 'off';
    }
    const playerState = snapshotArg.mediaStatus?.playerState;
    if (playerState === 'PLAYING') {
      return 'playing';
    }
    if (playerState === 'BUFFERING') {
      return 'buffering';
    }
    if (playerState === 'PAUSED') {
      return 'paused';
    }
    if (playerState === 'IDLE') {
      return 'idle';
    }
    return this.activeApp(snapshotArg) ? 'idle' : 'off';
  }

  private static activeApp(snapshotArg: ICastSnapshot): ICastApplication | undefined {
    return snapshotArg.receiverStatus?.applications?.[0];
  }

  private static metadata(snapshotArg: ICastSnapshot): ICastMediaMetadata {
    return snapshotArg.mediaStatus?.media?.metadata || {};
  }

  private static deviceId(snapshotArg: ICastSnapshot): string {
    return `cast.device.${this.slug(snapshotArg.deviceInfo.uuid || this.deviceName(snapshotArg))}`;
  }

  private static deviceName(snapshotArg: ICastSnapshot): string {
    return snapshotArg.deviceInfo.friendlyName || snapshotArg.deviceInfo.modelName || 'Google Cast';
  }

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