package com.crm.chat.utils

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.*
import android.media.AudioManager
import android.media.RingtoneManager
import android.net.Uri
import android.os.Build
import android.os.Vibrator
import android.os.VibrationEffect
import androidx.core.app.NotificationCompat

import com.crm.chat.R
import com.crm.chat.ui.main.MainActivity
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.net.URL

object NotificationHelper {

    private const val BADGE_CHANNEL_ID = "badge_notifications"
    private const val BADGE_CHANNEL_NAME = "Badge Notifications"
    private const val BADGE_CHANNEL_DESCRIPTION = "Persistent notifications for unread message badges"
    private const val BADGE_NOTIFICATION_ID = 999999



    fun createNotificationChannel(context: Context) {
        // Create badge notification channel only
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val importance = NotificationManager.IMPORTANCE_LOW
            val channel = NotificationChannel(BADGE_CHANNEL_ID, BADGE_CHANNEL_NAME, importance).apply {
                description = BADGE_CHANNEL_DESCRIPTION
                // Badge notifications don't need sound or vibration
                enableVibration(false)
                enableLights(true)
            }
            val notificationManager: NotificationManager =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }



    private fun getMessageCountText(count: Int): String {
        return when {
            count % 10 == 1 && count % 100 != 11 -> "$count непрочитанное сообщение"
            count % 10 in 2..4 && count % 100 !in 12..14 -> "$count непрочитанных сообщения"
            else -> "$count непрочитанных сообщений"
        }
    }



    private fun getAvatarCacheFile(context: Context, userId: Long): File {
        val cacheDir = File(context.cacheDir, "user_avatars")
        if (!cacheDir.exists()) {
            cacheDir.mkdirs()
        }
        return File(cacheDir, "avatar_$userId.png")
    }

    fun cacheUserAvatar(context: Context, userInfo: com.crm.chat.data.api.User) {
        println("DEBUG: cacheUserAvatar called for user ${userInfo.id}, avatarUrl=${userInfo.avatarUrl}")
        userInfo.avatarUrl?.let { avatarUrl ->
            try {
                val cacheFile = getAvatarCacheFile(context, userInfo.id)
                println("DEBUG: Cache file path: ${cacheFile.absolutePath}")

                // Skip if already cached
                if (cacheFile.exists()) {
                    println("DEBUG: Avatar already cached for user ${userInfo.id}")
                    return
                }

                println("DEBUG: Downloading avatar from $avatarUrl")
                val url = URL(avatarUrl)
                val connection = url.openConnection() as java.net.HttpURLConnection
                connection.connectTimeout = 15000 // 15 seconds timeout
                connection.readTimeout = 15000
                connection.requestMethod = "GET"
                connection.setRequestProperty("User-Agent", "Android Chat App")
                connection.setRequestProperty("Accept", "image/*")

                // Add authentication headers if available
                val prefs = context.getSharedPreferences("crm_chat_prefs", Context.MODE_PRIVATE)
                val token = prefs.getString("auth_token", null)
                val apiKey = prefs.getString("api_key", null)

                if (token != null) {
                    connection.setRequestProperty("Authorization", "Bearer $token")
                }
                if (apiKey != null) {
                    connection.setRequestProperty("x-api-key", apiKey)
                }

                connection.connect()

                val responseCode = connection.responseCode
                println("DEBUG: HTTP response code: $responseCode")

                if (responseCode == java.net.HttpURLConnection.HTTP_OK) {
                    val inputStream = connection.inputStream
                    val bitmap = BitmapFactory.decodeStream(inputStream)
                    inputStream.close()
                    connection.disconnect()

                    if (bitmap != null) {
                        // Ensure cache directory exists
                        cacheFile.parentFile?.mkdirs()

                        FileOutputStream(cacheFile).use { out ->
                            bitmap.compress(Bitmap.CompressFormat.PNG, 90, out)
                        }
                        bitmap.recycle()
                        println("DEBUG: Successfully cached avatar for user ${userInfo.id}, file size: ${cacheFile.length()}")
                    } else {
                        println("DEBUG: Failed to decode bitmap for user ${userInfo.id}")
                    }
                } else {
                    println("DEBUG: HTTP error $responseCode for user ${userInfo.id}")
                    connection.disconnect()
                }
            } catch (e: IOException) {
                println("DEBUG: Failed to cache avatar for user ${userInfo.id}: ${e.message}")
                e.printStackTrace()
            } catch (e: Exception) {
                println("DEBUG: Unexpected error caching avatar for user ${userInfo.id}: ${e.message}")
                e.printStackTrace()
            }
        } ?: println("DEBUG: No avatar URL for user ${userInfo.id}")
    }

    private fun createUserAvatarBitmap(context: Context, userInfo: com.crm.chat.data.api.User): Bitmap {
        val size = 192 // Standard notification icon size

        // Try to load cached avatar first
        val cacheFile = getAvatarCacheFile(context, userInfo.id)
        println("DEBUG: createUserAvatarBitmap - checking cache file: ${cacheFile.absolutePath}, exists: ${cacheFile.exists()}")

        if (cacheFile.exists()) {
            println("DEBUG: Cache file exists, size: ${cacheFile.length()}")
            try {
                val cachedBitmap = BitmapFactory.decodeFile(cacheFile.absolutePath)
                if (cachedBitmap != null) {
                    println("DEBUG: Successfully decoded cached bitmap for user ${userInfo.id}: ${cachedBitmap.width}x${cachedBitmap.height}")
                    return createCircularBitmap(cachedBitmap, size)
                } else {
                    println("DEBUG: Failed to decode cached bitmap for user ${userInfo.id}")
                }
            } catch (e: Exception) {
                println("DEBUG: Exception loading cached avatar for user ${userInfo.id}: ${e.message}")
                // Delete corrupted cache file
                cacheFile.delete()
            }
        } else {
            println("DEBUG: Cache file does not exist for user ${userInfo.id}")
        }

        // Try to download and cache avatar from URL if available
        userInfo.avatarUrl?.let { avatarUrl ->
            try {
                val url = URL(avatarUrl)
                val connection = url.openConnection()
                connection.connectTimeout = 5000 // 5 seconds timeout
                connection.readTimeout = 5000
                connection.connect()

                val inputStream = connection.getInputStream()
                val originalBitmap = BitmapFactory.decodeStream(inputStream)
                inputStream.close()

                if (originalBitmap != null) {
                    // Cache the downloaded avatar
                    try {
                        FileOutputStream(cacheFile).use { out ->
                            originalBitmap.compress(Bitmap.CompressFormat.PNG, 90, out)
                        }
                    } catch (e: IOException) {
                        println("Failed to cache downloaded avatar for user ${userInfo.id}: ${e.message}")
                    }

                    // Resize and crop to circle
                    return createCircularBitmap(originalBitmap, size)
                }
            } catch (e: IOException) {
                // Fall back to generated avatar if image loading fails
                println("Failed to load avatar from URL: $avatarUrl, error: ${e.message}")
            }
        }

        // Fallback: Generate avatar with initials
        val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)

        // Get user name for initials
        val fullName = userInfo.name
        val initials = if (fullName.isNotBlank()) {
            val parts = fullName.split(" ")
            when (parts.size) {
                1 -> parts[0].take(1).uppercase()
                else -> "${parts[0].take(1)}${parts[1].take(1)}".uppercase()
            }
        } else {
            "U"
        }

        // Generate color based on user ID
        val colors = arrayOf(
            Color.parseColor("#E53935"), // Red
            Color.parseColor("#1E88E5"), // Blue
            Color.parseColor("#43A047"), // Green
            Color.parseColor("#FB8C00"), // Orange
            Color.parseColor("#8E24AA"), // Purple
            Color.parseColor("#00ACC1"), // Cyan
            Color.parseColor("#FDD835"), // Yellow
            Color.parseColor("#6D4C41")  // Brown
        )
        val backgroundColor = colors[(userInfo.id % colors.size).toInt()]

        // Draw circle background
        val paint = Paint().apply {
            color = backgroundColor
            isAntiAlias = true
            style = Paint.Style.FILL
        }
        val rect = RectF(0f, 0f, size.toFloat(), size.toFloat())
        canvas.drawOval(rect, paint)

        // Draw initials text
        paint.apply {
            color = Color.WHITE
            textSize = size * 0.4f
            textAlign = Paint.Align.CENTER
            style = Paint.Style.FILL
        }
        val xPos = size / 2f
        val yPos = size / 2f - (paint.descent() + paint.ascent()) / 2f
        canvas.drawText(initials, xPos, yPos, paint)

        return bitmap
    }


    private fun createCircularBitmap(sourceBitmap: Bitmap, diameter: Int): Bitmap {
        val output = Bitmap.createBitmap(diameter, diameter, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(output)

        val paint = Paint().apply {
            isAntiAlias = true
        }

        // Calculate scaling to fit the bitmap in the circle
        val minEdge = minOf(sourceBitmap.width, sourceBitmap.height)
        val scale = diameter.toFloat() / minEdge
        val matrix = android.graphics.Matrix()
        matrix.postScale(scale, scale)

        // Center the bitmap
        val xOffset = (diameter - sourceBitmap.width * scale) / 2
        val yOffset = (diameter - sourceBitmap.height * scale) / 2
        matrix.postTranslate(xOffset, yOffset)

        // Create circular mask
        val radius = diameter / 2f
        canvas.drawCircle(radius, radius, radius, paint)

        // Apply Porter-Duff mode to clip the bitmap to circle
        paint.xfermode = android.graphics.PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN)
        canvas.drawBitmap(sourceBitmap, matrix, paint)

        sourceBitmap.recycle()

        return output
    }

    private fun createBadgeNotificationChannel(context: Context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val importance = NotificationManager.IMPORTANCE_LOW
            val channel = NotificationChannel(BADGE_CHANNEL_ID, BADGE_CHANNEL_NAME, importance).apply {
                description = BADGE_CHANNEL_DESCRIPTION
            }
            val notificationManager: NotificationManager =
                context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

    fun updateAppIconBadge(context: Context, unreadCount: Int, senderName: String? = null, latestMessage: String? = null, userAvatar: Bitmap? = null) {
        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        if (unreadCount > 0) {
            // Ensure badge notification channel exists
            createBadgeNotificationChannel(context)

            // Create intent to open MainActivity
            val intent = Intent(context, com.crm.chat.ui.main.MainActivity::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            }
            val pendingIntent: PendingIntent = PendingIntent.getActivity(
                context,
                BADGE_NOTIFICATION_ID,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )

            // Use sender avatar as large icon
            val baseAvatar = userAvatar ?: android.graphics.BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher)

            // Use sender name as title if available, otherwise generic title
            val title = senderName ?: "Непрочитанные сообщения"
            val contentText = if (senderName != null && latestMessage != null) {
                latestMessage
            } else {
                val messageText = getMessageCountText(unreadCount)
                "У вас $messageText"
            }

            // Create ongoing notification for badge with avatar as large icon
            val notificationBuilder = NotificationCompat.Builder(context, BADGE_CHANNEL_ID)
                .setSmallIcon(R.mipmap.ic_launcher) // Use app icon as small icon
                .setLargeIcon(baseAvatar) // Use user avatar as large icon
                .setContentTitle(title)
                .setContentText(contentText)
                .setPriority(NotificationCompat.PRIORITY_MIN)
                .setOngoing(true) // Makes it persistent
                .setOnlyAlertOnce(true) // Don't make sound/vibration for updates
                .setNumber(unreadCount) // This sets the badge count on supported launchers
                .setContentIntent(pendingIntent) // Opens app when tapped
                .setAutoCancel(false)

            val badgeNotification = notificationBuilder.build()

            notificationManager.notify(BADGE_NOTIFICATION_ID, badgeNotification)
        } else {
            // Remove badge notification when no unread messages
            notificationManager.cancel(BADGE_NOTIFICATION_ID)
        }
    }


}
