package com.dreamteam.timelapse

import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore
import android.util.Log
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.widget.PopupMenu
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.dreamteam.timelapse.data.ApiService
import com.dreamteam.timelapse.data.ProjectRepository
import com.dreamteam.timelapse.data.Video
import com.dreamteam.timelapse.data.VideoRepository
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.bumptech.glide.request.RequestOptions
import com.google.android.material.imageview.ShapeableImageView
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.internal.http2.Http2Reader
import okio.IOException
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream

class VideoAdapter(
    public val withProjectNames : Boolean,
    private val videos: MutableList<Video>,
    private val listener: OnEmptyStateListener?
) : RecyclerView.Adapter<VideoAdapter.VideoViewHolder>() {
    private var projectRepository: ProjectRepository;
    private var videoRepository : VideoRepository;
    init {
        val retrofit = Retrofit.Builder()
            .baseUrl("https://timelapse.kerboul.me/api/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        projectRepository = ProjectRepository(retrofit.create(ApiService::class.java))
        videoRepository = VideoRepository(retrofit.create(ApiService::class.java))
        listener?.onEmptyStateChanged(videos.isEmpty())
    }

    interface OnEmptyStateListener {
        fun onEmptyStateChanged(isEmpty: Boolean)
    }

    class VideoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val videoTitle: TextView = itemView.findViewById(R.id.videoTitle)
        val videoThumbnail: ShapeableImageView = itemView.findViewById(R.id.videoThumbnail)
        val playButton: ImageView = itemView.findViewById(R.id.playButton)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VideoViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_video, parent, false)
        return VideoViewHolder(view)
    }

    override fun onBindViewHolder(holder: VideoViewHolder, position: Int) {
        val video = videos[position]
        val context = holder.itemView.context
        holder.videoTitle.text = video.name
        if(withProjectNames){
            projectRepository.fetchProject(video.project_id, { p->
                holder.videoTitle.text = video.name + " (" + p.name + ")"
            }, { s->
                Log.e("VideoAdapter", s)
            })
        }

        // Load video thumbnail
        val url = "https://timelapse.kerboul.me/api/videos/file/${video.id}"


        Glide.with(context)
            .load(url) // Load the video URL
            .frame(0)
            .placeholder(R.drawable.not_found) // Optional placeholder
            .into(holder.videoThumbnail)

        // Click listener to open video player
        holder.itemView.setOnClickListener {
            val intent = Intent(context, VideoPlayerActivity::class.java)
            intent.putExtra("VIDEO_URL", url) // Pass video URL
            intent.setFlags(FLAG_ACTIVITY_NEW_TASK)
            context.startActivity(intent)
        }
        holder.itemView.setOnLongClickListener {
            showPopupMenu(it, url, video.id)
            true
        }
    }

    private fun showPopupMenu(view: View, videoUrl: String, id:Int) {
        val popupMenu = PopupMenu(view.context, view)
        popupMenu.menuInflater.inflate(R.menu.video_popup_menu, popupMenu.menu)

        popupMenu.setOnMenuItemClickListener { item ->
            when (item.itemId) {
                R.id.menu_download -> {
                    downloadVideo(view.context, videoUrl)
                    true
                }
                R.id.menu_delete -> {
                    videoRepository.deleteVideo(id, onSuccess = {
                        val v = videos.find {v -> v.id == id}
                        val i = videos.indexOf(v)
                        this.videos.removeAt(i)
                        Handler(Looper.getMainLooper()).post {
                            Toast.makeText(view.context, "Video supprimée", Toast.LENGTH_SHORT).show()
                        }
                        notifyItemRemoved(i)
                    }, onError = {s ->
                        Handler(Looper.getMainLooper()).post {
                            Toast.makeText(view.context, "Erreur lors de la suppression : $s", Toast.LENGTH_SHORT).show()
                        }
                    });
                    true
                }
                else -> false
            }
        }
        popupMenu.show()
    }

    fun downloadVideo(context: Context, videoUrl: String) {
        val request = Request.Builder().url(videoUrl).build()
        val client = OkHttpClient()

        val progressDialog = ProgressDialog(context).apply {
            setTitle("Téléchargement en cours")
            setMessage("Patientez...")
            setCancelable(false)
            setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)
            show()
        }

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                Log.e("DownloadError", "Failed: ${e.message}")
                progressDialog.dismiss()
                Handler(Looper.getMainLooper()).post {
                    Toast.makeText(context, "Une erreur s'est produite lors du téléchargement", Toast.LENGTH_SHORT).show()
                }            }

            override fun onResponse(call: Call, response: Response) {
                if (!response.isSuccessful) {
                    Log.e("DownloadError", "Error: ${response.code}")
                    progressDialog.dismiss()

                    Handler(Looper.getMainLooper()).post {
                        Toast.makeText(context, "Une erreur s'est produite lors du téléchargement (Erreur ${response.code})", Toast.LENGTH_SHORT).show()
                    }
                    return
                }

                val fileName = "video_${System.currentTimeMillis()}.mp4"
                val file = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), fileName)

                val body = response.body ?: return
                val totalSize = body.contentLength()
                var downloadedSize = 0L

                body.byteStream().use { input ->
                    FileOutputStream(file).use { output ->
                        val buffer = ByteArray(1024)
                        var bytesRead: Int

                        while (input.read(buffer).also { bytesRead = it } != -1) {
                            output.write(buffer, 0, bytesRead)
                            downloadedSize += bytesRead
                            progressDialog.progress = ((downloadedSize * 100) / totalSize).toInt()
                        }
                    }
                }

                progressDialog.dismiss()
                Handler(Looper.getMainLooper()).post {
                    moveFileToDownloads(file)
                    Toast.makeText(context, "Téléchargé : $fileName", Toast.LENGTH_SHORT).show()
                }
            }
        })
    }

    fun moveFileToDownloads(sourceFile: File) {
        val downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
        val destFile = File(downloadsDir, sourceFile.name)

        try {
            // Create streams for copying data
            FileInputStream(sourceFile).use { input ->
                FileOutputStream(destFile).use { output ->
                    input.copyTo(output)
                }
            }
            // Optionally delete the original file
            if (sourceFile.exists()) {
                sourceFile.delete()
            }
            Log.d("FileMove", "File moved to: ${destFile.absolutePath}")
        } catch (e: Exception) {
            Log.e("FileMoveError", "Error moving file: ${e.message}")
        }
    }

    override fun getItemCount(): Int {
        return videos.size
    }
}