import * as plugins from '../../plugins.js';
import type { IIntegrationEntity, IIntegrationEvent } from '../../core/types.js';
import type { IDlnaDmrEvent, IDlnaDmrSnapshot, TDlnaDmrMediaPlayerState } from './dlna_dmr.types.js';

const mediaTypeMap: Record<string, string> = {
  object: 'url',
  'object.item': 'url',
  'object.item.imageItem': 'image',
  'object.item.imageItem.photo': 'image',
  'object.item.audioItem': 'music',
  'object.item.audioItem.musicTrack': 'music',
  'object.item.audioItem.audioBroadcast': 'music',
  'object.item.audioItem.audioBook': 'podcast',
  'object.item.videoItem': 'video',
  'object.item.videoItem.movie': 'movie',
  'object.item.videoItem.videoBroadcast': 'tvshow',
  'object.item.videoItem.musicVideoClip': 'video',
  'object.item.playlistItem': 'playlist',
  'object.container': 'playlist',
  'object.container.album': 'album',
  'object.container.album.musicAlbum': 'album',
  'object.container.person.musicArtist': 'artist',
  'object.container.genre.musicGenre': 'genre',
};

export class DlnaDmrMapper {
  public static toDevices(snapshotArg: IDlnaDmrSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
    const updatedAt = snapshotArg.state.updatedAt || new Date().toISOString();
    const features: plugins.shxInterfaces.data.IDeviceFeature[] = [
      { 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: 'current_uri', capability: 'media', name: 'Current URI', readable: true, writable: true },
      { id: 'current_title', capability: 'media', name: 'Current title', readable: true, writable: false },
    ];
    const state: plugins.shxInterfaces.data.IDeviceState[] = [
      { featureId: 'playback', value: this.mediaState(snapshotArg), updatedAt },
      { featureId: 'volume', value: snapshotArg.state.rendering.volume ?? null, updatedAt },
      { featureId: 'muted', value: snapshotArg.state.rendering.muted ?? null, updatedAt },
      { featureId: 'current_uri', value: snapshotArg.state.media.currentTrackUri || snapshotArg.state.media.currentUri || null, updatedAt },
      { featureId: 'current_title', value: this.mediaTitle(snapshotArg) || null, updatedAt },
    ];

    if (snapshotArg.state.rendering.presets?.length) {
      features.push({ id: 'source', capability: 'media', name: 'Source', readable: true, writable: true });
      state.push({ featureId: 'source', value: snapshotArg.state.rendering.selectedPreset || null, updatedAt });
    }

    return [{
      id: this.deviceId(snapshotArg),
      integrationDomain: 'dlna_dmr',
      name: this.deviceName(snapshotArg),
      protocol: 'http',
      manufacturer: snapshotArg.device.manufacturer || 'DLNA',
      model: snapshotArg.device.modelName || snapshotArg.device.modelNumber,
      online: snapshotArg.state.online,
      features,
      state,
      metadata: {
        udn: snapshotArg.device.udn,
        deviceType: snapshotArg.device.deviceType,
        location: snapshotArg.device.location,
        serialNumber: snapshotArg.device.serialNumber,
        macAddress: snapshotArg.device.macAddress,
        sinkProtocolInfo: snapshotArg.state.sinkProtocolInfo,
      },
    }];
  }

  public static toEntities(snapshotArg: IDlnaDmrSnapshot): IIntegrationEntity[] {
    return [{
      id: `media_player.${this.slug(this.deviceName(snapshotArg))}`,
      uniqueId: `dlna_dmr_${this.uniqueBase(snapshotArg)}`,
      integrationDomain: 'dlna_dmr',
      deviceId: this.deviceId(snapshotArg),
      platform: 'media_player',
      name: this.deviceName(snapshotArg),
      state: this.mediaState(snapshotArg),
      attributes: {
        volumeLevel: typeof snapshotArg.state.rendering.volume === 'number' ? snapshotArg.state.rendering.volume / 100 : undefined,
        isVolumeMuted: snapshotArg.state.rendering.muted,
        source: snapshotArg.state.rendering.selectedPreset,
        sourceList: snapshotArg.state.rendering.presets,
        mediaContentId: snapshotArg.state.media.currentTrackUri || snapshotArg.state.media.currentUri,
        mediaContentType: this.mediaContentType(snapshotArg),
        mediaDuration: snapshotArg.state.media.position?.trackDurationSeconds ?? snapshotArg.state.media.metadata?.duration,
        mediaPosition: snapshotArg.state.media.position?.relativeTimeSeconds,
        mediaTitle: this.mediaTitle(snapshotArg),
        mediaArtist: snapshotArg.state.media.metadata?.artist,
        mediaAlbumName: snapshotArg.state.media.metadata?.album,
        mediaAlbumArtist: snapshotArg.state.media.metadata?.albumArtist,
        mediaImageUrl: snapshotArg.state.media.metadata?.albumArtUri,
        currentTransportActions: snapshotArg.state.transport.currentTransportActions,
        currentPlayMode: snapshotArg.state.transport.currentPlayMode,
      },
      available: snapshotArg.state.online,
    }];
  }

  public static toIntegrationEvent(eventArg: IDlnaDmrEvent): IIntegrationEvent {
    return {
      type: 'state_changed',
      integrationDomain: 'dlna_dmr',
      data: eventArg,
      timestamp: Date.now(),
    };
  }

  public static mediaState(snapshotArg: IDlnaDmrSnapshot): TDlnaDmrMediaPlayerState {
    if (!snapshotArg.state.online) {
      return 'off';
    }
    const state = snapshotArg.state.transport.currentTransportState;
    if (state === 'PLAYING' || state === 'TRANSITIONING') {
      return 'playing';
    }
    if (state === 'PAUSED_PLAYBACK' || state === 'PAUSED_RECORDING') {
      return 'paused';
    }
    if (!state) {
      return 'on';
    }
    if (state === 'VENDOR_DEFINED') {
      return 'unknown';
    }
    return 'idle';
  }

  private static mediaContentType(snapshotArg: IDlnaDmrSnapshot): string | undefined {
    const upnpClass = snapshotArg.state.media.metadata?.upnpClass || snapshotArg.state.media.mediaClass;
    return upnpClass ? mediaTypeMap[upnpClass] || 'url' : undefined;
  }

  private static mediaTitle(snapshotArg: IDlnaDmrSnapshot): string | undefined {
    return snapshotArg.state.media.metadata?.title || snapshotArg.state.media.currentTrackUri || snapshotArg.state.media.currentUri;
  }

  private static deviceId(snapshotArg: IDlnaDmrSnapshot): string {
    return `dlna_dmr.renderer.${this.uniqueBase(snapshotArg)}`;
  }

  private static uniqueBase(snapshotArg: IDlnaDmrSnapshot): string {
    return this.slug(snapshotArg.device.udn || snapshotArg.device.location || this.deviceName(snapshotArg));
  }

  private static deviceName(snapshotArg: IDlnaDmrSnapshot): string {
    return snapshotArg.device.friendlyName || 'DLNA Digital Media Renderer';
  }

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