package com.dano.test1.ui

import android.content.ActivityNotFoundException
import android.content.ContentUris
import android.content.ContentValues
import android.content.Intent
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.pdf.PdfDocument
import android.provider.MediaStore
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import com.dano.test1.LanguageManager
import com.dano.test1.MainActivity
import com.dano.test1.MyApp
import com.dano.test1.questionnaire.GlobalValues
import kotlinx.coroutines.*

class SaveButtonHandler(
    private val activity: MainActivity,
    private val saveButton: Button,
    private val editText: EditText,
    private val languageIDProvider: () -> String
) {

    fun setup() {
        saveButton.text = LanguageManager.getText(languageIDProvider(), "save")
        saveButton.setOnClickListener { handleSaveClick() }
    }

    private fun handleSaveClick() {
        val clientCode = editText.text.toString().trim()
        if (clientCode.isBlank()) {
            val message = LanguageManager.getText(languageIDProvider(), "please_client_code")
            Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
            return
        }
        GlobalValues.LAST_CLIENT_CODE = clientCode
        showCompletedQuestionnaires(clientCode)
    }

    private fun showCompletedQuestionnaires(clientCode: String) {
        CoroutineScope(Dispatchers.IO).launch {
            val actualClientCode = clientCode.removeSuffix("_database")
            val completedEntries = MyApp.database.completedQuestionnaireDao().getAllForClient(actualClientCode)

            Log.d("PDF_DEBUG", "Completed entries for client $actualClientCode:")
            for (entry in completedEntries) {
                Log.d("PDF_DEBUG", "Questionnaire ID: ${entry.questionnaireId}, Done: ${entry.isDone}, Points: ${entry.sumPoints}")
            }

            val pdfDocument = PdfDocument()
            val pageWidth = 595
            val pageHeight = 842
            val paint = Paint().apply { textSize = 12f }

            val csvBuilder = StringBuilder()
            csvBuilder.appendLine("ClientCode,QuestionnaireID,IsDone,Points,Question,Answer")

            for ((index, entry) in completedEntries.withIndex()) {
                val pageInfo = PdfDocument.PageInfo.Builder(pageWidth, pageHeight, index + 1).create()
                var page = pdfDocument.startPage(pageInfo)
                var canvas = page.canvas
                var yPosition = 40f

                canvas.drawText("Client Code: $actualClientCode", 20f, yPosition, paint)
                yPosition += 20f
                canvas.drawText("Questionnaire: ${entry.questionnaireId}", 20f, yPosition, paint)
                yPosition += 20f
                canvas.drawText("Status: ${entry.isDone}", 20f, yPosition, paint)
                yPosition += 20f
                canvas.drawText("Points: ${entry.sumPoints ?: "N/A"}", 20f, yPosition, paint)
                yPosition += 30f

                val answers = MyApp.database.answerDao().getAnswersForClientAndQuestionnaire(actualClientCode, entry.questionnaireId)

                for (answer in answers) {
                    val questionKey = answer.questionId.substringAfter("-")
                    val questionText = LanguageManager.getText("ENGLISH", questionKey)
                    val rawAnswerText = LanguageManager.getText("ENGLISH", answer.answerValue)
                    val answerText = rawAnswerText.trim().removePrefix("[").removeSuffix("]")

                    yPosition = drawMultilineText(canvas, "Question: $questionText", 20f, yPosition, paint, pageWidth - 40, isBold = true)
                    yPosition += 8f
                    yPosition = drawMultilineText(canvas, "Answer: $answerText", 20f, yPosition, paint, pageWidth - 40)
                    yPosition += 20f

                    paint.strokeWidth = 0.5f
                    canvas.drawLine(20f, yPosition - 30f, pageWidth - 20f, yPosition - 30f, paint)
                    paint.strokeWidth = 0f

                    val sanitizedQuestion = questionText.replace(",", " ").replace("\n", " ")
                    val sanitizedAnswer = answerText.replace(",", " ").replace("\n", " ")
                    csvBuilder.appendLine("${actualClientCode},${entry.questionnaireId},${entry.isDone},${entry.sumPoints ?: ""},\"$sanitizedQuestion\",\"$sanitizedAnswer\"")

                    if (yPosition > pageHeight - 60) {
                        pdfDocument.finishPage(page)
                        val newPageInfo = PdfDocument.PageInfo.Builder(pageWidth, pageHeight, pdfDocument.pages.size + 1).create()
                        page = pdfDocument.startPage(newPageInfo)
                        canvas = page.canvas
                        yPosition = 40f
                    }
                }

                pdfDocument.finishPage(page)
            }

            Log.d("CSV_OUTPUT", "Generated CSV:\n${csvBuilder}")

            val pdfFileName = "DatabaseOutput_${actualClientCode}.pdf"
            val csvFileName = "DatabaseOutput_${actualClientCode}.csv"
            val resolver = activity.contentResolver

            val deleteIfExists: (String) -> Unit = { name ->
                val projection = arrayOf(MediaStore.MediaColumns._ID)
                val selection = "${MediaStore.MediaColumns.DISPLAY_NAME} = ?"
                val selectionArgs = arrayOf(name)
                val query = resolver.query(
                    MediaStore.Downloads.EXTERNAL_CONTENT_URI,
                    projection, selection, selectionArgs, null
                )
                query?.use { cursor ->
                    if (cursor.moveToFirst()) {
                        val idColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID)
                        val id = cursor.getLong(idColumn)
                        val deleteUri = ContentUris.withAppendedId(
                            MediaStore.Downloads.EXTERNAL_CONTENT_URI, id
                        )
                        resolver.delete(deleteUri, null, null)
                    }
                }
            }

            deleteIfExists(pdfFileName)
            deleteIfExists(csvFileName)

            try {
                val pdfUri = resolver.insert(
                    MediaStore.Downloads.EXTERNAL_CONTENT_URI,
                    ContentValues().apply {
                        put(MediaStore.MediaColumns.DISPLAY_NAME, pdfFileName)
                        put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf")
                        put(MediaStore.MediaColumns.RELATIVE_PATH, "Download/")
                    }
                )

                val csvUri = resolver.insert(
                    MediaStore.Downloads.EXTERNAL_CONTENT_URI,
                    ContentValues().apply {
                        put(MediaStore.MediaColumns.DISPLAY_NAME, csvFileName)
                        put(MediaStore.MediaColumns.MIME_TYPE, "text/csv")
                        put(MediaStore.MediaColumns.RELATIVE_PATH, "Download/")
                    }
                )

                pdfUri?.let {
                    resolver.openOutputStream(it)?.use { out -> pdfDocument.writeTo(out) }
                    pdfDocument.close()
                }

                csvUri?.let {
                    resolver.openOutputStream(it)?.use { out ->
                        out.write(csvBuilder.toString().toByteArray(Charsets.UTF_8))
                    }
                }

                withContext(Dispatchers.Main) {
                    val msg = LanguageManager.getText(languageIDProvider(), "saved_pdf_csv")
                    Toast.makeText(activity, msg, Toast.LENGTH_LONG).show()

                    pdfUri?.let {
                        val intent = Intent(Intent.ACTION_VIEW).apply {
                            setDataAndType(it, "application/pdf")
                            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NO_HISTORY)
                        }
                        try {
                            activity.startActivity(intent)
                        } catch (e: ActivityNotFoundException) {
                            val noViewer = LanguageManager.getText(languageIDProvider(), "no_pdf_viewer")
                            Toast.makeText(activity, noViewer, Toast.LENGTH_SHORT).show()
                        }
                    }
                }
            } catch (e: Exception) {
                Log.e("SAVE", "Fehler beim Speichern der Dateien", e)
                withContext(Dispatchers.Main) {
                    val errTpl = LanguageManager.getText(languageIDProvider(), "save_error")
                    val msg = (errTpl ?: "Fehler beim Speichern: {message}").replace("{message}", e.message ?: "")
                    Toast.makeText(activity, msg, Toast.LENGTH_LONG).show()
                }
            }
        }
    }

    private fun drawMultilineText(
        canvas: Canvas,
        text: String,
        x: Float,
        yStart: Float,
        paint: Paint,
        maxWidth: Int,
        isBold: Boolean = false
    ): Float {
        paint.isFakeBoldText = isBold

        val words = text.split(" ")
        var line = ""
        var y = yStart
        for (word in words) {
            val testLine = if (line.isEmpty()) word else "$line $word"
            val lineWidth = paint.measureText(testLine)
            if (lineWidth > maxWidth) {
                canvas.drawText(line, x, y, paint)
                y += paint.textSize * 1.4f
                line = word
            } else {
                line = testLine
            }
        }
        if (line.isNotEmpty()) {
            canvas.drawText(line, x, y, paint)
            y += paint.textSize * 1.4f
        }

        paint.isFakeBoldText = false
        return y
    }
}
