package org.apache.fineract.ui.online.customers.customerlist;

import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import androidx.annotation.Nullable;
import androidx.appcompat.widget.SearchView;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.transition.TransitionManager;

import com.github.therajanmaurya.sweeterror.SweetUIErrorHandler;

import org.apache.fineract.R;
import org.apache.fineract.data.local.PreferencesHelper;
import org.apache.fineract.data.models.customer.Customer;
import org.apache.fineract.ui.adapters.CustomerAdapter;
import org.apache.fineract.ui.base.FineractBaseActivity;
import org.apache.fineract.ui.base.FineractBaseFragment;
import org.apache.fineract.ui.base.OnItemClickListener;
import org.apache.fineract.ui.base.Toaster;
import org.apache.fineract.ui.online.customers.createcustomer.CustomerAction;
import org.apache.fineract.ui.online.customers.createcustomer.customeractivity.CreateCustomerActivity;
import org.apache.fineract.ui.online.customers.customerdetails.CustomerDetailsActivity;
import org.apache.fineract.utils.ConstantKeys;

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

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

import static android.app.Activity.RESULT_OK;

/**
 * @author Rajan Maurya
 * On 20/06/17.
 */
public class CustomersFragment extends FineractBaseFragment implements CustomersContract.View,
        SwipeRefreshLayout.OnRefreshListener, OnItemClickListener {

    private static final Integer CUSTOMER_STATUS = 1;

    @BindView(R.id.rv_customers)
    RecyclerView rvCustomers;

    @BindView(R.id.swipe_container)
    SwipeRefreshLayout swipeRefreshLayout;

    @BindView(R.id.layout_error)
    View layoutError;

    View rootView;

    @Inject
    CustomersPresenter customerPresenter;

    @Inject
    CustomerAdapter customerAdapter;

    @Inject
    PreferencesHelper preferencesHelper;

    @BindView(R.id.rb_offline)
    RadioButton rbOffline;

    @BindView(R.id.rb_online)
    RadioButton rbOnline;

    @BindView(R.id.rg_search)
    RadioGroup rgSearch;

    @BindView(R.id.coordinator)
    CoordinatorLayout coordinator;

    @BindView(R.id.ll_search)
    LinearLayout llSearch;

    private List<Customer> customers;
    private Integer detailsCustomerPosition;
    private boolean isNewCustomer = false;
    private SweetUIErrorHandler sweetUIErrorHandler;

    public static CustomersFragment newInstance() {
        CustomersFragment fragment = new CustomersFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        customers = new ArrayList<>();
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_customer_list, container, false);
        ((FineractBaseActivity) getActivity()).getActivityComponent().inject(this);
        ButterKnife.bind(this, rootView);
        initializeFineractUIErrorHandler(getActivity(), rootView);
        customerPresenter.attachView(this);
        setToolbarTitle(getString(R.string.customers));

        showUserInterface();
        sweetUIErrorHandler = new SweetUIErrorHandler(getActivity(), rootView);

        return rootView;
    }

    @Override
    public void onResume() {
        super.onResume();
        if (preferencesHelper.isFetching()) {
            sweetUIErrorHandler.showSweetCustomErrorUI(getString(R.string.syncing_please_wait),
                    R.drawable.ic_error_black_24dp, swipeRefreshLayout, layoutError);
        } else {
            customerPresenter.fetchCustomers(0, false);
        }
        if (isNewCustomer) {
            isNewCustomer = false;
            customerPresenter.fetchCustomers(0, false);
        }
    }

    @Override
    public void onRefresh() {
        customerPresenter.fetchCustomers(0, false);
        sweetUIErrorHandler.hideSweetErrorLayoutUI(rvCustomers, layoutError);
    }

    @OnClick(R.id.btn_try_again)
    void onRetry() {
        customerPresenter.fetchCustomers(0, false);
        sweetUIErrorHandler.hideSweetErrorLayoutUI(rvCustomers, layoutError);
    }

    @Override
    public void showUserInterface() {
        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        rvCustomers.setLayoutManager(layoutManager);
        rvCustomers.setHasFixedSize(true);
        customerAdapter.setOnItemClickListener(this);
        rvCustomers.setAdapter(customerAdapter);
        swipeRefreshLayout.setColorSchemeColors(getActivity()
                .getResources().getIntArray(R.array.swipeRefreshColors));
        swipeRefreshLayout.setOnRefreshListener(this);
        sweetUIErrorHandler = new SweetUIErrorHandler(getActivity(), rootView);
    }

    @OnClick(R.id.fab_add_customer)
    void addCustomer() {
        isNewCustomer = true;
        Intent intent = new Intent(getActivity(), CreateCustomerActivity.class);
        intent.putExtra(ConstantKeys.CUSTOMER_ACTION, CustomerAction.CREATE);
        startActivity(intent);
    }

    @Override
    public void showCustomers(List<Customer> customers) {
        showRecyclerView(true);
        this.customers = customers;
        customerAdapter.setCustomers(customers);
    }

    @Override
    public void showMoreCustomers(List<Customer> customers) {
        showRecyclerView(true);
        this.customers.addAll(customers);
        customerAdapter.setMoreCustomers(customers);
    }

    @Override
    public void showEmptyCustomers(String message) {
        showRecyclerView(false);
        sweetUIErrorHandler.showSweetCustomErrorUI(message,
                R.drawable.ic_customer_black_24dp, rvCustomers, layoutError);
    }

    @Override
    public void showRecyclerView(boolean status) {
        if (status) {
            rvCustomers.setVisibility(View.VISIBLE);
            layoutError.setVisibility(View.GONE);
        } else {
            rvCustomers.setVisibility(View.GONE);
            layoutError.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void showProgressbar() {
        swipeRefreshLayout.setRefreshing(true);
    }

    @Override
    public void hideProgressbar() {
        swipeRefreshLayout.setRefreshing(false);
    }

    @Override
    public void showMessage(String errorMessage) {
        Toaster.show(rootView, errorMessage);
    }

    @Override
    public void searchCustomerList(Customer customer) {
        customerAdapter.setCustomers(Collections.singletonList(customer));
    }

    @Override
    public void showNoInternetConnection() {
        showRecyclerView(false);
        showFineractNoInternetUI();
        sweetUIErrorHandler.showSweetNoInternetUI(swipeRefreshLayout, layoutError);
    }

    @Override
    public void showError(String message) {
        if (customerAdapter.getItemCount() != 0) {
            sweetUIErrorHandler.showSweetCustomErrorUI(message,
                    R.drawable.ic_error_black_24dp, swipeRefreshLayout, layoutError);
        } else {
            showRecyclerView(false);
            sweetUIErrorHandler.showSweetCustomErrorUI(getString(R.string.customers),
                    R.drawable.ic_error_black_24dp, swipeRefreshLayout, layoutError);
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        customerPresenter.detachView();
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.menu_customer, menu);
        setUpSearchInterface(menu);
    }

    private void setUpSearchInterface(Menu menu) {

        SearchManager manager = (SearchManager) getActivity().
                getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(
                R.id.menu_customer_search).getActionView();
        searchView.setSearchableInfo(manager.getSearchableInfo(getActivity().getComponentName()));

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                findCustomer(query);
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                if (TextUtils.isEmpty(newText)) {
                    customerAdapter.setCustomers(customers);
                }

                return false;
            }
        });

        searchView.setOnSearchClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TransitionManager.beginDelayedTransition(coordinator);
                llSearch.setVisibility(View.VISIBLE);
            }
        });

        searchView.setOnCloseListener(new SearchView.OnCloseListener() {
            @Override
            public boolean onClose() {
                rgSearch.clearCheck();
                TransitionManager.beginDelayedTransition(coordinator);
                llSearch.setVisibility(View.GONE);
                return false;
            }
        });
    }

    private void findCustomer(String query) {

        if (rgSearch.getCheckedRadioButtonId() == -1) {
            Toaster.show(swipeRefreshLayout, getString(R.string.error_finding_customer_options),
                    Toaster.SHORT);
        } else if (rbOnline.isChecked()) {
            customerPresenter.searchCustomerOnline(query);
        }
    }


    @Override
    public void onItemClick(View childView, int position) {
        detailsCustomerPosition = position;
        Intent customerDetailsIntent = new Intent(getActivity(), CustomerDetailsActivity.class);
        customerDetailsIntent.putExtra(ConstantKeys.CUSTOMER_IDENTIFIER,
                customers.get(position).getIdentifier());
        startActivityForResult(customerDetailsIntent, CUSTOMER_STATUS);
    }

    @Override
    public void onItemLongPress(View childView, int position) {

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if ((requestCode == CUSTOMER_STATUS) && (resultCode == RESULT_OK)) {
            Customer.State state = (Customer.State) data.getSerializableExtra(
                    ConstantKeys.CUSTOMER_STATUS);
            customers.get(detailsCustomerPosition).setCurrentState(state);
            customerAdapter.notifyItemChanged(detailsCustomerPosition);
        }
    }
}
