package com.nadi.player.nativeplayer;

import androidx.annotation.OptIn;
import androidx.media3.common.ForwardingPlayer;
import androidx.media3.common.MediaItem;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.ExoPlayer;

import com.nadi.player.nativeplayer.channels.Channel;
import com.nadi.player.nativeplayer.channels.ChannelStore;

/**
 * A {@link ForwardingPlayer} that turns the standard "next / previous
 * media item" Player commands into IPTV channel zapping.
 *
 * Why this matters:
 *   The MediaSession exposes {@code COMMAND_SEEK_TO_NEXT_MEDIA_ITEM} /
 *   {@code _PREVIOUS_MEDIA_ITEM} to every controller — the lock-screen
 *   notification, Bluetooth headset ⏭/⏮, Android Auto, Google Assistant
 *   ("OK Google, next track"), wearables, AND our home-screen widget.
 *   By default Media3 wires those buttons to ExoPlayer's playlist
 *   navigation; but ExoPlayer's playlist is just the single live
 *   channel currently playing, so the buttons would do nothing.
 *
 *   This wrapper intercepts seek-next / seek-previous and replaces the
 *   underlying player's MediaItem with the next channel from
 *   {@link ChannelStore}. Same fast-zap path PlayerActivity uses for
 *   in-app UP/DOWN, just routed through Media3's standard surfaces.
 *
 * Also overrides {@link #hasNextMediaItem()} / {@link #hasPreviousMediaItem()}
 * and {@link #getAvailableCommands()} so the controls actually appear
 * (and are enabled) on the lock-screen notification.
 */
@OptIn(markerClass = UnstableApi.class)
public final class ChannelAwarePlayer extends ForwardingPlayer {

    private final ExoPlayer delegate;

    public ChannelAwarePlayer(ExoPlayer delegate) {
        super(delegate);
        this.delegate = delegate;
    }

    /* === Surfacing the buttons on lock-screen / notification === */

    @Override
    public boolean hasNextMediaItem() {
        return !ChannelStore.get().isEmpty();
    }

    @Override
    public boolean hasPreviousMediaItem() {
        return !ChannelStore.get().isEmpty();
    }

    @Override
    public Commands getAvailableCommands() {
        Commands base = super.getAvailableCommands();
        if (ChannelStore.get().isEmpty()) return base;
        return base.buildUpon()
                .add(Player.COMMAND_SEEK_TO_NEXT)
                .add(Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM)
                .add(Player.COMMAND_SEEK_TO_PREVIOUS)
                .add(Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM)
                .build();
    }

    /* === Re-routing the buttons to fast-zap === */

    @Override public void seekToNext()             { zap(+1); }
    @Override public void seekToNextMediaItem()    { zap(+1); }
    @Override public void seekToPrevious()         { zap(-1); }
    @Override public void seekToPreviousMediaItem(){ zap(-1); }

    private void zap(int delta) {
        Channel ch = delta > 0
                ? ChannelStore.get().zapNext()
                : ChannelStore.get().zapPrevious();
        if (ch == null || ch.streamUrl == null || ch.streamUrl.isEmpty()) return;
        // Reuse the existing PlaybackService MediaItem builder so .m3u8 /
        // .ts / .mp4 MIME detection and live-config stay identical.
        MediaItem item = PlaybackService.buildLiveMediaItem(ch.streamUrl, ch.name);
        delegate.setMediaItem(item);
        delegate.setPlayWhenReady(true);
        delegate.prepare();
    }
}
