package com.unibuy.smartdevice.ui.tools;

import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.widget.ImageView;

import androidx.annotation.OptIn;
import androidx.media3.common.MediaItem;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.DefaultDataSource;
import androidx.media3.exoplayer.DefaultLoadControl;
import androidx.media3.exoplayer.DefaultRenderersFactory;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
import androidx.media3.extractor.DefaultExtractorsFactory;
import androidx.media3.ui.PlayerView;

import com.bumptech.glide.Glide;
import com.unibuy.smartdevice.exception.Logs;

import java.io.File;
import java.util.List;
import java.util.concurrent.Executors;

public class VideoImageMixedPlayer {

    public static class AdItem {
        public String url;
        public int duration; // 秒

        public AdItem(String url, int duration) {
            this.url = url;
            this.duration = duration;
        }
    }

    private final Logs logs;
    private final Context context;
    private final List<AdItem> adItems;

    private ExoPlayer exoPlayer;
    private PlayerView playerView;
    private ImageView imageView;
    private Handler handler;
    private int currentIndex = 0;

    public VideoImageMixedPlayer(Context context, List<AdItem> adItems) {
        this.context = context;
        this.adItems = adItems;
        this.logs = new Logs(getClass());
        this.handler = new Handler(Looper.getMainLooper());
    }

    public void start(PlayerView playerView, ImageView imageView) {
        this.playerView = playerView;
        this.imageView = imageView;
        currentIndex = 0;
        playNext();
    }

    private void playNext() {
        if (adItems == null || adItems.isEmpty()) {
            logs.info("Ads沒有任何媒體可以播放！清空視圖 (flag-based)...");
            if (playerView != null) {
                playerView.setVisibility(android.view.View.GONE);
                playerView.setPlayer(null);
            }
            if (imageView != null) {
                imageView.setVisibility(android.view.View.GONE);
                imageView.setImageDrawable(null); // 清除舊圖片
            }
            releaseExoPlayer();
            return;
        }

        logs.info("Ads 目前播放索引: " + currentIndex + " / 總數: " + adItems.size());

        if (currentIndex >= adItems.size()) {
            currentIndex = 0;
        }

        AdItem item = adItems.get(currentIndex);
        String url = item.url;

        // 先檢查快取
        String cachedPath = MediaCacheHelper.getCachedPath(context, url);

        if (cachedPath != null) {
            logs.info("Ads使用快取檔: " + cachedPath);
            playMedia(cachedPath);
        } else {
            logs.info("Ads快取不存在，開始下載: " + url);

            // 背景下載，下載完成立即播放
            MediaCacheHelper.downloadFileAsync(context, url, downloadedPath -> {
                if (downloadedPath != null) {
                    logs.info("Ads下載完成，播放本地檔: " + downloadedPath);
                    playMedia(downloadedPath);
                } else {
                    logs.info("Ads下載失敗，使用線上 URL 播放: " + url);
                    playMedia(url);
                }
            });
        }
    }

    private void playMedia(String path) {
        if (isVideo(path)) {
            playVideo(path);
        } else {
            playImage(path);
        }
    }

    @OptIn(markerClass = UnstableApi.class)
    private void playVideo(String path) {
        releaseExoPlayer();

        DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(context)
                .setEnableDecoderFallback(true)
                .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER);

        DefaultLoadControl loadControl = new DefaultLoadControl.Builder()
                .setBufferDurationsMs(5000, 50000, 3000, 5000)
                .build();

        exoPlayer = new ExoPlayer.Builder(context)
                .setRenderersFactory(renderersFactory)
                .setLoadControl(loadControl)
                .build();

        playerView.setPlayer(exoPlayer);
        imageView.setVisibility(ImageView.GONE);
        playerView.setVisibility(PlayerView.VISIBLE);

        DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
        ProgressiveMediaSource.Factory mediaSourceFactory = new ProgressiveMediaSource.Factory(
                new DefaultDataSource.Factory(context), extractorsFactory);

        MediaItem item;
        if (path.startsWith("/")) {
            item = MediaItem.fromUri(Uri.fromFile(new File(path)));
        } else {
            item = MediaItem.fromUri(Uri.parse(path));
        }

        MediaSource source = mediaSourceFactory.createMediaSource(item);
        exoPlayer.setMediaSource(source);
        exoPlayer.prepare();
        exoPlayer.setPlayWhenReady(true);

        // ✅ 使用設定的秒數控制影片播放時間，到時間就強制切下一個
        int duration = adItems.get(currentIndex).duration;
        if (duration <= 0) duration = 10;
        final Runnable forceNextRunnable = () -> {
            logs.info("影片播放到設定秒數 (" + adItems.get(currentIndex).duration + "s)，強制切下一個廣告");
            releaseExoPlayer();
            currentIndex = (currentIndex + 1) % adItems.size();
            playNext();
        };
        handler.postDelayed(forceNextRunnable, duration * 1000L);

        exoPlayer.addListener(new Player.Listener() {
            @Override
            public void onPlaybackStateChanged(int state) {
                if (state == Player.STATE_ENDED) {
                    // 影片自然播放結束，取消強制計時器，直接切下一個
                    handler.removeCallbacks(forceNextRunnable);
                    nextSchedule(1000);
                }
            }

            @Override
            public void onPlayerError(PlaybackException error) {
                logs.info("影片播放錯誤: " + error.getMessage());
                handler.removeCallbacks(forceNextRunnable);
                nextSchedule(1000);
            }
        });
    }

    private void playImage(String path) {
        releaseExoPlayer();
        playerView.setVisibility(PlayerView.GONE);
        imageView.setVisibility(ImageView.VISIBLE);

        Object source = path.startsWith("/") ? new File(path) : path;

        // ✅ 增加生命週期檢查，避免 Glide 在 Activity 銷毀後嘗試載入導致崩潰
        if (context instanceof android.app.Activity) {
            android.app.Activity activity = (android.app.Activity) context;
            if (activity.isFinishing() || (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed())) {
                logs.info("⚠️ Activity 已銷毀，跳過圖片載入: " + path);
                return;
            }
        }

        Glide.with(context)
                .load(source)
                .fitCenter()
                .into(imageView);

        // 使用動態秒數，若為 0 則預設 10 秒
        int duration = adItems.get(currentIndex).duration;
        if (duration <= 0) duration = 10;
        nextSchedule(duration * 1000L); 
    }

    private void nextSchedule(long delayMs) {
        handler.postDelayed(() -> {
            currentIndex = (currentIndex + 1) % adItems.size();
            playNext();
        }, delayMs);
    }

    private void releaseExoPlayer() {
        if (exoPlayer != null) {
            exoPlayer.stop();
            exoPlayer.release();
            exoPlayer = null;
            playerView.setPlayer(null);
        }
    }

    public void stop() {
        logs.info("Ads 播放器停止，清空視圖");
        releaseExoPlayer();
        if (playerView != null) {
            playerView.setVisibility(android.view.View.GONE);
            playerView.setPlayer(null);
        }
        if (imageView != null) {
            imageView.setVisibility(android.view.View.GONE);
            imageView.setImageDrawable(null);
        }
        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
        }
    }

    private boolean isVideo(String url) {
        String lower = url.toLowerCase();
        return lower.endsWith(".mp4") || lower.endsWith(".webm") || lower.endsWith(".mkv");
    }

    public static void clearAdsCache(Context context) {
        File cacheDir = new File(context.getFilesDir(), "ads");
        if (cacheDir.exists()) {
            for (File file : cacheDir.listFiles()) {
                file.delete();
            }
        }
    }
}
