package com.jrz.nfcapp.ui.write

import android.nfc.NdefMessage
import android.nfc.Tag
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.google.android.material.snackbar.Snackbar
import com.jrz.nfcapp.R
import com.jrz.nfcapp.databinding.FragmentWriteBinding
import com.jrz.nfcapp.util.NfcHelper

class WriteFragment : Fragment() {

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

    var isWaitingForTag = false
        private set

    private var pendingMessage: NdefMessage? = null

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        _binding = FragmentWriteBinding.inflate(inflater, container, false)
        return binding.root
    }

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

        binding.etContent.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
            override fun afterTextChanged(s: Editable?) {
                updateByteCount()
            }
        })

        binding.btnWrite.setOnClickListener { startWrite() }
        binding.btnCancelWrite.setOnClickListener { cancelWrite() }
    }

    private fun updateByteCount() {
        val content = binding.etContent.text?.toString() ?: ""
        val bytes = try {
            buildMessage(content).byteArrayLength
        } catch (_: Exception) { content.length }
        binding.tvByteCount.text = "$bytes Bytes"
    }

    private fun startWrite() {
        val content = binding.etContent.text?.toString()?.trim() ?: ""
        if (content.isEmpty()) {
            Snackbar.make(binding.root, "Bitte Inhalt eingeben", Snackbar.LENGTH_SHORT).show()
            return
        }

        pendingMessage = try {
            buildMessage(content)
        } catch (e: Exception) {
            Snackbar.make(binding.root, "Ungültiger Inhalt: ${e.message}", Snackbar.LENGTH_LONG).show()
            return
        }

        isWaitingForTag = true
        binding.btnWrite.isEnabled = false
        binding.btnCancelWrite.visibility = View.VISIBLE
        binding.writeStatusCard.visibility = View.VISIBLE
        binding.tvWriteStatus.text = getString(R.string.write_waiting)
    }

    private fun cancelWrite() {
        isWaitingForTag = false
        pendingMessage = null
        binding.btnWrite.isEnabled = true
        binding.btnCancelWrite.visibility = View.GONE
        binding.writeStatusCard.visibility = View.GONE
    }

    fun onTagScanned(tag: Tag) {
        if (!isWaitingForTag) return
        val msg = pendingMessage ?: return

        Thread {
            try {
                when (NfcHelper.detectWriteMethod(tag)) {
                    NfcHelper.WriteMethod.NFC_V -> {
                        // NFC-V: erst als NDEF formatieren (NdefFormatable), dann NDEF schreiben
                        // Falls NdefFormatable vorhanden → format() macht beides in einem Schritt
                        NfcHelper.writeNdef(tag, msg)
                    }
                    NfcHelper.WriteMethod.MIFARE_CLASSIC ->
                        throw java.io.IOException("MIFARE Classic benötigt Schlüssel zum Schreiben")
                    NfcHelper.WriteMethod.UNSUPPORTED ->
                        throw java.io.IOException("Dieser Tag unterstützt kein Schreiben")
                    else -> NfcHelper.writeNdef(tag, msg)
                }
                requireActivity().runOnUiThread { onWriteSuccess() }
            } catch (e: Exception) {
                requireActivity().runOnUiThread { onWriteError(e.message ?: "Unbekannter Fehler") }
            }
        }.start()
    }

    private fun onWriteSuccess() {
        isWaitingForTag = false
        pendingMessage = null
        binding.btnWrite.isEnabled = true
        binding.btnCancelWrite.visibility = View.GONE
        binding.tvWriteStatus.text = getString(R.string.write_success)
        binding.writeStatusCard.setCardBackgroundColor(resources.getColor(R.color.success_green, null))
    }

    private fun onWriteError(error: String) {
        isWaitingForTag = false
        pendingMessage = null
        binding.btnWrite.isEnabled = true
        binding.btnCancelWrite.visibility = View.GONE
        binding.tvWriteStatus.text = getString(R.string.error_write, error)
        binding.writeStatusCard.setCardBackgroundColor(resources.getColor(R.color.error_red, null))
    }

    private fun buildMessage(content: String): NdefMessage = when {
        binding.chipUrl.isChecked -> NfcHelper.buildUriNdef(content)
        binding.chipHex.isChecked -> NfcHelper.buildRawNdef(content)
        else -> NfcHelper.buildTextNdef(content)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}
