package com.smplayer.media3_engine

import android.content.Context
import android.graphics.Color
import android.view.Gravity
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.View
import android.widget.FrameLayout
import androidx.media3.ui.SubtitleView
import io.flutter.plugin.common.StandardMessageCodec
import io.flutter.plugin.platform.PlatformView
import io.flutter.plugin.platform.PlatformViewFactory


internal class Media3PlatformView(
    context: Context,
    private val playerId: Int,
    private val getPlayer: (Int) -> Media3PlayerInstance?,
) : PlatformView, SurfaceHolder.Callback {

    private val rootView: FrameLayout = FrameLayout(context).apply {
        setBackgroundColor(Color.BLACK)
    }
    private val aspectLayout: Media3AspectRatioFrameLayout = Media3AspectRatioFrameLayout(context)
    private val surfaceView: SurfaceView = SurfaceView(context)
    private val subtitleView: SubtitleView = SubtitleView(context)


    private val shutterView: View = View(context).apply {
        setBackgroundColor(Color.BLACK)
    }

    init {
        aspectLayout.addView(
            surfaceView,
            FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT,
            ),
        )
        aspectLayout.addView(
            subtitleView,
            FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT,
            ),
        )
        rootView.addView(
            aspectLayout,
            FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT,
                Gravity.CENTER,
            ),
        )
        rootView.addView(
            shutterView,
            FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                FrameLayout.LayoutParams.MATCH_PARENT,
            ),
        )
        surfaceView.holder.addCallback(this)
        getPlayer(playerId)?.attachView(aspectLayout)
        getPlayer(playerId)?.attachSubtitleView(subtitleView)
        getPlayer(playerId)?.attachShutter(shutterView)
    }

    override fun getView(): View = rootView

    override fun dispose() {
        surfaceView.holder.removeCallback(this)
        getPlayer(playerId)?.detachShutter(shutterView)
        getPlayer(playerId)?.detachSubtitleView(subtitleView)
        getPlayer(playerId)?.detachView(aspectLayout)
        getPlayer(playerId)?.detachSurface()
    }


    override fun surfaceCreated(holder: SurfaceHolder) {
        android.util.Log.i(TAG, "surfaceCreated playerId=$playerId valid=${holder.surface.isValid}")
        getPlayer(playerId)?.attachSurface(holder.surface)
    }

    override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
        android.util.Log.i(TAG, "surfaceChanged playerId=$playerId ${width}x$height format=$format")

    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        android.util.Log.i(TAG, "surfaceDestroyed playerId=$playerId")
        getPlayer(playerId)?.detachSurface()
    }

    companion object {
        private const val TAG = "Media3PlatformView"
    }
}


internal class Media3PlatformViewFactory(
    private val getPlayer: (Int) -> Media3PlayerInstance?,
) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {

    override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
        val params = args as? Map<*, *>
        val playerId = (params?.get("playerId") as? Number)?.toInt() ?: -1
        return Media3PlatformView(context, playerId, getPlayer)
    }
}
