package com.example.defenseapplication.personal

import android.Manifest
import android.content.ContentResolver
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.util.Log
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.example.defenseapplication.R
import com.example.defenseapplication.bean.UpdateUserInfo
import com.example.defenseapplication.bean.UserInfoBean
import com.example.defenseapplication.databinding.PersonalProfileActivityBinding
import com.example.defenseapplication.utils.RetrofitNetwork
import com.example.defenseapplication.view.AvatarSelectDialog
import com.example.defenseapplication.view.CustomDialogFragmentText
import com.example.defenseapplication.view.LoadingDialog
import com.example.defenseapplication.view.PhoneModifyDialogFragment
import com.gyf.immersionbar.ImmersionBar
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
//个人资料页面
class PersonalProfileActivity : AppCompatActivity() {
    private lateinit var binding: PersonalProfileActivityBinding
    private var userInfo: UserInfoBean? = null

    // 拍照返回的文件
    private var photoFile: File? = null

    // 加载弹窗
    private lateinit var loadingDialog: LoadingDialog

    // 请求权限回调
    private val requestPermissionsLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        val cameraGranted = permissions[Manifest.permission.CAMERA] ?: false
        val storageGranted = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            permissions[Manifest.permission.READ_MEDIA_IMAGES] ?: false
        } else {
            permissions[Manifest.permission.READ_EXTERNAL_STORAGE] ?: false
        }
        val writeStorageGranted = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            true
        } else {
            permissions[Manifest.permission.WRITE_EXTERNAL_STORAGE] ?: false
        }

        if (!cameraGranted) {
            Toast.makeText(this, getString(R.string.camera_permission_denied), Toast.LENGTH_SHORT).show()
        }
        if (!storageGranted) {
            Toast.makeText(this, getString(R.string.storage_permission_denied), Toast.LENGTH_SHORT).show()
        }
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU && !writeStorageGranted) {
            Toast.makeText(this, getString(R.string.write_storage_permission_denied), Toast.LENGTH_SHORT).show()
        }
    }

    // 拍照结果回调
    private val takePhotoLauncher = registerForActivityResult(
        ActivityResultContracts.TakePicture()
    ) { success ->
        if (success && photoFile != null) {
            Log.d("PersonalProfile", "拍照成功，文件路径: ${photoFile?.absolutePath}")
            uploadAvatar(photoFile!!.absolutePath)
        } else {
            Toast.makeText(this, getString(R.string.take_photo_failed), Toast.LENGTH_SHORT).show()
        }
    }

    // 相册选择结果回调
    private val selectAlbumLauncher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        if (result.resultCode == RESULT_OK && result.data != null) {
            val uri = result.data?.data
            uri?.let {
                val filePath = getFilePathFromUri(it)
                if (filePath != null) {
                    Log.d("PersonalProfile", "相册选择成功，文件路径: $filePath")
                    uploadAvatar(filePath)
                } else {
                    Toast.makeText(this, getString(R.string.get_file_failed), Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = PersonalProfileActivityBinding.inflate(layoutInflater)
        setContentView(binding.root)
        ImmersionBar.with(this)
            .statusBarDarkFont(true)
            .titleBar(binding.topBar)
            .init()
        // 初始化加载弹窗
        loadingDialog = LoadingDialog(this)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            userInfo = intent.getParcelableExtra("userInfo", UserInfoBean::class.java)
        } else {
            userInfo = intent.getParcelableExtra("userInfo")
        }
        initView()
    }

    private fun initView() {
        binding.ivBack.setOnClickListener {
            finish()
        }

        userInfo?.let { info ->
            Log.d("头像", "头像 URL = ${info.avatar}")
            val requestOptions = RequestOptions()
                .placeholder(R.drawable.img)
                .error(R.drawable.img)

            Glide.with(this)
                .load(info.avatar)
                .apply(requestOptions)
                .circleCrop()
                .into(binding.ivAvatar)
            binding.tvNickname.text = info.nickName ?: getString(R.string.nickname_default)
            binding.tvPhone.text = info.phonenumber ?: ""
        }

        binding.ivAvatar.setOnClickListener {
            showAvatarSelectDialog()
        }

        binding.itemNickname.setOnClickListener {
            showNicknameDialog()
        }

        binding.itemPhone.setOnClickListener {
            showPhoneDialog()
        }
    }

    private fun showNicknameDialog() {
        val currentNickname = binding.tvNickname.text.toString()
        val dialog = CustomDialogFragmentText()
            .setTitle(getString(R.string.set_name))
            .setMessage("")
            .setInputHint(getString(R.string.nickname_hint))
            .setInputText(currentNickname)
            .setShowInput(true)
            .setPositiveText(getString(R.string.confirm))
            .setNegativeText("")
            .setOnConfirmListener { newNickname ->
                if (newNickname.isNotBlank()) {
                    updateNickname(newNickname)
                }
            }
        dialog.show(supportFragmentManager, "nickname_dialog")
    }

    private fun updateNickname(newNickname: String) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val request = UpdateUserInfo(
                    userId = userInfo?.userId,
                    nickName = newNickname
                )
                val response = RetrofitNetwork.getNetworkService().updateUserInfo(request)
                withContext(Dispatchers.Main) {
                    if (response.code == 200) {
                        binding.tvNickname.text = newNickname
                        userInfo = userInfo?.copy(nickName = newNickname)
                        Toast.makeText(this@PersonalProfileActivity, getString(R.string.operation_success), Toast.LENGTH_SHORT).show()
                    } else {
                        Toast.makeText(this@PersonalProfileActivity, getString(R.string.operation_failed), Toast.LENGTH_SHORT).show()
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                withContext(Dispatchers.Main) {
                    Toast.makeText(this@PersonalProfileActivity, getString(R.string.network_error), Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun showPhoneDialog() {
        val dialog = PhoneModifyDialogFragment()
            .setTitle(getString(R.string.modify_phone))
            .setNegativeText(getString(R.string.cancel))
            .setPositiveText(getString(R.string.verify_and_bind))
            .setOnConfirmListener { phone, code ->
                updatePhone(phone, code)
            }
        dialog.show(supportFragmentManager, "phone_dialog")
    }

    private fun updatePhone(phone: String, code: String) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val request = UpdateUserInfo(
                    userId = userInfo?.userId,
                    phonenumber = phone,
                    smsCoode = code
                )
                val response = RetrofitNetwork.getNetworkService().updateUserInfo(request)
                withContext(Dispatchers.Main) {
                    if (response.code == 200) {
                        binding.tvPhone.text = phone
                        userInfo = userInfo?.copy(phonenumber = phone)
                        Toast.makeText(this@PersonalProfileActivity, getString(R.string.operation_success), Toast.LENGTH_SHORT).show()
                    } else {
                        Toast.makeText(this@PersonalProfileActivity, getString(R.string.operation_failed), Toast.LENGTH_SHORT).show()
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                withContext(Dispatchers.Main) {
                    Toast.makeText(this@PersonalProfileActivity, getString(R.string.network_error), Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun showAvatarSelectDialog() {
        AvatarSelectDialog(this)
            .setOnTakePhotoListener {
                checkCameraPermission { granted ->
                    if (granted) {
                        takePhoto()
                    }
                }
            }
            .setOnSelectAlbumListener {
                checkStoragePermission { granted ->
                    if (granted) {
                        selectAlbum()
                    }
                }
            }
            .show()
    }

    /**
     * 检查相机权限
     */
    private fun checkCameraPermission(callback: (Boolean) -> Unit) {
        val permissions = mutableListOf(Manifest.permission.CAMERA)
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
            permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
        }

        val allGranted = permissions.all {
            ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
        }

        if (allGranted) {
            callback(true)
        } else {
            requestPermissionsLauncher.launch(permissions.toTypedArray())
            callback(false)
        }
    }

    /**
     * 检查存储权限
     */
    private fun checkStoragePermission(callback: (Boolean) -> Unit) {
        val permission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            Manifest.permission.READ_MEDIA_IMAGES
        } else {
            Manifest.permission.READ_EXTERNAL_STORAGE
        }

        if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED) {
            callback(true)
        } else {
            requestPermissionsLauncher.launch(arrayOf(permission))
            callback(false)
        }
    }

    /**
     * 调用系统相机拍照
     */
    private fun takePhoto() {
        try {
            photoFile = createImageFile()
            val photoUri = FileProvider.getUriForFile(
                this,
                "$packageName.fileprovider",
                photoFile!!
            )
            takePhotoLauncher.launch(photoUri)
        } catch (e: IOException) {
            e.printStackTrace()
            Toast.makeText(this, getString(R.string.create_file_failed), Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * 创建图片文件
     */
    @Throws(IOException::class)
    private fun createImageFile(): File {
        val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
        val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        return File.createTempFile(
            "JPEG_${timeStamp}_",
            ".jpg",
            storageDir
        ).apply {
            Log.d("PersonalProfile", "创建图片文件: $absolutePath")
        }
    }

    /**
     * 调用系统相册选择图片
     */
    private fun selectAlbum() {
        val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
        intent.type = "image/*"
        selectAlbumLauncher.launch(intent)
    }

    /**
     * 从 Uri 获取文件路径
     */
    private fun getFilePathFromUri(uri: Uri): String? {
        val contentResolver: ContentResolver = contentResolver
        val inputStream: InputStream? = contentResolver.openInputStream(uri)
        inputStream?.use {
            try {
                val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
                val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
                val file = File(storageDir, "JPEG_${timeStamp}_temp.jpg")

                FileOutputStream(file).use { outputStream ->
                    val buffer = ByteArray(1024)
                    var bytesRead: Int
                    while (inputStream.read(buffer).also { bytesRead = it } != -1) {
                        outputStream.write(buffer, 0, bytesRead)
                    }
                }
                return file.absolutePath
            } catch (e: IOException) {
                e.printStackTrace()
                return null
            }
        }
        return null
    }

    /**
     * 上传头像到服务器并更新个人信息
     */
    private fun uploadAvatar(filePath: String) {
        // 显示加载弹窗
        loadingDialog.show()

        CoroutineScope(Dispatchers.IO).launch {
            try {
                val file = File(filePath)
                val requestBody = file.asRequestBody("image/jpeg".toMediaTypeOrNull())
                val part = MultipartBody.Part.createFormData("file", file.name, requestBody)

                val uploadResponse = RetrofitNetwork.getNetworkService().uploadFile(part)

                withContext(Dispatchers.Main) {
                    if (uploadResponse.code == 200 && uploadResponse.data?.url != null) {
                        Log.d("PersonalProfile", "文件上传成功，URL: ${uploadResponse.data?.url}")
                        updateAvatar(uploadResponse.data!!.url)
                    } else {
                        loadingDialog.dismiss()
                        Toast.makeText(this@PersonalProfileActivity, getString(R.string.upload_failed), Toast.LENGTH_SHORT).show()
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                withContext(Dispatchers.Main) {
                    loadingDialog.dismiss()
                    Toast.makeText(this@PersonalProfileActivity, getString(R.string.network_error), Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    /**
     * 调用修改个人信息接口更新头像
     */
    private fun updateAvatar(avatarUrl: String) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val request = UpdateUserInfo(
                    userId = userInfo?.userId,
                    avatar = avatarUrl
                )
                val response = RetrofitNetwork.getNetworkService().updateUserInfo(request)
                withContext(Dispatchers.Main) {
                    loadingDialog.dismiss()
                    if (response.code == 200) {
                        Glide.with(this@PersonalProfileActivity)
                            .load(avatarUrl)
                            .apply(RequestOptions()
                                .placeholder(R.drawable.img)
                                .error(R.drawable.img))
                            .circleCrop()
                            .into(binding.ivAvatar)
                        userInfo = userInfo?.copy(avatar = avatarUrl)
                        Toast.makeText(this@PersonalProfileActivity, getString(R.string.operation_success), Toast.LENGTH_SHORT).show()
                    } else {
                        Toast.makeText(this@PersonalProfileActivity, getString(R.string.operation_failed), Toast.LENGTH_SHORT).show()
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                withContext(Dispatchers.Main) {
                    loadingDialog.dismiss()
                    Toast.makeText(this@PersonalProfileActivity, getString(R.string.network_error), Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
}