package com.example.smartlab.fragments

import android.Manifest
import android.app.DatePickerDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.text.Editable
import android.text.TextWatcher
import android.util.Base64
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.example.smartlab.R
import com.example.smartlab.SharedPreferenceManager
import com.example.smartlab.databinding.FragmentProfileBinding
import java.io.ByteArrayOutputStream
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale


class ProfileFragment : Fragment() {

    private  var _binding: FragmentProfileBinding? = null
    private val binding get() = _binding!!

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        _binding = FragmentProfileBinding.inflate(inflater, container, false)

        val view = binding.root

        val genders = resources.getStringArray(R.array.gender)
        var arrayAdapter = ArrayAdapter(requireContext(), R.layout.dropdown_item, genders)
        binding.autoComplete.setAdapter(arrayAdapter)

        // Немного некорректно но сойдёт

        binding.autoComplete.setOnClickListener{
            var textFromHint = binding.inptLayout.hint

            if( textFromHint != null || binding.autoComplete.text.isNotEmpty()  ) {
                binding.inptLayout.hint  = null
            } else{
                binding.inptLayout.hint  =  "Пол"
            }
        }

        val calender = Calendar.getInstance()
        val datePicker = DatePickerDialog.OnDateSetListener{ view, year, month, dayOfMonth ->
            calender.set(Calendar.YEAR, year)
            calender.set(Calendar.MONTH, month)
            calender.set(Calendar.DAY_OF_MONTH, dayOfMonth)
            updateLabel(calender)
        }
        binding.datePickerActions.setOnClickListener {
            DatePickerDialog(requireContext(), datePicker, calender.get(Calendar.YEAR),
                calender.get(Calendar.MONTH), calender.get(Calendar.DAY_OF_MONTH)).show()
        }


        forTextChanged()

        listener()

        inputFromPrefManager()

        return view
        //return inflater.inflate(R.layout.fragment_profile, container, false)
    }

    private fun inputFromPrefManager(){
        val shrdPrefMangr = SharedPreferenceManager(requireContext())

        binding.name.setText(shrdPrefMangr.Name)
        binding.surname.setText(shrdPrefMangr.Surname)
        binding.middleName.setText(shrdPrefMangr.Patronymic)


        val date = shrdPrefMangr.BirthDay

        val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
        var dateObj = dateFormat.parse(date)
        val newDateFormant = SimpleDateFormat("dd LLLL yyyy", Locale.getDefault())
        val myString = newDateFormant.format(dateObj.time)

        binding.datePickerActions.setText(myString)


        binding.autoComplete.setText(shrdPrefMangr.Gender)

        // Delete hint
        if( binding.inptLayout.hint != null || binding.autoComplete.text.isNotEmpty()  ) {
            binding.inptLayout.hint  = null
        } else{
            binding.inptLayout.hint  =  "Пол"
        }

        // Set photo
        if (!shrdPrefMangr.ProfilePhoto.isNullOrEmpty()){
            try {
                val b: ByteArray = Base64.decode(shrdPrefMangr.ProfilePhoto, Base64.DEFAULT)
                val bitmap = BitmapFactory.decodeByteArray(b, 0, b.size)
                binding.shapeableImageView.setImageBitmap(bitmap)
            }
            catch (e: Exception){
                Log.d("Wrong is: ", "${e.message}  ${e.toString()}")
            }
        }

    }


    private fun listener(){
        binding.shapeableImageView.setOnClickListener{
            checkPermission(Manifest.permission.READ_MEDIA_IMAGES, 101)
        }
    }

    private fun checkPermission(permission: String, requestCode: Int){
        if (ContextCompat.checkSelfPermission(requireContext(), permission)
            == PackageManager.PERMISSION_DENIED){
            ActivityCompat.requestPermissions(requireActivity(),
                arrayOf(Manifest.permission.READ_MEDIA_IMAGES),
            requestCode)
        } else{
            val pickImg = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
            changeImage.launch(pickImg)
        }
    }

    private val changeImage =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()){
            if (it.resultCode == PackageManager.PERMISSION_DENIED){
                val shrdPrefMangr = SharedPreferenceManager(requireContext())
                val data = it.data
                val imgUri = data?.data

                // Take bitmap from URI path
                val bitmap = BitmapFactory.decodeStream(imgUri?.let { it1 ->
                    requireContext().getContentResolver()
                        .openInputStream(it1)
                });

                // Encode my Bitmap and return as string format
                val myEncode = BitMapToString(bitmap)

                shrdPrefMangr.ProfilePhoto = myEncode

                binding.shapeableImageView.setImageBitmap(bitmap)
            }
        }

    fun BitMapToString(bitmap: Bitmap): String {
        val baos = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos)
        val b = baos.toByteArray()
        return Base64.encodeToString(b, Base64.DEFAULT)
    }

    private fun updateLabel(calender: Calendar){
        val dateFormat = SimpleDateFormat("dd LLLL yyyy", Locale.getDefault())
        val current = dateFormat
        binding.datePickerActions.setText(current.format(calender.time))
    }


    private fun checkForAllFields(){
        val patternOFName = "^[A-ZА-Я][A-Za-zА-Яа-я]+$".toRegex()

        if ( patternOFName.matches(binding.name.text.trim()) &&
            patternOFName.matches(binding.surname.text.trim()) &&
            patternOFName.matches(binding.middleName.text.trim()) &&
            binding.autoComplete.text.isNotEmpty() && binding.datePickerActions.text.isNotEmpty()){
            binding.btn.isEnabled = true
        } else{ binding.btn.isEnabled = false  }
    }

    private fun forTextChanged(){

        binding.name.addTextChangedListener(object: TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun afterTextChanged(p0: Editable?) {
                checkForAllFields()  }
        })

        binding.surname.addTextChangedListener(object: TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun afterTextChanged(p0: Editable?) {
                checkForAllFields()  }
        })

        binding.middleName.addTextChangedListener(object: TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun afterTextChanged(p0: Editable?) {
                checkForAllFields() }
        } )

        binding.datePickerActions.addTextChangedListener(object: TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun afterTextChanged(p0: Editable?) {
                checkForAllFields() }
        } )

        binding.autoComplete.addTextChangedListener(object: TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun afterTextChanged(p0: Editable?) {
                checkForAllFields()
            }
        } )
    }

}