package com.crm.chat.ui.main

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.crm.chat.data.model.Chat
import com.crm.chat.databinding.ItemChatBinding
import androidx.core.graphics.toColorInt
import java.text.SimpleDateFormat
import java.util.*

class ChatAdapter(
    private val onChatClick: (Chat) -> Unit,
    private val getUserName: (Long) -> String,
    private val getUserAvatarUrl: (Long) -> String?
) :
    ListAdapter<Chat, ChatAdapter.ChatViewHolder>(ChatDiffCallback()) {

    private val dateFormat = SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.getDefault())

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatViewHolder {
        val binding = ItemChatBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
        return ChatViewHolder(binding, onChatClick, getUserName, getUserAvatarUrl, dateFormat)
    }

    override fun onBindViewHolder(holder: ChatViewHolder, position: Int) {
        holder.bind(getItem(position))
    }

    class ChatViewHolder(
        private val binding: ItemChatBinding,
        private val onChatClick: (Chat) -> Unit,
        private val getUserName: (Long) -> String,
        private val getUserAvatarUrl: (Long) -> String?,
        private val dateFormat: SimpleDateFormat
    ) : RecyclerView.ViewHolder(binding.root) {

        fun bind(chat: Chat) {
            // Determine chat display name
            val displayName = when {
                chat.title != null -> chat.title
                chat.type == "personal" && chat.users != null && chat.users.size >= 2 -> {
                    // For personal chats, show the other user's name
                    val currentUserId = 12033923L // Should be from auth store
                    val otherUser = chat.users.find { it.userId != currentUserId }
                    otherUser?.let { user ->
                        // Use cached user data from address book (firstname + lastname)
                        getUserName(user.userId)
                    } ?: "Personal Chat"
                }
                chat.type == "group" -> chat.title ?: "Group Chat"
                else -> "Chat ${chat.id}"
            }

            binding.chatNameTextView.text = displayName
            binding.lastMessageTextView.text = getLastMessageSnippet(chat)
            binding.lastMessageTimeTextView.text = formatTimestamp(chat.lastMessage?.createdAt)

            // Load avatar for personal chats
            if (chat.type == "personal" && chat.users != null && chat.users.size >= 2) {
                val currentUserId = 12033923L // Should be from auth store
                val otherUser = chat.users.find { it.userId != currentUserId }

                if (otherUser != null) {
                    // Try to get user name from cache or API
                    val userName = getUserName(otherUser.userId)
                    loadUserAvatar(otherUser.userId, userName)
                } else {
                    // Fallback to default avatar
                    loadDefaultAvatar()
                }
            } else {
                // For group chats and other types, use group icon
                android.util.Log.d("ChatAdapter", "Loading group avatar for chat ${chat.id}, type: ${chat.type}")
                loadGroupAvatar(chat.title ?: "Group Chat")
            }

            // Handle unread count
            if (chat.unseenCount > 0) {
                binding.unreadCountBadge.text = chat.unseenCount.toString()
                binding.unreadCountBadge.visibility = android.view.View.VISIBLE
            } else {
                binding.unreadCountBadge.visibility = android.view.View.GONE
            }

            // Handle click
            binding.root.setOnClickListener {
                onChatClick(chat)
            }
        }

        private fun getLastMessageSnippet(chat: Chat): String {
            val lastMessage = chat.lastMessage ?: return ""
            
            // Check if message has files
            if (!lastMessage.files.isNullOrEmpty()) {
                val fileType = lastMessage.files[0].fileType
                val fileEmoji = when {
                    fileType?.contains("image") == true -> "🖼️"
                    fileType?.contains("audio") == true -> "🎧"
                    else -> "📎"
                }

                return if (lastMessage.text.isNotEmpty()) {
                    "$fileEmoji ${lastMessage.text}"
                } else {
                    lastMessage.files[0].fileName
                }
            }
            
            // Regular text message
            return lastMessage.text.ifEmpty {
                "💬"
            }
        }

        private fun loadUserAvatar(userId: Long, userName: String) {
            val avatarUrl = getUserAvatarUrl(userId)

            if (!avatarUrl.isNullOrEmpty()) {
                // Clear the circular background for actual avatar images
                binding.chatAvatarImageView.background = null

                // Load actual avatar image from URL with Glide
                Glide.with(binding.chatAvatarImageView.context)
                    .load(avatarUrl)
                    .circleCrop()
                    .placeholder(getUserColor(userId)) // Show color while loading
                    .error(object : com.bumptech.glide.request.target.CustomTarget<android.graphics.drawable.Drawable>() {
                        override fun onResourceReady(resource: android.graphics.drawable.Drawable, transition: com.bumptech.glide.request.transition.Transition<in android.graphics.drawable.Drawable>?) {
                            // Avatar loaded successfully
                            binding.chatAvatarImageView.setImageDrawable(resource)
                        }

                        override fun onLoadCleared(placeholder: android.graphics.drawable.Drawable?) {
                            // Show initials when avatar fails to load
                            showInitialsAvatar(userId, userName)
                        }
                    })
                    .into(binding.chatAvatarImageView)

                print("Loading avatar for $userName: $avatarUrl")
            } else {
                // No avatar URL, show initials
                showInitialsAvatar(userId, userName)
                print("No avatar for $userName, showing initials")
            }
        }

        private fun showInitialsAvatar(userId: Long, userName: String) {
            // Generate initials from user name
            val initials = userName.split(" ").let { parts ->
                when (parts.size) {
                    1 -> parts[0].take(1).uppercase()
                    2 -> "${parts[0].take(1)}${parts[1].take(1)}".uppercase()
                    else -> parts.firstOrNull()?.take(1)?.uppercase() ?: "U"
                }
            }

            // Background color for the avatar
            val backgroundColor = getUserColor(userId)

            // Create circular bitmap with initials
            val size = 192
            val bitmap = android.graphics.Bitmap.createBitmap(size, size, android.graphics.Bitmap.Config.ARGB_8888)
            val canvas = android.graphics.Canvas(bitmap)

            // Draw circle background
            val circlePaint = android.graphics.Paint().apply {
                color = backgroundColor
                isAntiAlias = true
                style = android.graphics.Paint.Style.FILL
            }
            canvas.drawCircle(size / 2f, size / 2f, size / 2f, circlePaint)

            // Draw initials text
            val textPaint = android.graphics.Paint().apply {
                color = android.graphics.Color.WHITE
                textSize = size * 0.5f // Larger text for better visibility
                textAlign = android.graphics.Paint.Align.CENTER
                isAntiAlias = true
                typeface = android.graphics.Typeface.DEFAULT_BOLD
            }

            val xPos = size / 2f
            val yPos = size / 2f - (textPaint.descent() + textPaint.ascent()) / 2f
            canvas.drawText(initials, xPos, yPos, textPaint)

            // Clear any background color from ImageView (let the bitmap be fully circular)
            binding.chatAvatarImageView.setBackgroundColor(android.graphics.Color.TRANSPARENT)
            binding.chatAvatarImageView.setImageBitmap(bitmap)
        }

        private fun loadGroupAvatar(groupName: String) {
            // Load the custom group chat avatar drawable
            val drawable = androidx.core.content.ContextCompat.getDrawable(
                binding.chatAvatarImageView.context,
                com.crm.chat.R.drawable.ic_group_chat
            )

            // Clear the circular background and set the drawable as image source
            binding.chatAvatarImageView.background = null
            binding.chatAvatarImageView.setImageDrawable(drawable)
        }

        private fun loadDefaultAvatar() {
            // Default avatar color
            val color = "#9E9E9E".toColorInt() // Grey
            binding.chatAvatarImageView.setBackgroundColor(color)
        }

        private fun formatTimestamp(timestamp: String?): String {
            if (timestamp.isNullOrEmpty()) return ""
            return try {
                // Assuming timestamp is in ISO format
                val date = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault())
                    .parse(timestamp)
                dateFormat.format(date ?: Date())
            } catch (e: Exception) {
                dateFormat.format(Date())
            }
        }

        private fun getUserColor(userId: Long): Int {
            // Generate a color based on user ID for consistency
            val colors = intArrayOf(
                "#E53935".toColorInt(), // Red
                "#1E88E5".toColorInt(), // Blue
                "#43A047".toColorInt(), // Green
                "#FB8C00".toColorInt(), // Orange
                "#8E24AA".toColorInt(), // Purple
                "#00ACC1".toColorInt(), // Cyan
                "#FDD835".toColorInt(), // Yellow
                "#6D4C41".toColorInt(), // Brown
            )
            return colors[(userId % colors.size).toInt()]
        }
    }

    class ChatDiffCallback : DiffUtil.ItemCallback<Chat>() {
        override fun areItemsTheSame(oldItem: Chat, newItem: Chat): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: Chat, newItem: Chat): Boolean {
            // Compare only fields that affect UI display
            return oldItem.title == newItem.title &&
                   oldItem.type == newItem.type &&
                   oldItem.unseenCount == newItem.unseenCount &&
                   oldItem.hasAccess == newItem.hasAccess &&
                   areUsersTheSame(oldItem.users, newItem.users) &&
                   areLastMessagesTheSame(oldItem.lastMessage, newItem.lastMessage)
        }

        private fun areUsersTheSame(oldUsers: List<com.crm.chat.data.model.ChatUserItem>?, newUsers: List<com.crm.chat.data.model.ChatUserItem>?): Boolean {
            if (oldUsers == null && newUsers == null) return true
            if (oldUsers == null || newUsers == null) return false
            if (oldUsers.size != newUsers.size) return false

            // For chat display, we mainly care about user IDs and roles
            return oldUsers.all { oldUser ->
                newUsers.any { newUser ->
                    oldUser.id == newUser.id && oldUser.userId == newUser.userId && oldUser.role == newUser.role
                }
            }
        }

        private fun areLastMessagesTheSame(oldMsg: com.crm.chat.data.model.ChatMessage?, newMsg: com.crm.chat.data.model.ChatMessage?): Boolean {
            if (oldMsg == null && newMsg == null) return true
            if (oldMsg == null || newMsg == null) return false

            // Compare only display-relevant fields, ignore timestamps and statuses
            return oldMsg.id == newMsg.id &&
                   oldMsg.text == newMsg.text &&
                   oldMsg.chatUserId == newMsg.chatUserId &&
                   oldMsg.files?.map { it.id to it.fileName } == newMsg.files?.map { it.id to it.fileName }
        }
    }
}
