package ch.pizzalemon.android.activity;

import android.content.Intent;
import androidx.annotation.NonNull;
import android.os.Bundle;
import android.view.View;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantLock;

import butterknife.BindString;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import ch.pizzalemon.android.R;
import ch.pizzalemon.android.api.ApiEndPoints;
import ch.pizzalemon.android.api.ApiErrorUtils;
import ch.pizzalemon.android.api.ApiService;
import ch.pizzalemon.android.api.ResponseArray;
import ch.pizzalemon.android.api.ResponseObject;
import ch.pizzalemon.android.helper.DialogHelper;
import ch.pizzalemon.android.helper.SessionHelper;
import ch.pizzalemon.android.helper.ViewHelper;
import ch.pizzalemon.android.model.AddNewAddressResponseModel;
import ch.pizzalemon.android.model.CityModel;
import ch.pizzalemon.android.model.CountryModel;
import ch.pizzalemon.android.model.ZoneModel;
import ch.pizzalemon.android.view.AppDropdownView;
import ch.pizzalemon.android.view.AppEditText;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class AddAddressActivity extends BaseActivity {

    @BindView(R.id.address1PizzalinkEditText) AppEditText address1AppEditText;
    @BindView(R.id.cityPizzalinkDropdown) AppDropdownView cityPizzalinkDropdown;
    @BindView(R.id.postcodePizzalinkEditText) AppEditText postcodeAppEditText;
    @BindView(R.id.countryPizzalinkDropdown) AppDropdownView countryPizzalinkDropdown;
    @BindView(R.id.zonePizzalinkDropdown) AppDropdownView zonePizzalinkDropdown;

    @BindString(R.string.alert_fill_all_fields) String fillAllFieldsText;
    @BindString(R.string.alert_select_country_first) String selectCountryFirstText;
    @BindString(R.string.new_address_added) String newAddressAddedText;
    @BindString(R.string.alert_invalid_post_code) String invalidPostcodeText;

    private ArrayList<CityModel> cityList = new ArrayList<>();
    private ArrayList<CountryModel> countryList = new ArrayList<>();
    private ArrayList<ZoneModel> zoneList = new ArrayList<>();
    private CityModel selectedCityModel;
    private CountryModel selectedCountryModel;
    private ZoneModel selectedZoneModel;

    private int activeRequestCount = 0;
    private ReentrantLock lock = new ReentrantLock();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_address);
        ButterKnife.bind(this);
        getCityList();
        //getCountryList();
    }

    @OnClick({R.id.cityPizzalinkDropdown, R.id.countryPizzalinkDropdown,
            R.id.zonePizzalinkDropdown, R.id.addNewAddressButton})
    protected void onClick(View view){
        switch (view.getId()){
            case R.id.cityPizzalinkDropdown:
                showCityDialog();
                break;
            case R.id.countryPizzalinkDropdown:
                showCountryDialog();
                break;
            case R.id.zonePizzalinkDropdown:
                if(selectedCountryModel != null){
                    getZoneList();
                }
                else {
                    DialogHelper.showAlertDialog(BaseActivity.currentActivity, selectCountryFirstText);
                }
                break;
            case R.id.addNewAddressButton:
                ViewHelper.hideKeyboard();
                if(checkFields())
                    addNewAddress();
                break;
        }
    }

    private boolean checkFields(){

        /*
        if(address1PizzalinkEditText.isEmail() ||
                selectedCityModel == null ||
                selectedCountryModel == null ||
                selectedZoneModel == null){
            DialogHelper.showAlertDialog(this, fillAllFieldsText);
            return false;
        }
        */

        if(address1AppEditText.isEmpty() ||
                selectedCityModel == null ||
                postcodeAppEditText.isEmpty()){
            DialogHelper.showAlertDialog(this, fillAllFieldsText);
            return false;
        }

        if(postcodeAppEditText.getText().length() != 4){
            DialogHelper.showAlertDialog(this, invalidPostcodeText);
            return false;
        }
        return true;
    }

    private void getCityList(){

        if(activeRequestCount == 0)
            DialogHelper.showLoadingDialog();

        Call<ResponseArray<CityModel>> call = ApiService.apiInterface.getCityList(SessionHelper.getSelectedStore().getStoreName());
        call.enqueue(new Callback<ResponseArray<CityModel>>() {
            @Override
            public void onResponse(Call<ResponseArray<CityModel>> call, Response<ResponseArray<CityModel>> response) {

                decreaseActiveRequestCount();

                if(activeRequestCount == 0)
                    DialogHelper.hideLoadingDialog();

                if(response.isSuccessful() &&
                        response.body().getData() != null &&
                        response.body().isSuccess()){
                    fillAndNotifyCityList(response.body().getData());
                }
                else if(activeRequestCount == 0){
                    ApiErrorUtils.parseError(response);
                }
            }

            @Override
            public void onFailure(Call<ResponseArray<CityModel>> call, Throwable t) {
                decreaseActiveRequestCount();
                if(activeRequestCount == 0){
                    DialogHelper.hideLoadingDialog();
                    DialogHelper.showFailedDialog();
                }
            }
        });


        increaseActiveRequestCount();
    }

    private void getCountryList(){

        if(activeRequestCount == 0)
            DialogHelper.showLoadingDialog();

        increaseActiveRequestCount();

        Call<ResponseArray<CountryModel>> call = ApiService.apiInterface.getCountryList(SessionHelper.getSelectedStore().getStoreName());
        call.enqueue(new Callback<ResponseArray<CountryModel>>() {
            @Override
            public void onResponse(Call<ResponseArray<CountryModel>> call, Response<ResponseArray<CountryModel>> response) {

                decreaseActiveRequestCount();

                if(activeRequestCount == 0)
                    DialogHelper.hideLoadingDialog();

                if(response.isSuccessful() &&
                        response.body().getData() != null &&
                        response.body().isSuccess()){
                    fillAndNotifyCountryList(response.body().getData());
                }
                else if(activeRequestCount == 0){
                    ApiErrorUtils.parseError(response);
                }
            }

            @Override
            public void onFailure(Call<ResponseArray<CountryModel>> call, Throwable t) {
                decreaseActiveRequestCount();
                if(activeRequestCount == 0){
                    DialogHelper.hideLoadingDialog();
                    DialogHelper.showFailedDialog();
                }
            }
        });
    }

    private void getZoneList(){
        DialogHelper.showLoadingDialog();
        Call<ResponseArray<ZoneModel>> call = ApiService.apiInterface.getZoneList(
                SessionHelper.getSelectedStore().getStoreName(),
                selectedCountryModel.getId());
        call.enqueue(new Callback<ResponseArray<ZoneModel>>() {
            @Override
            public void onResponse(Call<ResponseArray<ZoneModel>> call, Response<ResponseArray<ZoneModel>> response) {
                DialogHelper.hideLoadingDialog();
                if(response.isSuccessful() &&
                        response.body().getData() != null &&
                        response.body().isSuccess()){
                    fillAndShowZoneList(response.body().getData());
                }
                else {
                    ApiErrorUtils.parseError(response);
                }
            }

            @Override
            public void onFailure(Call<ResponseArray<ZoneModel>> call, Throwable t) {
                DialogHelper.hideLoadingDialog();
                DialogHelper.showFailedDialog();
            }
        });
    }

    private void fillAndNotifyCityList(ArrayList<CityModel> cities){
        CityModel.checkNull(cities);
        cityList.clear();
        cityList.addAll(cities);
    }

    private void fillAndNotifyCountryList(ArrayList<CountryModel> countries){
        CountryModel.checkNull(countries);
        countryList.clear();
        countryList.addAll(countries);
    }

    private void fillAndShowZoneList(ArrayList<ZoneModel> zones){
        ZoneModel.checkNull(zones);
        zoneList.clear();
        zoneList.addAll(zones);
        showZoneDialog();
    }

    private void showCityDialog(){

        final ArrayList<String> zoneNameList = new ArrayList<>();
        for(CityModel zone : cityList){
            zoneNameList.add(zone.getCity());
        }

        DialogHelper.showListDialog(zoneNameList, new MaterialDialog.ListCallback() {
            @Override
            public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) {
                selectedCityModel = cityList.get(position);
                cityPizzalinkDropdown.setText(selectedCityModel.getCity());
            }
        });
    }

    private void showCountryDialog(){

        final ArrayList<String> countryNameList = new ArrayList<>();
        for(CountryModel country : countryList){
            countryNameList.add(country.getName());
        }

        DialogHelper.showListDialog(countryNameList, new MaterialDialog.ListCallback() {
            @Override
            public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) {
                selectedCountryModel = countryList.get(position);
                countryPizzalinkDropdown.setText(selectedCountryModel.getName());
            }
        });
    }

    private void showZoneDialog(){

        final ArrayList<String> zoneNameList = new ArrayList<>();
        for(ZoneModel zone : zoneList){
            zoneNameList.add(zone.getName());
        }

        DialogHelper.showListDialog(zoneNameList, new MaterialDialog.ListCallback() {
            @Override
            public void onSelection(MaterialDialog dialog, View itemView, int position, CharSequence text) {
                selectedZoneModel = zoneList.get(position);
                zonePizzalinkDropdown.setText(selectedZoneModel.getName());
            }
        });
    }

    private void addNewAddress(){
        DialogHelper.showLoadingDialog();
        Call<ResponseObject<AddNewAddressResponseModel>> call = ApiService.apiInterface.addNewAddress(
                "/" + SessionHelper.getSelectedStore().getStoreName() + ApiEndPoints.API_ADD_NEW_ADDRESS + SessionHelper.getCustomerToken().getToken(),
                getAddNewAddressRequestParams());
        call.enqueue(new Callback<ResponseObject<AddNewAddressResponseModel>>() {
            @Override
            public void onResponse(Call<ResponseObject<AddNewAddressResponseModel>> call, final Response<ResponseObject<AddNewAddressResponseModel>> response) {
                DialogHelper.hideLoadingDialog();
                if(response.isSuccessful() &&
                        response.body().getData() != null &&
                        response.body().isSuccess()){
                    DialogHelper.showOneButtonDialogWithCallback(newAddressAddedText,
                            new MaterialDialog.SingleButtonCallback() {
                                @Override
                                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                                    dialog.dismiss();
                                    Intent newAddressIntent = new Intent();
                                    newAddressIntent.putExtra("newAddressId",
                                            response.body().getData().getAddressId());
                                    setResult(RESULT_OK, newAddressIntent);
                                    finish();
                                }
                            });
                }
                else {
                    ApiErrorUtils.parseError(response);
                }
            }

            @Override
            public void onFailure(Call<ResponseObject<AddNewAddressResponseModel>> call, Throwable t) {
                DialogHelper.hideLoadingDialog();
                DialogHelper.showFailedDialog();
            }
        });
    }

    private HashMap<String, Object> getAddNewAddressRequestParams(){
        HashMap<String, Object> params = new HashMap<>();
        params.put("address_1", address1AppEditText.getText());
        params.put("address_2", "");
        params.put("city", selectedCityModel.getCity());
        //params.put("postcode", selectedCityModel.getPostcode());
        params.put("postcode", postcodeAppEditText.getText());
        //params.put("country_id", selectedCountryModel.getId());
        //params.put("zone_id", selectedZoneModel.getZoneId());
        params.put("country_id", "1");
        params.put("zone_id", "1");
        return params;
    }

    private synchronized void increaseActiveRequestCount(){
        lock.lock();
        try {
            activeRequestCount++;
        }finally {
            lock.unlock();
        }
    }

    private synchronized void decreaseActiveRequestCount(){
        lock.lock();
        try {
            activeRequestCount--;
        }finally {
            lock.unlock();
        }
    }

}
