package com.crm.chat.ui.main

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import androidx.core.widget.doOnTextChanged
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.crm.chat.R
import com.crm.chat.data.api.User
import com.crm.chat.data.repository.ChatRepository
import com.crm.chat.databinding.ActivityUserSelectionBinding
import com.crm.chat.databinding.ItemUserBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class UserSelectionActivity : AppCompatActivity() {

    private lateinit var binding: ActivityUserSelectionBinding
    private val viewModel: MainViewModel by viewModels()
    private lateinit var userAdapter: UserAdapter
    private var searchJob: Job? = null
    private val selectedUsers = mutableListOf<User>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityUserSelectionBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // Initialize with auth data
        val prefs = getSharedPreferences("crm_chat_prefs", MODE_PRIVATE)
        val serverUrl = prefs.getString("server_url", "") ?: ""
        val token = prefs.getString("auth_token", "") ?: ""
        val apiKey = prefs.getString("api_key", "") ?: ""

        if (token.isNotEmpty() && serverUrl.isNotEmpty()) {
            viewModel.initialize(this, serverUrl, token, apiKey)
        }

        setupViews()
        loadUsers()
    }

    private fun setupViews() {
        setSupportActionBar(binding.toolbar)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        supportActionBar?.title = "Выберите пользователей"

        // Add Done button to toolbar
        binding.toolbar.inflateMenu(R.menu.menu_user_selection)
        binding.toolbar.setOnMenuItemClickListener { item ->
            when (item.itemId) {
                R.id.action_done -> {
                    onDoneClicked()
                    true
                }
                else -> false
            }
        }

        // Update toolbar subtitle with selection count
        updateToolbarSubtitle()

        // Setup RecyclerView
        userAdapter = UserAdapter(
            onUserClick = { user -> toggleUserSelection(user) },
            isUserSelected = { user -> selectedUsers.contains(user) }
        )

        binding.usersRecyclerView.apply {
            layoutManager = LinearLayoutManager(this@UserSelectionActivity)
            adapter = userAdapter
        }

        // Setup search
        binding.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                searchUsers(query)
                return true
            }

            override fun onQueryTextChange(newText: String?): Boolean {
                // Debounce search
                searchJob?.cancel()
                searchJob = CoroutineScope(Dispatchers.Main).launch {
                    delay(300)
                    searchUsers(newText)
                }
                return true
            }
        })

        // Clear search on back press
        binding.searchView.setOnCloseListener {
            loadUsers()
            false
        }

        // Setup done button at the bottom
        binding.doneButton.setOnClickListener {
            onDoneClicked()
        }

        // Update button visibility based on selection
        updateDoneButtonVisibility()
    }

    private fun loadUsers() {
        binding.progressBar.visibility = android.view.View.VISIBLE
        binding.emptyTextView.visibility = android.view.View.GONE

        CoroutineScope(Dispatchers.Main).launch {
            viewModel.getUsers(null).observe(this@UserSelectionActivity) { result ->
                binding.progressBar.visibility = android.view.View.GONE

                result.fold(
                    onSuccess = { users ->
                        if (users.isEmpty()) {
                            binding.emptyTextView.visibility = android.view.View.VISIBLE
                            binding.emptyTextView.text = "Пользователи не найдены"
                        } else {
                            binding.emptyTextView.visibility = android.view.View.GONE
                            userAdapter.submitList(users)
                        }
                    },
                    onFailure = { exception ->
                        binding.emptyTextView.visibility = android.view.View.VISIBLE
                        binding.emptyTextView.text = "Ошибка загрузки пользователей"
                        Toast.makeText(this@UserSelectionActivity, exception.message, Toast.LENGTH_SHORT).show()
                    }
                )
            }
        }
    }

    private fun searchUsers(query: String?) {
        if (query.isNullOrBlank()) {
            loadUsers()
            return
        }

        binding.progressBar.visibility = android.view.View.VISIBLE
        binding.emptyTextView.visibility = android.view.View.GONE

        CoroutineScope(Dispatchers.Main).launch {
            viewModel.getUsers(query).observe(this@UserSelectionActivity) { result ->
                binding.progressBar.visibility = android.view.View.GONE

                result.fold(
                    onSuccess = { users ->
                        if (users.isEmpty()) {
                            binding.emptyTextView.visibility = android.view.View.VISIBLE
                            binding.emptyTextView.text = "Пользователи не найдены по запросу \"$query\""
                        } else {
                            binding.emptyTextView.visibility = android.view.View.GONE
                            userAdapter.submitList(users)
                        }
                    },
                    onFailure = { exception ->
                        binding.emptyTextView.visibility = android.view.View.VISIBLE
                        binding.emptyTextView.text = "Ошибка поиска"
                        Toast.makeText(this@UserSelectionActivity, exception.message, Toast.LENGTH_SHORT).show()
                    }
                )
            }
        }
    }

    private fun toggleUserSelection(user: User) {
        if (selectedUsers.contains(user)) {
            selectedUsers.remove(user)
        } else {
            selectedUsers.add(user)
        }
        updateToolbarSubtitle()
        updateDoneButtonVisibility()
        userAdapter.notifyDataSetChanged()
    }

    private fun updateToolbarSubtitle() {
        val count = selectedUsers.size
        supportActionBar?.subtitle = when {
            count == 0 -> "Никто не выбран"
            count == 1 -> "Выбран 1 пользователь"
            count < 5 -> "Выбрано $count пользователя"
            else -> "Выбрано $count пользователей"
        }
        updateDoneButtonVisibility()
    }

    private fun updateDoneButtonVisibility() {
        val count = selectedUsers.size
        if (count > 0) {
            binding.doneButton.visibility = android.view.View.VISIBLE
            binding.doneButton.text = when {
                count == 1 -> "Создать личный чат"
                else -> "Создать групповой чат ($count)"
            }
        } else {
            binding.doneButton.visibility = android.view.View.GONE
        }
    }

    private fun onDoneClicked() {
        when (selectedUsers.size) {
            0 -> {
                Toast.makeText(this, "Выберите хотя бы одного пользователя", Toast.LENGTH_SHORT).show()
            }
            1 -> {
                // Single user selection - return immediately for personal chat
                val user = selectedUsers[0]
                val resultIntent = Intent().apply {
                    putExtra("selected_user_id", user.id)
                    putExtra("selected_user_name", user.name)
                    putExtra("chat_type", "personal")
                }
                setResult(Activity.RESULT_OK, resultIntent)
                finish()
            }
            else -> {
                // Multiple users selection - return for group chat
                val userIds = selectedUsers.map { it.id }.toLongArray()
                val userNames = selectedUsers.map { it.name }.toTypedArray()
                val resultIntent = Intent().apply {
                    putExtra("selected_user_ids", userIds)
                    putExtra("selected_user_names", userNames)
                    putExtra("chat_type", "group")
                }
                setResult(Activity.RESULT_OK, resultIntent)
                finish()
            }
        }
    }

    override fun onSupportNavigateUp(): Boolean {
        setResult(Activity.RESULT_CANCELED)
        onBackPressedDispatcher.onBackPressed()
        return true
    }

    class UserAdapter(
        private val onUserClick: (User) -> Unit,
        private val isUserSelected: (User) -> Boolean
    ) : ListAdapter<User, UserAdapter.UserViewHolder>(UserDiffCallback()) {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
            val binding = ItemUserBinding.inflate(
                LayoutInflater.from(parent.context),
                parent,
                false
            )
            return UserViewHolder(binding, onUserClick, isUserSelected)
        }

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

        class UserViewHolder(
            private val binding: ItemUserBinding,
            private val onUserClick: (User) -> Unit,
            private val isUserSelected: (User) -> Boolean
        ) : RecyclerView.ViewHolder(binding.root) {

            fun bind(user: User) {
                binding.userNameTextView.text = user.name
                binding.userIdTextView.text = "ID: ${user.id}"
                binding.userEmailTextView.text = user.email ?: ""

                // Load user avatar or show initials
                if (!user.avatarUrl.isNullOrBlank()) {
                    Glide.with(binding.userAvatarImageView)
                        .load(user.avatarUrl)
                        .circleCrop()
                        .placeholder(android.R.drawable.ic_menu_camera)
                        .error(createInitialsBitmap(user.name))
                        .into(binding.userAvatarImageView)
                } else {
                    binding.userAvatarImageView.setImageBitmap(createInitialsBitmap(user.name))
                }

                // Show selection state
                binding.root.isSelected = isUserSelected(user)
                binding.root.setBackgroundResource(
                    if (isUserSelected(user)) R.color.selected_item_background
                    else android.R.color.transparent
                )

                binding.root.setOnClickListener {
                    onUserClick(user)
                }
            }

            private fun createInitialsBitmap(userName: String): android.graphics.Bitmap {
                // 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"
                    }
                }

                // Get user color based on user ID (assuming we have access to user ID)
                val userId = userName.hashCode().toLong() // Simple hash for color consistency
                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
                    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)

                return bitmap
            }

            private fun getUserColor(userId: Long): Int {
                // Generate a color based on user ID for consistency
                val colors = arrayOf(
                    "#E53935", // Red
                    "#1E88E5", // Blue
                    "#43A047", // Green
                    "#FB8C00", // Orange
                    "#8E24AA", // Purple
                    "#00ACC1", // Cyan
                    "#FDD835", // Yellow
                    "#6D4C41"  // Brown
                )
                // Ensure positive index to avoid ArrayIndexOutOfBoundsException with negative hash codes
                val index = kotlin.math.abs(userId.toInt()) % colors.size
                return android.graphics.Color.parseColor(colors[index])
            }
        }

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

            override fun areContentsTheSame(oldItem: User, newItem: User): Boolean {
                return oldItem == newItem
            }
        }
    }
}
