// Copyright (c) 2017-2018, Tom Geiselmann
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge, publish, distribute,
// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY,WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package com.none.tom.simplerssreader.fragment;

import android.app.Activity;
import android.app.LoaderManager;
import android.content.Context;
import android.content.Loader;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.none.tom.simplerssreader.R;
import com.none.tom.simplerssreader.activity.MainActivity;
import com.none.tom.simplerssreader.adapter.SavedEntriesAdapter;
import com.none.tom.simplerssreader.feed.SavedEntries;
import com.none.tom.simplerssreader.fragment.base.BaseRecyclerViewFragment;
import com.none.tom.simplerssreader.library.jBCrypt.*;
import com.none.tom.simplerssreader.loader.SavedEntriesDeleteLoader;
import com.none.tom.simplerssreader.loader.SavedEntriesQueryLoader;
import com.none.tom.simplerssreader.loader.SavedEntriesSaveLoader;
import com.none.tom.simplerssreader.utils.CenterLayoutManager;
import com.none.tom.simplerssreader.utils.SharedPrefUtils;
import com.none.tom.simplerssreader.utils.VerticalSpaceItemDecoration;

import java.util.ArrayList;
import java.util.List;

import static com.none.tom.simplerssreader.utils.Constants.DIVIDER_WIDTH;
import static com.none.tom.simplerssreader.utils.Constants.KEY_HASHED_PASSWORD;

public class SavedEntriesFragment extends BaseRecyclerViewFragment implements LoaderManager.LoaderCallbacks {
    public static final String TAG = "saved_entries_fragment";

    private static final String KEY_CAN_ACCESS = "key_can_access";
    private static final String KEY_SORT_ORDER = "key_sort_order";
    private static final String KEY_POSITIONS = "key_positions";
    private static final String KEY_ENTRY_URLS = "key_entry_urls";
    private static final String KEY_ENTRY_TITLES = "key_entry_titles";

    private boolean mCanAccessSavedEntries;
    private int mSortOrder;

    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;

    @Override
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
                             final Bundle savedInstanceState) {
        final View view =
                inflater.inflate(R.layout.fragment_saved_entries_recyclerview, container, false);

        final Activity activity = getActivity();

        mRecyclerView = view.findViewById(R.id.SavedEntriesRecyclerView);
        mRecyclerView.setLayoutManager(new CenterLayoutManager(activity));

        mSortOrder = SharedPrefUtils.getInt(activity, KEY_SORT_ORDER);

        if (savedInstanceState == null || !savedInstanceState.getBoolean(KEY_CAN_ACCESS, false)) {
            if (!TextUtils.isEmpty(SharedPrefUtils.getString(activity, KEY_HASHED_PASSWORD))) {
                SavedEntriesPasswordFragment.getInstance()
                        .show(getFragmentManager(), SavedEntriesPasswordFragment.TAG);
            } else {
                SavedEntriesSetupPasswordFragment.getInstance()
                     .show(getFragmentManager(), SavedEntriesSetupPasswordFragment.TAG);
            }
        }

        super.initialize((CoordinatorLayout) view, mRecyclerView);

        activity.invalidateOptionsMenu();

        return view;
    }

    @Override
    public void onViewStateRestored(final Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);

        if (savedInstanceState != null) {
            mCanAccessSavedEntries = savedInstanceState.getBoolean(KEY_CAN_ACCESS, false);

            if (mCanAccessSavedEntries) {
                super.onViewStateRestored(savedInstanceState);
                getLoaderManager().restartLoader(SavedEntriesQueryLoader.ID, null, this);
            }
        }
    }

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

        outState.putBoolean(KEY_CAN_ACCESS, mCanAccessSavedEntries);

        if (mCanAccessSavedEntries) {
            super.onSaveInstanceState(outState);
        }
    }

    @Override
    public Loader onCreateLoader(final int id, final Bundle args) {
        switch (id) {
            case SavedEntriesQueryLoader.ID:
                return new SavedEntriesQueryLoader(getActivity(), getSortOrder());
            case SavedEntriesDeleteLoader.ID:
                return new SavedEntriesDeleteLoader(getActivity(),
                        args.getIntegerArrayList(KEY_POSITIONS));
            default:
                return null;
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public void onLoadFinished(final Loader loader, final Object data) {
        final int id = loader.getId();

        switch (id) {
            case SavedEntriesQueryLoader.ID:
                onDbQueryResult();
                break;
            case SavedEntriesDeleteLoader.ID:
                onSavedEntriesDeleted((List<Integer>) data);
                break;
        }

        getLoaderManager().destroyLoader(id);
    }

    @Override
    public void onLoaderReset(final Loader loader) {}

    @SuppressWarnings({"ConstantConditions", "SuspiciousNameCombination"})
    private void onDbQueryResult() {
        final Activity activity = getActivity();

        final VerticalSpaceItemDecoration decor =
                new VerticalSpaceItemDecoration(activity, DIVIDER_WIDTH);
        decor.setDrawable(activity.getDrawable(R.drawable.divider));

        mRecyclerView.addItemDecoration(decor);

        mAdapter = new SavedEntriesAdapter((MainActivity) activity);
        mRecyclerView.setAdapter(mAdapter);

        if (mRecyclerView.getVisibility() != View.VISIBLE) {
            mRecyclerView.setVisibility(View.VISIBLE);
        }
    }

    private void onSavedEntriesDeleted(final List<Integer> positions) {
        for (final int position : positions) {
            mAdapter.notifyItemRemoved(position);
        }
    }

    public void changeSortOrder(final int newSortOrder) {
        setSortOrder(newSortOrder);
        SavedEntries.reverse();

        SharedPrefUtils.put(getActivity(), KEY_SORT_ORDER, mSortOrder);

        mAdapter.notifyDataSetChanged();
    }

    public void deleteSavedEntries(final ArrayList<Integer> positions) {
        final Bundle args = new Bundle();
        args.putIntegerArrayList(KEY_POSITIONS, positions);

        getLoaderManager().restartLoader(SavedEntriesDeleteLoader.ID, args, this);
    }

    public int getSortOrder() {
        return mSortOrder;
    }

    public boolean isPasswordValid(final Context context, final String validatePassword) {
        final String password = SharedPrefUtils.getString(context, KEY_HASHED_PASSWORD);

        return !TextUtils.isEmpty(password) && !TextUtils.isEmpty(password) &&
                BCrypt.checkpw(validatePassword, password);
    }

    private void putPasswordHash(final String password) {
        if (TextUtils.isEmpty(password)) {
            SharedPrefUtils.put(getActivity(), KEY_HASHED_PASSWORD, password);
        } else {
            SharedPrefUtils.put(getActivity(), KEY_HASHED_PASSWORD,
                    BCrypt.hashpw(password, BCrypt.gensalt()));
        }
    }

    public void querySavedEntries() {
        mCanAccessSavedEntries = true;
        getLoaderManager().restartLoader(SavedEntriesQueryLoader.ID, null, this);
    }

    public void resetPassword() {
        putPasswordHash(null);

        SavedEntriesSetupPasswordFragment.getInstance().show(getFragmentManager(),
                SavedEntriesSetupPasswordFragment.TAG);
    }

    public void saveEntry(final MainActivity activity, final ArrayList<String> entryUrls,
                          final ArrayList<String> entryTitles) {
        final Bundle args = new Bundle();

        args.putStringArrayList(KEY_ENTRY_URLS, entryUrls);
        args.putStringArrayList(KEY_ENTRY_TITLES, entryTitles);

        activity.getLoaderManager().restartLoader(SavedEntriesSaveLoader.ID, args, activity);
    }

    private void setSortOrder(final int sortOrder) {
        mSortOrder = sortOrder;
    }

    public boolean setupPassword(final String password, final String confirmPassword) {
        if (!password.equals(confirmPassword)) {
            return false;
        }

        putPasswordHash(password);

        return true;
    }
}