package dominando.android.livros

import android.os.Bundle
import android.view.*
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.auth.FirebaseAuth
import dominando.android.livros.R.id.fabAdd
import dominando.android.livros.R.id.rvBooks
import dominando.android.livros.common.observeOnce
import dominando.android.presentation.BookListViewModel
import dominando.android.presentation.BookVmFactory
import dominando.android.presentation.binding.Book
import kotlinx.android.synthetic.main.fragment_book_list.*
import org.parceler.Parcels

class BookListFragment : BaseFragment() {
    private val viewModel: BookListViewModel by lazy {
        ViewModelProviders.of(this,
                BookVmFactory(requireActivity().application)
        ).get(BookListViewModel::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
    }

    override fun onCreateView(inflater: LayoutInflater,
                              container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_book_list, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        updateList(emptyList())
        fabAdd.setOnClickListener {
            newBook()
        }
    }

    override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
        super.onCreateOptionsMenu(menu, inflater)
        inflater?.inflate(R.menu.main, menu)
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        if (item?.itemId == R.id.menu_sign_out) {
            FirebaseAuth.getInstance().signOut()
            return true
        }
        return super.onOptionsItemSelected(item)
    }

    override fun init() {
        try {
            viewModel.getBooks().observe(this, Observer { books ->
                updateList(books)
            })
        } catch (e: Exception) {
            Toast.makeText(requireContext(), R.string.message_error_load_books,
                    Toast.LENGTH_SHORT).show()
        }
    }

    private fun updateList(books: List<Book>) {
        rvBooks.layoutManager = LinearLayoutManager(requireContext())
        rvBooks.adapter = BookAdapter(books) { book ->
            viewDetails(book)
        }
        attachSwipeToRecyclerView()
    }

    private fun attachSwipeToRecyclerView() {
        val swipe = object : ItemTouchHelper.SimpleCallback(
                0,
                ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
            override fun onMove(recyclerView: RecyclerView,
                                viewHolder: RecyclerView.ViewHolder,
                                target: RecyclerView.ViewHolder): Boolean {
                return false
            }

            override fun onSwiped(viewHolder: RecyclerView.ViewHolder,
                                  direction: Int) {
                val position = viewHolder.adapterPosition
                deleteBookFromPosition(position)
            }
        }
        val itemTouchHelper = ItemTouchHelper(swipe)
        itemTouchHelper.attachToRecyclerView(rvBooks)
    }

    private fun deleteBookFromPosition(position: Int) {
        val adapter = rvBooks.adapter as BookAdapter
        val book = adapter.books[position]
        viewModel.remove(book).observeOnce(this, Observer { success ->
            if (!success) {
                Toast.makeText(requireContext(),
                        R.string.message_error_delete_book, Toast.LENGTH_SHORT).show()
            }
        })
    }

    private fun newBook() {
        navController.navigate(R.id.action_list_to_form)
    }

    private fun viewDetails(book: Book) {
        val args = Bundle().apply {
            putParcelable("book", Parcels.wrap(book))
        }
        navController.navigate(R.id.action_list_to_details, args)
    }
}