package com.dano.test1.network

import android.app.AlertDialog
import android.content.Context
import android.text.InputType
import android.util.Log
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.Toast
import kotlinx.coroutines.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject

object LoginManager {
    private const val SERVER_LOGIN_URL = "https://daniel-ocks.de/qdb/login.php"
    private const val SERVER_CHANGE_URL = "https://daniel-ocks.de/qdb/change_password.php"
    private val client = OkHttpClient()

    fun loginUserWithCredentials(
        context: Context,
        username: String,
        password: String,
        onSuccess: (String) -> Unit,
        onError: (String) -> Unit
    ) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val bodyJson = JSONObject()
                    .put("username", username)
                    .put("password", password)
                    .toString()
                    .toRequestBody("application/json".toMediaType())

                val request = Request.Builder()
                    .url(SERVER_LOGIN_URL)
                    .post(bodyJson)
                    .build()

                val response = client.newCall(request).execute()
                val text = response.body?.string()

                if (!response.isSuccessful || text == null) {
                    withContext(Dispatchers.Main) { onError("Fehler beim Login (${response.code})") }
                    return@launch
                }

                val json = JSONObject(text)
                if (!json.optBoolean("success")) {
                    withContext(Dispatchers.Main) { onError(json.optString("message", "Login fehlgeschlagen")) }
                    return@launch
                }

                // Passwortwechsel erforderlich?
                if (json.optBoolean("must_change_password", false)) {
                    withContext(Dispatchers.Main) {
                        showChangePasswordDialog(
                            context = context,
                            username = username,
                            oldPassword = password,
                            onChanged = { token ->
                                // Nach PW-Änderung direkt eingeloggt
                                TokenStore.save(context, token, username)
                                onSuccess(token)
                            },
                            onError = onError
                        )
                    }
                    return@launch
                }

                // normaler Login: Token speichern
                val token = json.getString("token")
                TokenStore.save(context, token, username)
                withContext(Dispatchers.Main) { onSuccess(token) }

            } catch (e: Exception) {
                Log.e("LOGIN", "Exception", e)
                withContext(Dispatchers.Main) { onError("Exception: ${e.message}") }
            }
        }
    }

    private fun showChangePasswordDialog(
        context: Context,
        username: String,
        oldPassword: String,
        onChanged: (String) -> Unit,
        onError: (String) -> Unit
    ) {
        val container = LinearLayout(context).apply {
            orientation = LinearLayout.VERTICAL
            setPadding(48, 24, 48, 0)
        }
        val etNew = EditText(context).apply {
            hint = "Neues Passwort"
            inputType = InputType.TYPE_CLASS_TEXT or
                    InputType.TYPE_TEXT_VARIATION_PASSWORD
        }
        val etRepeat = EditText(context).apply {
            hint = "Neues Passwort (wiederholen)"
            inputType = InputType.TYPE_CLASS_TEXT or
                    InputType.TYPE_TEXT_VARIATION_PASSWORD
        }
        container.addView(etNew)
        container.addView(etRepeat)

        val dialog = AlertDialog.Builder(context)
            .setTitle("Passwort ändern")
            .setMessage("Du verwendest ein Standard-Konto. Bitte setze jetzt ein eigenes Passwort.")
            .setView(container)
            .setPositiveButton("OK", null)        // nicht sofort schließen lassen
            .setNegativeButton("Abbrechen", null) // nicht sofort schließen lassen
            .setCancelable(false)
            .create()

        dialog.setOnShowListener {
            val btnOk = dialog.getButton(AlertDialog.BUTTON_POSITIVE)
            val btnCancel = dialog.getButton(AlertDialog.BUTTON_NEGATIVE)

            btnOk.setOnClickListener {
                etNew.error = null
                etRepeat.error = null

                val p1 = etNew.text?.toString().orEmpty()
                val p2 = etRepeat.text?.toString().orEmpty()

                when {
                    p1.length < 6 -> {
                        etNew.error = "Mindestens 6 Zeichen."
                        return@setOnClickListener
                    }
                    p1 != p2 -> {
                        etRepeat.error = "Passwörter stimmen nicht überein."
                        return@setOnClickListener
                    }
                    else -> {
                        btnOk.isEnabled = false
                        btnCancel.isEnabled = false
                        changePassword(
                            context = context,
                            username = username,
                            oldPassword = oldPassword,
                            newPassword = p1,
                            onChanged = { token ->
                                dialog.dismiss()
                                onChanged(token)
                            },
                            onError = { msg ->
                                btnOk.isEnabled = true
                                btnCancel.isEnabled = true
                                Toast.makeText(context, msg, Toast.LENGTH_LONG).show()
                            }
                        )
                    }
                }
            }

            // >>> Überarbeitet: Abbrechen schließt Dialog und informiert den Aufrufer
            btnCancel.setOnClickListener {
                dialog.dismiss()
                onError("Passwortänderung abgebrochen.")
            }
        }

        dialog.show()
    }



    private fun changePassword(
        context: Context,
        username: String,
        oldPassword: String,
        newPassword: String,
        onChanged: (String) -> Unit,
        onError: (String) -> Unit
    ) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val body = JSONObject()
                    .put("username", username)
                    .put("old_password", oldPassword)
                    .put("new_password", newPassword)
                    .toString()
                    .toRequestBody("application/json".toMediaType())

                val req = Request.Builder()
                    .url(SERVER_CHANGE_URL)
                    .post(body)
                    .build()

                val resp = client.newCall(req).execute()
                val txt = resp.body?.string()

                if (!resp.isSuccessful || txt == null) {
                    withContext(Dispatchers.Main) { onError("Fehler beim Ändern (${resp.code})") }
                    return@launch
                }

                val json = JSONObject(txt)
                if (!json.optBoolean("success")) {
                    withContext(Dispatchers.Main) { onError(json.optString("message", "Ändern fehlgeschlagen")) }
                    return@launch
                }

                val token = json.getString("token")
                withContext(Dispatchers.Main) { onChanged(token) }

            } catch (e: Exception) {
                Log.e("LOGIN", "changePassword Exception", e)
                withContext(Dispatchers.Main) { onError("Exception: ${e.message}") }
            }
        }
    }
}
