package org.apache.fineract.ui.online.loanaccounts.loanapplication.loandetails;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.textfield.TextInputLayout;
import androidx.core.widget.NestedScrollView;
import androidx.appcompat.widget.AppCompatSpinner;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;

import com.stepstone.stepper.Step;
import com.stepstone.stepper.VerificationError;

import org.apache.fineract.R;
import org.apache.fineract.data.models.loan.LoanAccount;
import org.apache.fineract.data.models.loan.PaymentCycle;
import org.apache.fineract.data.models.loan.TermRange;
import org.apache.fineract.data.models.product.Product;
import org.apache.fineract.ui.base.FineractBaseActivity;
import org.apache.fineract.ui.base.FineractBaseFragment;
import org.apache.fineract.ui.base.Toaster;
import org.apache.fineract.ui.online.loanaccounts.loanapplication.OnNavigationBarListener;
import org.apache.fineract.utils.Utils;
import org.apache.fineract.utils.ValidateIdentifierUtil;
import org.apache.fineract.utils.ValidationUtil;

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

import javax.inject.Inject;

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

/**
 * @author Rajan Maurya
 *         On 17/07/17.
 */
public class LoanDetailsFragment extends FineractBaseFragment implements Step,
        LoanDetailsContract.View, AdapterView.OnItemSelectedListener, TextWatcher {

    public static final String LOG_TAG = LoanDetailsFragment.class.getSimpleName();

    @BindView(R.id.ncv_loan_details)
    NestedScrollView ncvLoanDetails;

    @BindView(R.id.sp_products)
    AppCompatSpinner spProducts;

    @BindView(R.id.til_short_name)
    TextInputLayout tilShortName;

    @BindView(R.id.et_short_name)
    EditText etShortName;

    @BindView(R.id.et_principal_amount)
    EditText etPrincipalAmount;

    @BindView(R.id.til_principal_amount)
    TextInputLayout tilPrincipalAmount;

    @BindView(R.id.et_term)
    EditText etTerm;

    @BindView(R.id.til_term)
    TextInputLayout tilTerm;

    @BindView(R.id.sp_term_unit_type)
    AppCompatSpinner spTermUnitType;

    @BindView(R.id.et_repay)
    EditText etRepay;

    @BindView(R.id.til_repay)
    TextInputLayout tilRepay;

    @BindView(R.id.sp_repay_unit_type)
    AppCompatSpinner spRepayUnitType;

    @BindView(R.id.ll_repay_unit_week)
    LinearLayout llRepayUnitWeek;

    @BindView(R.id.ll_repay_unit_year)
    LinearLayout llRepayUnitYear;

    @BindView(R.id.sp_repay_unit_week)
    AppCompatSpinner spRepayUnitTypeWeek;

    @BindView(R.id.ll_repay_unit_month)
    LinearLayout llRepayUnitMonth;

    @BindView(R.id.rb_repay_on_day)
    RadioButton rbRepayOnDay;

    @BindView(R.id.rb_repay_on_specific_week_day)
    RadioButton rbRepayOnSpecificDay;

    @BindView(R.id.sp_repay_month_day_in_number)
    AppCompatSpinner spRepayMonthDayInNumber;

    @BindView(R.id.sp_repay_time_slots)
    AppCompatSpinner spRepayTimeSlots;

    @BindView(R.id.sp_repay_week_days)
    AppCompatSpinner spRepayWeekDays;

    @BindView(R.id.sp_repay_year_month)
    AppCompatSpinner spRepayYearMonth;

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

    View rootView;

    @Inject
    LoanDetailsPresenter loanDetailsPresenter;

    private OnNavigationBarListener.LoanDetailsData onNavigationBarListener;

    private List<String> products;
    private List<String> repayUnitType;
    private List<String> ternUnitType;
    private List<String> timeSlots;
    private List<String> weeks;
    private List<String> months;
    private List<String> monthsNumber;
    private Product product;

    private ArrayAdapter<String> productsAdapter;
    private ArrayAdapter<String> termUnitTypeAdapter;

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

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((FineractBaseActivity) getActivity()).getActivityComponent().inject(this);
        setRetainInstance(true);
        products = new ArrayList<>();
        ternUnitType = new ArrayList<>();
        repayUnitType = new ArrayList<>(Arrays.asList(
                getActivity().getResources().getStringArray(R.array.repay_unit_type)));
        timeSlots = new ArrayList<>(Arrays.asList(
                getActivity().getResources().getStringArray(R.array.time_slots)));
        weeks = new ArrayList<>(Arrays.asList(
                getActivity().getResources().getStringArray(R.array.week_names)));
        months = new ArrayList<>(Arrays.asList(
                getActivity().getResources().getStringArray(R.array.month_names)));
        monthsNumber = new ArrayList<>(Arrays.asList(
                getActivity().getResources().getStringArray(R.array.repay_on_months)));
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_loan_details, container, false);
        ButterKnife.bind(this, rootView);
        initializeFineractUIErrorHandler(getActivity(), rootView);
        loanDetailsPresenter.attachView(this);

        showUserInterface();

        loanDetailsPresenter.fetchProducts();

        return rootView;
    }

    @OnClick(R.id.btn_try_again)
    void reloadProducts() {
        layoutError.setVisibility(View.GONE);
        ncvLoanDetails.setVisibility(View.GONE);
        loanDetailsPresenter.fetchProducts();
    }

    @Override
    public VerificationError verifyStep() {
        if (!validateShortName() || !validateTerm() || !validateRepay()
                || !validatePrincipalAmount()) {
            return new VerificationError(null);
        } else {
            PaymentCycle paymentCycle = new PaymentCycle();
            paymentCycle.setPeriod(Integer.parseInt(etRepay.getText().toString().trim()));
            paymentCycle.setTemporalUnit(
                    spRepayUnitType.getSelectedItem().toString().toUpperCase());
            switch (spRepayUnitType.getSelectedItemPosition()) {
                case 0:
                    paymentCycle.setAlignmentDay(spRepayUnitTypeWeek.getSelectedItemPosition());
                    break;
                case 1:
                    if (rbRepayOnDay.isChecked()) {
                        paymentCycle.setAlignmentDay(
                                spRepayMonthDayInNumber.getSelectedItemPosition());
                    } else if (rbRepayOnSpecificDay.isChecked()) {
                        paymentCycle.setAlignmentDay(spRepayWeekDays.getSelectedItemPosition());
                        paymentCycle.setAlignmentMonth(null);
                        paymentCycle.setAlignmentWeek(spRepayTimeSlots.getSelectedItemPosition());
                    }
                    break;
                case 2:
                    if (rbRepayOnDay.isChecked()) {
                        paymentCycle.setAlignmentDay(
                                spRepayMonthDayInNumber.getSelectedItemPosition());
                    } else if (rbRepayOnSpecificDay.isChecked()) {
                        paymentCycle.setAlignmentDay(spRepayWeekDays.getSelectedItemPosition());
                        paymentCycle.setAlignmentMonth(null);
                        paymentCycle.setAlignmentWeek(spRepayTimeSlots.getSelectedItemPosition());
                    }
                    paymentCycle.setAlignmentMonth(spRepayYearMonth.getSelectedItemPosition());
                    break;
            }
            onNavigationBarListener.setLoanDetails(LoanAccount.State.CREATED,
                    etShortName.getText().toString().trim(), product.getIdentifier(),
                    Double.parseDouble(etPrincipalAmount.getText().toString().trim()),
                    paymentCycle, new TermRange(product.getTermRange().getTemporalUnit(),
                            Double.parseDouble(etTerm.getText().toString().trim()))
                    , spProducts.getSelectedItem().toString());


            return null;
        }
    }

    @Override
    public void onSelected() {
        // when every condition will fine in verifyStep();
    }

    @Override
    public void onError(@NonNull VerificationError error) {
        // Make changes on UI, If error occurred
    }

    @OnClick(R.id.rb_repay_on_day)
    void repayOnDay() {
        spRepayMonthDayInNumber.setEnabled(true);
        spRepayTimeSlots.setEnabled(false);
        spRepayWeekDays.setEnabled(false);
    }

    @OnClick(R.id.rb_repay_on_specific_week_day)
    void repayOnSpecificDay() {
        spRepayMonthDayInNumber.setEnabled(false);
        spRepayTimeSlots.setEnabled(true);
        spRepayWeekDays.setEnabled(true);
    }

    @Override
    public void showUserInterface() {

        productsAdapter = new ArrayAdapter<>(getActivity(),
                android.R.layout.simple_spinner_item, products);
        productsAdapter.setDropDownViewResource(
                android.R.layout.simple_spinner_dropdown_item);
        spProducts.setAdapter(productsAdapter);
        spProducts.setOnItemSelectedListener(this);

        ArrayAdapter<String> repayUnitAdapter = new ArrayAdapter<>(getActivity(),
                android.R.layout.simple_spinner_item, repayUnitType);
        repayUnitAdapter.setDropDownViewResource(
                android.R.layout.simple_spinner_dropdown_item);
        spRepayUnitType.setAdapter(repayUnitAdapter);
        spRepayUnitType.setOnItemSelectedListener(this);

        ArrayAdapter<String> repayUnitTypeWeekAdapter = new ArrayAdapter<>(getActivity(),
                android.R.layout.simple_spinner_item, weeks);
        repayUnitTypeWeekAdapter.setDropDownViewResource(
                android.R.layout.simple_spinner_dropdown_item);
        spRepayUnitTypeWeek.setAdapter(repayUnitTypeWeekAdapter);
        spRepayUnitTypeWeek.setOnItemSelectedListener(this);

        ArrayAdapter<String> repayUnitTypeMonthTimeSlotsAdapter = new ArrayAdapter<>(getActivity(),
                android.R.layout.simple_gallery_item, timeSlots);
        repayUnitTypeMonthTimeSlotsAdapter.setDropDownViewResource(
                android.R.layout.simple_spinner_dropdown_item);
        spRepayTimeSlots.setAdapter(repayUnitTypeMonthTimeSlotsAdapter);
        spRepayTimeSlots.setOnItemSelectedListener(this);

        ArrayAdapter<String> repayUnitTypeMonthWeeksAdapter = new ArrayAdapter<>(getActivity(),
                android.R.layout.simple_gallery_item, weeks);
        repayUnitTypeMonthWeeksAdapter.setDropDownViewResource(
                android.R.layout.simple_spinner_dropdown_item);
        spRepayWeekDays.setAdapter(repayUnitTypeMonthWeeksAdapter);
        spRepayWeekDays.setOnItemSelectedListener(this);

        ArrayAdapter<String> repayUnitTypeYearMonthsAdapter = new ArrayAdapter<>(getActivity(),
                android.R.layout.simple_spinner_item, months);
        repayUnitTypeYearMonthsAdapter.setDropDownViewResource(
                android.R.layout.simple_spinner_dropdown_item);
        spRepayYearMonth.setAdapter(repayUnitTypeYearMonthsAdapter);
        spRepayYearMonth.setOnItemSelectedListener(this);

        ArrayAdapter<String> repayMonthDayInNumberAdapter = new ArrayAdapter<>(getActivity(),
                android.R.layout.simple_gallery_item, monthsNumber);
        repayMonthDayInNumberAdapter.setDropDownViewResource(
                android.R.layout.simple_spinner_dropdown_item);
        spRepayMonthDayInNumber.setAdapter(repayMonthDayInNumberAdapter);
        spRepayMonthDayInNumber.setOnItemSelectedListener(this);

        termUnitTypeAdapter = new ArrayAdapter<>(getActivity(),
                android.R.layout.simple_gallery_item, ternUnitType);
        termUnitTypeAdapter.setDropDownViewResource(
                android.R.layout.simple_spinner_dropdown_item);
        spTermUnitType.setAdapter(termUnitTypeAdapter);
        spTermUnitType.setOnItemSelectedListener(this);

        etPrincipalAmount.addTextChangedListener(this);
        etTerm.addTextChangedListener(this);
        etRepay.addTextChangedListener(this);
        etShortName.addTextChangedListener(this);

        spRepayMonthDayInNumber.setEnabled(true);
        spRepayTimeSlots.setEnabled(false);
        spRepayWeekDays.setEnabled(false);
        rbRepayOnDay.setChecked(true);
    }

    @Override
    public void showProducts(List<String> products) {
        ncvLoanDetails.setVisibility(View.VISIBLE);
        layoutError.setVisibility(View.GONE);
        this.products.addAll(products);
        productsAdapter.notifyDataSetChanged();
    }

    @Override
    public void setComponentsValidations(Product product) {
        this.product = product;
        etPrincipalAmount.setText(String.valueOf(product.getBalanceRange().getMinimum()));
        ternUnitType.clear();
        ternUnitType.addAll(loanDetailsPresenter.getCurrentTermUnitType(
                repayUnitType, product.getTermRange().getTemporalUnit()));
        termUnitTypeAdapter.notifyDataSetChanged();
        spTermUnitType.setEnabled(false);
        etTerm.setText("1");
        etRepay.setText("1");
    }

    @Override
    public void showEmptyProducts() {
        ncvLoanDetails.setVisibility(View.VISIBLE);
        layoutError.setVisibility(View.GONE);
        Toaster.show(rootView, getString(R.string.empty_create_loan_products), Toaster.INDEFINITE);
    }

    @Override
    public void showProgressbar() {
        showMifosProgressBar();
    }

    @Override
    public void hideProgressbar() {
        hideMifosProgressBar();
    }

    @Override
    public void showNoInternetConnection() {
        ncvLoanDetails.setVisibility(View.GONE);
        layoutError.setVisibility(View.VISIBLE);
        showFineractNoInternetUI();
    }

    @Override
    public void showError(String message) {
        ncvLoanDetails.setVisibility(View.GONE);
        layoutError.setVisibility(View.VISIBLE);
        showFineractErrorUI(getString(R.string.products));
    }

    @Override
    public boolean validateShortName() {
        return ValidateIdentifierUtil.isValid(getActivity(),
                etShortName.getText().toString().trim(), tilShortName);
    }

    @Override
    public boolean validateTerm() {
        try {
            Double minimum = 1.0;
            Double maximum = product.getTermRange().getMaximum();
            Double value = Double.parseDouble(etTerm.getText().toString());

            if (etTerm.getText().toString().equals("")) {
                ValidationUtil.showTextInputLayoutError(tilTerm, getString(R.string.required));
                return false;
            } else if (!(minimum <= value)) {
                ValidationUtil.showTextInputLayoutError(tilTerm,
                        getString(R.string.value_must_greater_or_equal_to,
                                Utils.getPrecision(minimum)));
                return false;
            } else if (!(value <= maximum)) {
                ValidationUtil.showTextInputLayoutError(tilTerm,
                        getString(R.string.value_must_less_than_or_equal_to,
                                Utils.getPrecision(maximum)));
                return false;
            }
        } catch (NumberFormatException e) {
            ValidationUtil.showTextInputLayoutError(tilTerm,
                    getString(R.string.required));
            return false;
        }
        ValidationUtil.hideTextInputLayoutError(tilTerm);
        return true;
    }

    @Override
    public boolean validatePrincipalAmount() {
        try {
            Double minimum = product.getBalanceRange().getMinimum();
            Double maximum = product.getBalanceRange().getMaximum();
            Double value = Double.parseDouble(etPrincipalAmount.getText().toString());

            if (etPrincipalAmount.getText().toString().equals("")) {
                ValidationUtil.isEmpty(getActivity(),
                        etPrincipalAmount.getText().toString().trim(), tilPrincipalAmount);
                return false;
            } else if (!(minimum <= value)) {
                ValidationUtil.showTextInputLayoutError(tilPrincipalAmount,
                        getString(R.string.value_must_greater_or_equal_to,
                                Utils.getPrecision(minimum)));
                return false;
            } else if (!(value <= maximum)) {
                ValidationUtil.showTextInputLayoutError(tilPrincipalAmount,
                        getString(R.string.value_must_less_than_or_equal_to,
                                Utils.getPrecision(maximum)));
                return false;
            }
        } catch (NumberFormatException e) {
            ValidationUtil.showTextInputLayoutError(tilPrincipalAmount,
                    getString(R.string.required));
            return false;
        }
        ValidationUtil.hideTextInputLayoutError(tilPrincipalAmount);
        return true;
    }

    @Override
    public boolean validateRepay() {
        return ValidationUtil.isEmpty(getActivity(),
                etRepay.getText().toString().trim(), tilRepay);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        switch (parent.getId()) {
            case R.id.sp_products:
                loanDetailsPresenter.setProductPositionAndValidateViews(position);
                break;
            case R.id.sp_repay_unit_type:
                switch (position) {
                    case 0:
                        llRepayUnitWeek.setVisibility(View.VISIBLE);
                        llRepayUnitMonth.setVisibility(View.GONE);
                        llRepayUnitYear.setVisibility(View.GONE);
                        break;
                    case 1:
                        llRepayUnitWeek.setVisibility(View.GONE);
                        llRepayUnitMonth.setVisibility(View.VISIBLE);
                        llRepayUnitYear.setVisibility(View.GONE);
                        break;
                    case 2:
                        llRepayUnitWeek.setVisibility(View.GONE);
                        llRepayUnitMonth.setVisibility(View.VISIBLE);
                        llRepayUnitYear.setVisibility(View.VISIBLE);
                        break;
                }
                break;
        }

    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }

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

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Activity activity = context instanceof Activity ? (Activity) context : null;
        try {
            onNavigationBarListener = (OnNavigationBarListener.LoanDetailsData) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnNavigationBarListener");
        }
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        if (etPrincipalAmount.getText().hashCode() == s.hashCode()) {
            validatePrincipalAmount();
        } else if (etTerm.getText().hashCode() == s.hashCode()) {
            validateTerm();
        } else if (etRepay.getText().hashCode() == s.hashCode()) {
            validateRepay();
        } else if (etShortName.getText().hashCode() == s.hashCode()) {
            validateShortName();
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putStringArrayList("products", (ArrayList<String>) products);
        super.onSaveInstanceState(outState);
    }
}
