// 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.sharing;

import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;

import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import javax.annotation.Nullable;

import io.v.todos.R;
import io.v.todos.persistence.syncbase.SyncbasePersistence;
import io.v.v23.InputChannelCallback;
import io.v.v23.InputChannels;
import io.v.v23.context.VContext;
import io.v.v23.discovery.Update;
import io.v.v23.verror.VException;

/**
 * The share dialog contains two recycler views. The top one shows the existing items, and the
 * bottom shows ones that are nearby but not shared to yet. There's also a freeform text box to
 * allow entry of any value. Confirming this dialog sends the set of added and removed emails. Tap
 * to add/remove.
 */
public class ShareListDialogFragment extends DialogFragment
        implements ContactAdapter.ContactTouchListener {
    public static final String FRAGMENT_TAG = ShareListDialogFragment.class.getSimpleName();

    public static ShareListDialogFragment find(FragmentManager fragmentManager) {
        return (ShareListDialogFragment) fragmentManager.findFragmentByTag(FRAGMENT_TAG);
    }

    private RecyclerView mContacts;
    private Set<String> mRemoved, mAdded, mRecent;

    private static final String
            REMOVED_KEY = "removedShares",
            ADDED_KEY = "addedShares",
            RECENT_KEY = "recentShares";

    private ContactAdapter mAdapter;

    private ShareListMenuFragment getParent() {
        return ((ShareListMenuFragment) getParentFragment());
    }

    @Override
    public void onDestroyView() {
        rmAdapter(mAdapter);
        super.onDestroyView();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putStringArrayList(REMOVED_KEY, new ArrayList<>(mRemoved));
        outState.putStringArrayList(ADDED_KEY, new ArrayList<>(mAdded));
        outState.putStringArrayList(RECENT_KEY, new ArrayList<>(mRecent));
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        View view = getActivity().getLayoutInflater().inflate(R.layout.sharing, null);

        if (savedInstanceState == null) {
            mRemoved = new HashSet<>();
            mAdded = new HashSet<>();
            mRecent = new HashSet<>();
        } else {
            mRemoved = new HashSet<>(savedInstanceState.getStringArrayList(REMOVED_KEY));
            mAdded = new HashSet<>(savedInstanceState.getStringArrayList(ADDED_KEY));
            mRecent = new HashSet<>(savedInstanceState.getStringArrayList(RECENT_KEY));
        }

        mAdapter = new ContactAdapter(getParent().getSharedTo(), mAdded, mRemoved, mRecent);
        mAdapter.setContactTouchListener(this);
        mContacts = (RecyclerView) view.findViewById(R.id.recycler);
        mContacts.setAdapter(mAdapter);
        addAdapter(mAdapter);

        final EditText editText = (EditText) view.findViewById(R.id.custom_email);
        editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                boolean handled = false;
                if (actionId == EditorInfo.IME_ACTION_SEND) {
                    String email = editText.getText().toString();
                    mAdapter.onCustomShare(email);
                    editText.setText("");
                    handled = true;
                }
                return handled;
            }
        });

        return new AlertDialog.Builder(getActivity())
                .setView(view)
                .setPositiveButton("Save", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        mAdapter.filterDeltas();
                        getParent().persistence.shareTodoList(mAdded);
                        // TODO(alexfandrianto/rosswang): removal
                    }
                })
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                    }
                })
                .create();
    }

    private static void handleScanningError(Throwable t) {
        //TODO(rosswang): indicate error in the view
        SyncbasePersistence.getAppErrorReporter().onError(R.string.err_scan_nearby, t);
    }

    public void onSharedToChanged() {
        mContacts.post(new Runnable() {
            @Override
            public void run() {
                mAdapter.setSharedTo(getParent().getSharedTo());
            }
        });
    }

    @Override
    public void onContactTouch(RecyclerView.ViewHolder viewHolder) {
        mAdapter.toggleContact(viewHolder.getAdapterPosition());
    }
    
    private static Set<String> mEmails = new HashSet<String>();
    private static Set<ContactAdapter> mAdapters = new HashSet<ContactAdapter>();
    
    public static synchronized void addEmail(String email) {
        mEmails.add(email);
        for(ContactAdapter adapter : mAdapters) {
            adapter.onNearbyDeviceDiscovered(email);
        }
    }
    public static synchronized void rmEmail(String email) {
        mEmails.remove(email);
        for(ContactAdapter adapter : mAdapters) {
            adapter.onNearbyDeviceLost(email);
        }
    }
    public static synchronized void addAdapter(ContactAdapter adapter) {
        mAdapters.add(adapter);
        for(String email : mEmails) {
            adapter.onNearbyDeviceDiscovered(email);
        }
    }
    public static synchronized void rmAdapter(ContactAdapter adapter) {
        mAdapters.remove(adapter);
    }
    
    public static void initScan() {
        VContext mScanContext = SyncbasePersistence.getAppVContext();
        try {
            ListenableFuture<Void> scan = InputChannels.withCallback(
                    Sharing.getDiscovery().scan(mScanContext,
                            "v.InterfaceName = \"" + Sharing.getPresenceInterface() + "\""),
                    new InputChannelCallback<Update>() {
                        @Override
                        public ListenableFuture<Void> onNext(Update result) {
                            final String email = Iterables.getOnlyElement(result.getAddresses());
                            if (email == null ||
                                    email.equals(SyncbasePersistence.getPersonalEmail())) {
                                return null;
                            }
                            if (result.isLost()) {
                                rmEmail(email);
                            } else {
                                addEmail(email);
                            }
                            return null;
                        }
                    });
            Futures.addCallback(scan, new FutureCallback<Void>() {
                @Override
                public void onSuccess(@Nullable Void result) {
                }

                @Override
                public void onFailure(Throwable t) {
                    handleScanningError(t);
                }
            });
        } catch (VException e) {
            handleScanningError(e);
        }
    }   
}
