package com.example.livingai.ui.page

import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.widget.ArrayAdapter
import android.widget.AutoCompleteTextView
import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.livingai.R
import com.example.livingai.camera.CameraActivity
import com.example.livingai.commons.Constants
import com.example.livingai.storage.StorageUtils
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import java.io.File
import java.io.FileOutputStream
import java.io.FileWriter
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

class AddAnimalProfileActivity : AppCompatActivity() {

    private var currentCowName: String? = null
    private lateinit var imagesContainer: LinearLayout
    private val storagePermissionCode = 101
    private val orientationViews = mutableMapOf<String, View>()
    private val initialImagePaths = mutableSetOf<String>()
    private val orientationList = Constants.ORIENTATION_NAMES

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_cow_selection)

        val toolbar = findViewById<androidx.appcompat.widget.Toolbar>(R.id.toolbar)
        setSupportActionBar(toolbar)
        supportActionBar?.setDisplayShowTitleEnabled(false)
        
        toolbar.setNavigationOnClickListener {
            finish()
        }

        updateUILabels()

        initializeDefaultMasks()
        setupDropdowns()

        imagesContainer = findViewById(R.id.currentCowImagesContainer)

        currentCowName = savedInstanceState?.getString("COW_NAME") ?: intent.getStringExtra("COW_NAME")
        if (currentCowName == null) {
            generateNewCowName()
        }

        loadInitialImages()

        if (intent.hasExtra("COW_NAME")) {
             loadCowDetails(currentCowName!!)
        }

        for (orientation in orientationList) {
            orientationViews[orientation] = findViewById(resources.getIdentifier(orientation, "id", packageName))
        }

        findViewById<Button>(R.id.btnNewCow).setOnClickListener {
            if (checkStoragePermissions()) {
                saveProfile()
            } else {
                requestStoragePermissions()
            }
        }

        findViewById<Button>(R.id.btnCancel).setOnClickListener {
            deleteSessionImages()
            finish()
        }
    }

    private fun updateUILabels() {
        findViewById<TextView>(R.id.tvToolbarTitle).text = getString(R.string.title_cow_selection)
        findViewById<TextView>(R.id.tvAddCowDetails).text = getString(R.string.title_add_cow_details)
        findViewById<TextView>(R.id.tvLabelSpecies).text = getString(R.string.label_species)
        findViewById<TextView>(R.id.tvLabelBreed).text = getString(R.string.label_breed)
        findViewById<TextView>(R.id.tvLabelAge).text = getString(R.string.label_age)
        findViewById<TextView>(R.id.tvLabelMilk).text = getString(R.string.label_milk_yield)
        findViewById<TextView>(R.id.tvLabelCalving).text = getString(R.string.label_calving_no)
        findViewById<TextView>(R.id.tvReproductiveStatus).text = getString(R.string.label_reproductive_status)
        findViewById<RadioButton>(R.id.rbPregnant).text = getString(R.string.radio_pregnant)
        findViewById<RadioButton>(R.id.rbCalved).text = getString(R.string.radio_calved)
        findViewById<RadioButton>(R.id.rbNone).text = getString(R.string.radio_none)

        findViewById<TextView>(R.id.tvLabelDescription).text = getString(R.string.hint_description)
        findViewById<TextInputLayout>(R.id.tilDescription).hint = getString(R.string.hint_description)

        findViewById<TextView>(R.id.tvUploadPhotos).text = getString(R.string.label_upload_photos)

        findViewById<TextView>(R.id.tvFrontView).text = getString(R.string.text_front_view)
        findViewById<TextView>(R.id.tvRearView).text = getString(R.string.text_rear_view)
        findViewById<TextView>(R.id.tvLeftSide).text = getString(R.string.text_left_side)
        findViewById<TextView>(R.id.tvRightSide).text = getString(R.string.text_right_side)
        findViewById<TextView>(R.id.tvLeftAngle).text = getString(R.string.text_left_angle)
        findViewById<TextView>(R.id.tvRightAngle).text = getString(R.string.text_right_angle)
        findViewById<TextView>(R.id.tvAngleView).text = getString(R.string.text_angle_view)

        findViewById<Button>(R.id.btnNewCow).text = getString(R.string.btn_save_profile)
        findViewById<Button>(R.id.btnCancel).text = getString(R.string.btn_cancel)
    }

    private fun loadInitialImages() {
        val name = currentCowName ?: return
        val cowFolder = StorageUtils.getCowImageFolder(name)
        if (cowFolder.exists()) {
            cowFolder.listFiles()?.forEach { file ->
                if (file.isFile) {
                    initialImagePaths.add(file.absolutePath)
                }
            }
        }
    }

    private fun deleteSessionImages() {
        val name = currentCowName ?: return
        val cowFolder = StorageUtils.getCowImageFolder(name)
        if (cowFolder.exists()) {
            cowFolder.listFiles()?.forEach { file ->
                if (file.isFile && !initialImagePaths.contains(file.absolutePath)) {
                    file.delete()
                }
            }

            val remaining = cowFolder.listFiles()
            if (remaining == null || remaining.isEmpty()) {
                cowFolder.delete()
            }
        }
    }

    private fun checkStoragePermissions(): Boolean {
        return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            android.os.Environment.isExternalStorageManager()
        } else {
            val write = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
            val read = ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE)
            write == PackageManager.PERMISSION_GRANTED && read == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun requestStoragePermissions() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
            try {
                val intent = Intent(android.provider.Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
                val uri = android.net.Uri.fromParts("package", packageName, null)
                intent.data = uri
                startActivity(intent)
            } catch (_: Exception) {
                val intent = Intent(android.provider.Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
                startActivity(intent)
            }
        } else {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE),
                storagePermissionCode
            )
        }
    }

    private fun saveProfile() {
        val speciesDisplay = findViewById<AutoCompleteTextView>(R.id.spinnerSpecies).text.toString()
        val breedDisplay = findViewById<AutoCompleteTextView>(R.id.spinnerBreed).text.toString()

        val species = speciesDisplay
        val breed = breedDisplay

        val ageInput = findViewById<TextInputEditText>(R.id.etAge).text.toString()
        val milkInput = findViewById<TextInputLayout>(R.id.tilMilk).editText?.text.toString()
        val calvingInput = findViewById<TextInputLayout>(R.id.tilCalving).editText?.text.toString()
        val descriptionInput = findViewById<TextInputLayout>(R.id.tilDescription).editText?.text.toString()

        val rgReproductive = findViewById<RadioGroup>(R.id.rgReproductiveStatus)
        val reproductiveStatus = when(rgReproductive?.checkedRadioButtonId) {
            R.id.rbPregnant -> getString(R.string.radio_pregnant)
            R.id.rbCalved -> getString(R.string.radio_calved)
            R.id.rbNone -> getString(R.string.radio_none)
            else -> ""
        }

        val csvHeader = "CowID,Species,Breed,Age,MilkYield,CalvingNumber,ReproductiveStatus,Description\n"
        val csvRow = "$currentCowName,$species,$breed,$ageInput,$milkInput,$calvingInput,$reproductiveStatus,$descriptionInput\n"

        val docsFolder = StorageUtils.getDocumentsFolder()
        val csvFile = File(docsFolder, "cow_profiles.csv")

        try {
            val fileExists = csvFile.exists()
            val lines = if (fileExists) csvFile.readLines().toMutableList() else mutableListOf()

            if (!fileExists) {
                lines.add(csvHeader.trim())
            }

            val existingIndex = lines.indexOfFirst { it.startsWith("$currentCowName,") }

            if (existingIndex != -1) {
                lines[existingIndex] = csvRow.trim()
            } else {
                lines.add(csvRow.trim())
            }

            FileWriter(csvFile).use { writer ->
                lines.forEach { line ->
                    writer.write(line + "\n")
                }
            }

            Toast.makeText(this, getString(R.string.toast_profile_saved), Toast.LENGTH_SHORT).show()
            finish()
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(this, getString(R.string.toast_error_saving_profile) + " ${e.message}", Toast.LENGTH_SHORT).show()
        }
    }

    private fun loadCowDetails(cowId: String) {
        val docsFolder = StorageUtils.getDocumentsFolder()
        val csvFile = File(docsFolder, "cow_profiles.csv")
        if (!csvFile.exists()) return

        try {
            val lines = csvFile.readLines()
            val record = lines.find { it.startsWith("$cowId,") }?.split(",") ?: return

            if (record.size >= 8) {
                val displaySpecies = record[1]
                findViewById<AutoCompleteTextView>(R.id.spinnerSpecies).setText(displaySpecies, false)

                val displayBreed = record[2]
                findViewById<AutoCompleteTextView>(R.id.spinnerBreed).setText(displayBreed, false)

                findViewById<TextInputEditText>(R.id.etAge).setText(record[3])
                findViewById<TextInputLayout>(R.id.tilMilk).editText?.setText(record[4])
                findViewById<TextInputLayout>(R.id.tilCalving).editText?.setText(record[5])

                val storedStatus = record[6]

                if (storedStatus == getString(R.string.radio_pregnant)) {
                    findViewById<RadioButton>(R.id.rbPregnant).isChecked = true
                } else if (storedStatus == getString(R.string.radio_calved)) {
                    findViewById<RadioButton>(R.id.rbCalved).isChecked = true
                } else if (storedStatus == getString(R.string.radio_none)) {
                    findViewById<RadioButton>(R.id.rbNone).isChecked = true
                } else {
                    when (storedStatus) {
                         "Pregnant" -> findViewById<RadioButton>(R.id.rbPregnant).isChecked = true
                         "Calved" -> findViewById<RadioButton>(R.id.rbCalved).isChecked = true
                         "None" -> findViewById<RadioButton>(R.id.rbNone).isChecked = true
                    }
                }

                findViewById<TextInputLayout>(R.id.tilDescription).editText?.setText(record[7])
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun setupDropdowns() {
        val species = listOf(
            getString(R.string.species_cow),
            getString(R.string.species_buffalo)
        )
        val speciesAdapter = ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, species)
        findViewById<AutoCompleteTextView>(R.id.spinnerSpecies).setAdapter(speciesAdapter)

        val breeds = listOf(
            getString(R.string.breed_holstein),
            getString(R.string.breed_jersey),
            getString(R.string.breed_sahiwal),
            getString(R.string.breed_gir),
            getString(R.string.breed_red_sindhi),
            getString(R.string.breed_murrah),
            getString(R.string.breed_surti)
        )
        val breedAdapter = ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, breeds)
        findViewById<AutoCompleteTextView>(R.id.spinnerBreed).setAdapter(breedAdapter)
    }

    override fun onResume() {
        super.onResume()
        refreshCowImages()
    }

    private fun initializeDefaultMasks() {
        val orientationResources = orientationList.associate { orientation ->
            val resId = resources.getIdentifier(orientation, "drawable", packageName)
            orientation to resId
        }

        orientationResources.forEach { (orientation, resId) ->
            val filename = "${orientation}_mask.png"
            val file = File(filesDir, filename)
            if (!file.exists()) {
                try {
                    val original = BitmapFactory.decodeResource(resources, resId)
                    if (original != null) {
                        val inverted = createInverseBitmask(original)
                        FileOutputStream(file).use { out ->
                            inverted.compress(Bitmap.CompressFormat.PNG, 100, out)
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    }

    private fun createInverseBitmask(src: Bitmap): Bitmap {
        val width = src.width
        val height = src.height
        val pixels = IntArray(width * height)
        src.getPixels(pixels, 0, width, 0, 0, width, height)

        for (i in pixels.indices) {
            val alpha = (pixels[i] shr 24) and 0xFF
            if (alpha > 0) {
                pixels[i] = Color.TRANSPARENT
            } else {
                pixels[i] = Color.BLACK
            }
        }
        return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888)
    }

    private fun generateNewCowName() {
        val sdf = SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault())
        currentCowName = "cow_${sdf.format(Date())}"
    }

    private fun refreshCowImages() {
        val name = currentCowName ?: return

        val orientationResourcesPair = orientationList.associate { orientation ->
            val resId = resources.getIdentifier(orientation, "drawable", packageName)
            val btnId = resources.getIdentifier("btn${orientation}", "id", packageName)
            orientation to Pair(resId, btnId)
        }

        val cowImagesFolder = StorageUtils.getCowImageFolder(name)

        orientationResourcesPair.forEach { (orientation, pair) ->
            val (drawableId, viewId) = pair

            val files = if (cowImagesFolder.exists()) {
                cowImagesFolder.listFiles { _, fname -> fname.startsWith("${name}_${orientation}_") && fname.endsWith(".jpg") }
            } else {
                null
            }

            val latestFile = files?.maxByOrNull { it.lastModified() }

            val container = findViewById<LinearLayout>(viewId)
            container.removeAllViews()

            val label = when(orientation) {
                "front" -> getString(R.string.text_front_view)
                "back" -> getString(R.string.text_rear_view)
                "left" -> getString(R.string.text_left_side)
                "right" -> getString(R.string.text_right_side)
                "angle" -> getString(R.string.text_angle_view)
                "leftangle" -> getString(R.string.text_left_angle)
                "rightangle" -> getString(R.string.text_right_angle)
                else -> orientation
            }

            if (latestFile != null && latestFile.exists()) {
                 val frameLayout = android.widget.FrameLayout(this)
                frameLayout.layoutParams = LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.MATCH_PARENT
                )

                val imageView = ImageView(this)
                imageView.layoutParams = android.widget.FrameLayout.LayoutParams(
                    android.widget.FrameLayout.LayoutParams.MATCH_PARENT,
                    android.widget.FrameLayout.LayoutParams.MATCH_PARENT
                )
                imageView.scaleType = ImageView.ScaleType.CENTER_CROP
                val bitmap = BitmapFactory.decodeFile(latestFile.absolutePath)
                imageView.setImageBitmap(bitmap)
                
                val deleteBtn = ImageView(this)
                val btnSize = (24 * resources.displayMetrics.density).toInt()
                val btnParams = android.widget.FrameLayout.LayoutParams(btnSize, btnSize)
                btnParams.gravity = android.view.Gravity.TOP or android.view.Gravity.END
                val margin = (4 * resources.displayMetrics.density).toInt()
                btnParams.setMargins(margin, margin, margin, margin)
                deleteBtn.layoutParams = btnParams
                deleteBtn.setImageResource(android.R.drawable.ic_menu_close_clear_cancel)
                deleteBtn.setColorFilter(Color.RED)
                deleteBtn.setBackgroundColor(Color.parseColor("#80FFFFFF"))
                deleteBtn.isClickable = true
                deleteBtn.setOnClickListener {
                    if (latestFile.delete()) {
                        val remainingFiles = cowImagesFolder.listFiles()
                        if (remainingFiles == null || remainingFiles.isEmpty()) {
                            cowImagesFolder.delete()
                        }
                        refreshCowImages()
                    }
                }

                val labelView = TextView(this)
                labelView.text = label
                labelView.textSize = 12f
                labelView.setTextColor(Color.WHITE)
                labelView.setShadowLayer(3f, 0f, 0f, Color.BLACK)
                val labelParams = android.widget.FrameLayout.LayoutParams(
                    android.widget.FrameLayout.LayoutParams.WRAP_CONTENT,
                    android.widget.FrameLayout.LayoutParams.WRAP_CONTENT
                )
                labelParams.gravity = android.view.Gravity.BOTTOM or android.view.Gravity.CENTER_HORIZONTAL
                labelParams.bottomMargin = (4 * resources.displayMetrics.density).toInt()
                labelView.layoutParams = labelParams

                frameLayout.addView(imageView)
                frameLayout.addView(labelView)
                frameLayout.addView(deleteBtn)

                container.addView(frameLayout)

                imageView.setOnClickListener {
                    val intent = Intent(this, FullScreenImageActivity::class.java)
                    intent.putExtra("IMAGE_PATH", latestFile.absolutePath)
                    intent.putExtra("ALLOW_RETAKE", true)
                    intent.putExtra("COW_NAME", currentCowName)
                    intent.putExtra("ORIENTATION", orientation)
                    intent.putExtra("SILHOUETTE_ID", drawableId)
                    startActivity(intent)
                }

                container.setOnClickListener(null)
                container.isClickable = false

            } else {
                val iconView = ImageView(this)
                val params = LinearLayout.LayoutParams(
                    (24 * resources.displayMetrics.density).toInt(),
                    (24 * resources.displayMetrics.density).toInt()
                )
                params.gravity = android.view.Gravity.CENTER_HORIZONTAL
                iconView.layoutParams = params
                iconView.setImageResource(android.R.drawable.ic_menu_camera)
                iconView.setColorFilter(Color.parseColor("#5D4037"))

                val textView = TextView(this)
                val textParams = LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT
                )
                textParams.gravity = android.view.Gravity.CENTER_HORIZONTAL
                textParams.topMargin = (4 * resources.displayMetrics.density).toInt()
                textView.layoutParams = textParams

                textView.text = label
                textView.textSize = 12f
                textView.setTextColor(Color.parseColor("#5D4037"))
                
                container.addView(iconView)
                container.addView(textView)
                
                container.setOnClickListener {
                    val intent = Intent(this, CameraActivity::class.java)
                    intent.putExtra("SILHOUETTE_ID", drawableId)
                    intent.putExtra("COW_NAME", currentCowName)
                    intent.putExtra("ORIENTATION", orientation)
                    startActivity(intent)
                }
                container.isClickable = true
            }
        }
    }
    
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putString("COW_NAME", currentCowName)
    }
}