package com.apps.quicksketchtrace.activity

import MainViewModel
import android.Manifest
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
import com.apps.quicksketchtrace.R
import com.apps.quicksketchtrace.ad.TPManager
import com.apps.quicksketchtrace.adapter.ThreeLineAdapter
import com.apps.quicksketchtrace.database.Upload
import com.apps.quicksketchtrace.databinding.FragmentUploadBinding
import com.apps.quicksketchtrace.listener.MainClickListener
import com.apps.quicksketchtrace.util.OpenConvert
import java.io.File
import java.io.IOException

class UploadFragment : Fragment(), MainClickListener {
    private lateinit var binding: FragmentUploadBinding
    private lateinit var mainViewModel: MainViewModel
    private val adapter = ThreeLineAdapter()
    private var uploadList: List<Upload> = arrayListOf()
    private var photoPath: Uri? = null
    private var permissionCamera: ActivityResultLauncher<String>? = null
    private var cameraLauncher: ActivityResultLauncher<Uri>? = null
    private var galleryPermission: ActivityResultLauncher<Array<String>>? = null
    private var galleryLauncher: ActivityResultLauncher<Intent>? = null
    private var imgFile: File? = null
    private var delPosition = -1
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentUploadBinding.inflate(inflater, container, false)
        mainViewModel = ViewModelProvider(requireActivity())[MainViewModel::class.java]
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        init()
    }

    private fun init() {
        adapter.setListener(this)
        setupRecyclerView()
        mainViewModel.uploads.observe(viewLifecycleOwner) { list ->
            if (list.isNotEmpty()) {
                if (delPosition != -1) {
                    adapter.notifyItemRemoved(delPosition)
                    binding.recyclerView.postDelayed({
                        adapter.setUploadList(list, 1)
                    }, 3000)
                    delPosition = -1
                } else {
                    adapter.notifyDataSetChanged()
                    adapter.setUploadList(list, 1)
                }
            }
            uploadList = list
            Log.d("Upload list is:", "${uploadList.size}")
            refreshData()
        }
        registerCameraAndGallery()
        binding.llCamera.setOnClickListener {
            TPManager.showTPAD(requireActivity()) {
                openPermissionCamera()
            }

        }
        binding.llGallery.setOnClickListener {
            TPManager.showTPAD(requireActivity()) {
                openPermissionGallery()
            }
        }
    }

    private fun setupRecyclerView() {
        // 先设置空适配器，让UI快速显示
        binding.recyclerView.adapter = adapter
        val gridLayoutManager = GridLayoutManager(requireActivity(), 3)
        binding.recyclerView.layoutManager = gridLayoutManager
        binding.recyclerView.setHasFixedSize(true)
        binding.recyclerView.setItemViewCacheSize(20)
        binding.recyclerView.isDrawingCacheEnabled = true
        binding.recyclerView.drawingCacheQuality = View.DRAWING_CACHE_QUALITY_HIGH
    }

    private fun registerCameraAndGallery() {
        permissionCamera =
            registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
                if (granted) {
                    startCamera()
                } else {
                    Toast.makeText(requireActivity(), R.string.permit, Toast.LENGTH_SHORT).show()
                }
            }

        cameraLauncher =
            registerForActivityResult(ActivityResultContracts.TakePicture()) { success ->
                Log.d("YYYYYY", "photoPath is $photoPath")
                if (success && photoPath != null) {
                    savePhoto(photoPath!!, true)
                }
            }

        galleryPermission =
            registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
                val isGranted = permissions.values.all { it }
                if (isGranted) {
                    startGallery()
                } else {
                    Toast.makeText(requireActivity(), R.string.permit, Toast.LENGTH_SHORT).show()
                }
            }

        galleryLauncher =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                if (result.resultCode == RESULT_OK && result.data != null) {
                    val imageUri = result.data?.data
                    if (imageUri != null) {
                        savePhoto(imageUri, false)
                    }
                }
            }
    }

    private fun openPermissionCamera() {
        val camera = Manifest.permission.CAMERA
        if (ContextCompat.checkSelfPermission(
                requireContext(),
                camera
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            permissionCamera?.launch(camera)
        } else {
            startCamera()
        }
    }

    private fun openPermissionGallery() {
        val gallery = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            arrayOf(Manifest.permission.READ_MEDIA_IMAGES)
        } else {
            arrayOf(
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            )
        }

        if (!OpenConvert.checkPermission(requireActivity(), gallery)) {
            galleryPermission?.launch(gallery)
        } else {
            startGallery()
        }
    }

    private fun savePhoto(uri: Uri, isCamera: Boolean) {
        Log.d("YYYYYY", "save is start")
        var file: File? = null
        var filePath: String? = null
        binding.progress.visibility = View.VISIBLE
        val fileSize = OpenConvert.getUriFileSize(requireContext(), uri).toFloat()

        if (fileSize >= 5) {
            binding.progress.visibility = View.GONE
            Toast.makeText(requireContext(), R.string.image_too, Toast.LENGTH_SHORT).show()
            return
        }

        try {
            if (isCamera) {
                if (imgFile != null && imgFile!!.exists()) {
                    file = imgFile
                    filePath = imgFile!!.absolutePath
                }
            } else {
                val fileName = OpenConvert.getFileNameFromUri(uri, requireContext())
                if (fileName != null) {
                    filePath = OpenConvert.getImportPath(fileName)
                    file = File(filePath)
                    OpenConvert.copyUriToFile(uri, file, requireContext())
                }
            }

            if (file == null || !file.exists()) {
                requireActivity().runOnUiThread {
                    binding.progress.visibility = View.GONE
                    Toast.makeText(requireContext(), R.string.file_not, Toast.LENGTH_SHORT).show()
                }
                return
            }

            val finalFilePath = filePath
            if (finalFilePath != null) {
                binding.progress.visibility = View.VISIBLE
                var isUploadObserver: Observer<Boolean>? = null
                // 观察 isUpload LiveData 的变化
                isUploadObserver = Observer { isUploaded ->
                    binding.progress.visibility = View.GONE
                    if (isUploaded) {
                        Toast.makeText(
                            requireContext(),
                            R.string.image_already,
                            Toast.LENGTH_SHORT
                        ).show()
                    } else {
                        mainViewModel.addUpload(finalFilePath)
                    }

                    // 移除观察者以避免内存泄漏
                    isUploadObserver?.let { mainViewModel.isUpload.removeObserver(it) }
                }

                // 注册观察者
                mainViewModel.isUpload.observe(viewLifecycleOwner, isUploadObserver)

                // 开始检查
                mainViewModel.checkIsUpload(finalFilePath)
            }
        } catch (e: Exception) {
            requireActivity().runOnUiThread {
                binding.progress.visibility = View.GONE
                Toast.makeText(requireContext(), "error: ${e.message}", Toast.LENGTH_SHORT).show()
            }
        }
    }

    private fun refreshData() {
        if (uploadList.isEmpty()) {
            binding.llEmpty.visibility = View.VISIBLE
            binding.recyclerView.visibility = View.GONE
        } else {
            binding.llEmpty.visibility = View.GONE
            binding.recyclerView.visibility = View.VISIBLE
            adapter.setUploadList(uploadList, 1)
            adapter.setListener(this)
            binding.recyclerView.adapter = adapter
            val gridLayoutManager = GridLayoutManager(requireActivity(), 3)
            binding.recyclerView.layoutManager = gridLayoutManager
        }
    }

    private fun startGallery() {
        val intent =
            Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI).apply {
                type = "image/*"
            }
        galleryLauncher?.launch(intent)
    }

    private fun startCamera() {
        try {
            imgFile = File.createTempFile("IMG_", ".jpg", requireActivity().cacheDir)
            val uri = FileProvider.getUriForFile(
                requireContext(),
                "${requireContext().packageName}.fileprovider",
                imgFile
            ).also { photoPath = it }

            cameraLauncher?.launch(uri)
        } catch (e: IOException) {
            Toast.makeText(requireActivity(), "error", Toast.LENGTH_SHORT).show()
        }
    }

    override fun onClick(name: String) {
        val intent = Intent(requireActivity(), StartDrawActivity::class.java)
        intent.putExtra(StartDrawActivity.PATH_KEY, name)
        startActivity(intent)
    }

    override fun onDelete(name: String, position: Int) {
        delPosition = position
        mainViewModel.deleteUploadPath(name)
    }
}