// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.todos;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toolbar;

import io.v.todos.model.DataList;
import io.v.todos.model.ListMetadata;
import io.v.todos.model.ListSpec;
import io.v.todos.persistence.ListEventListener;
import io.v.todos.persistence.MainPersistence;
import io.v.todos.persistence.PersistenceFactory;

/**
 * MainActivity for Vanadium TODOs
 *
 * This activity shows a list of todo lists.
 * - Tap on a Todo List to launch its corresponding TodoListActivity.
 * - Swipe Left on a Todo List to delete it.
 * - Swipe Right in order to mark all of its Tasks as done.
 *
 * @author alexfandrianto
 */
public class MainActivity extends Activity {
    private MainPersistence mPersistence;

    // Snackoos are the code name for the list of todos.
    // These todos are backed up at the SNACKOOS child of the Firebase URL.
    // We use mMainList to track a custom sorted list of the stored values.
    static final String INTENT_SNACKOO_KEY = "snackoo key";
    private DataList<ListMetadata> mMainList = new DataList<>();

    // This adapter handle mirrors the firebase list values and generates the corresponding todo
    // item View children for a list view.
    private TodoListRecyclerAdapter mAdapter;
    private RecyclerView mRecyclerView;

    @Override
    protected void onDestroy() {
        if (mPersistence != null) {
            mPersistence.close();
            mPersistence = null;
        }
        super.onDestroy();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setActionBar(toolbar);
        getActionBar().setTitle(R.string.app_name);

        // Set up the todo list adapter
        mAdapter = new TodoListRecyclerAdapter(mMainList, new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String fbKey = (String)view.getTag();

                Intent intent = new Intent(MainActivity.this, TodoListActivity.class);
                intent.putExtra(INTENT_SNACKOO_KEY, fbKey);
                startActivity(intent);
            }
        });

        mRecyclerView = (RecyclerView)findViewById(R.id.recycler);
        mRecyclerView.setAdapter(mAdapter);

        new ItemTouchHelper(new SwipeableTouchHelperCallback() {
            @Override
            public void onSwiped(final RecyclerView.ViewHolder viewHolder, final int direction) {
                String todoListKey = (String)viewHolder.itemView.getTag();
                if (direction == ItemTouchHelper.RIGHT) {
                    int position = mMainList.findIndexByKey(todoListKey);
                    if (position == -1) {
                        return;
                    }
                    ListMetadata l = mMainList.get(position);
                    if (l.canCompleteAll()) {
                        mPersistence.setCompletion(l, true);
                    } else if (l.numTasks > 0) {
                        mPersistence.setCompletion(l, false);
                    } else {
                        mAdapter.notifyItemChanged(position);
                    }
                } else if (direction == ItemTouchHelper.LEFT) {
                    mPersistence.deleteTodoList(todoListKey);
                }
            }
        }).attachToRecyclerView(mRecyclerView);

        new PersistenceInitializer<MainPersistence>(this) {
            @Override
            protected MainPersistence initPersistence() throws Exception {
                return PersistenceFactory.getMainPersistence(mActivity, createMainListener());
            }

            @Override
            protected void onSuccess(MainPersistence persistence) {
                mPersistence = persistence;
            }
        }.execute(PersistenceFactory.mightGetMainPersistenceBlock());
    }

    // Creates a listener for this activity. Visible to tests to allow them to invoke the listener
    // methods directly.
    @VisibleForTesting
    ListEventListener<ListMetadata> createMainListener() {
        return new ListEventListener<ListMetadata>() {
                    @Override
                    public void onItemAdd(ListMetadata item) {
                        int position = mMainList.insertInOrder(item);

                        mAdapter.notifyItemInserted(position);
                        setEmptyVisiblity();
                    }

                    @Override
                    public void onItemUpdate(final ListMetadata item) {
                        int start = mMainList.findIndexByKey(item.key);
                        int end = mMainList.updateInOrder(item);

                        if (start != end) {
                            mAdapter.notifyItemMoved(start, end);
                        }

                        // The change animation involves a cross-fade that, if interrupted
                        // while another for the same item is already in progress, interacts
                        // badly with ItemTouchHelper's swipe animator. The effect would be
                        // a flicker of the intermediate ListMetadata view, then it fading
                        // out to the latest view but X-translated off the screen due to the
                        // swipe animator.
                        //
                        // We could queue up the next change after the current one, but it's
                        // probably better just to rebind.
                        View view = mRecyclerView.getChildAt(end);
                        if (view.getAlpha() < 1) {
                            mAdapter.bindViewHolder((TodoListViewHolder) mRecyclerView
                                    .getChildViewHolder(view), end);
                        } else {
                            mAdapter.notifyItemChanged(end);
                        }
                    }

                    @Override
                    public void onItemDelete(String key) {
                        int position = mMainList.removeByKey(key);

                        mAdapter.notifyItemRemoved(position);
                        setEmptyVisiblity();
                    }
                };
    }

    // Allow the tests to mock out the main persistence.
    @VisibleForTesting
    void setMainPersistence(MainPersistence p) {
        mPersistence = p;
    }

    // Set the visibility based on what the adapter thinks is the visible item count.
    private void setEmptyVisiblity() {
        View v = findViewById(R.id.empty);
        v.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
    }

    public void initiateItemAdd(View view) {
        UIUtil.showAddDialog(this, "New Todo List", new UIUtil.DialogResponseListener() {
            @Override
            public void handleResponse(String response) {
                mPersistence.addTodoList(new ListSpec(response));
            }
        });
    }

    // The following methods are boilerplate for handling the Menu in the top right corner.
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
