package ch.pizzalemon.android.activity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.afollestad.materialdialogs.MaterialDialog;

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

import butterknife.BindString;
import butterknife.BindView;
import butterknife.BindViews;
import butterknife.ButterKnife;
import butterknife.OnClick;
import ch.pizzalemon.android.R;
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.SharedPrefsHelper;
import ch.pizzalemon.android.helper.ViewHelper;
import ch.pizzalemon.android.model.AddressModel;
import ch.pizzalemon.android.model.CityModel;
import ch.pizzalemon.android.model.CountryModel;
import ch.pizzalemon.android.model.CustomerTokenModel;
import ch.pizzalemon.android.model.UserModel;
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 RegisterActivity extends BaseActivity {

    @BindViews({ R.id.firstnamePizzalinkEditText, R.id.lasstnamePizzalinkEditText,
            R.id.telephonePizzalinkEditText, R.id.emailPizzalinkEditText,
            R.id.passwordPizzalinkEditText, R.id.passwordAgainPizzalinkEditText,
            R.id.address1PizzalinkEditText, R.id.postcodePizzalinkEditText})
    List<AppEditText> appEditTextList;

    @BindView(R.id.cityPizzalinkDropdown)
    AppDropdownView cityPizzalinkDropdown;
    @BindView(R.id.countryPizzalinkDropdown)
    AppDropdownView countryPizzalinkDropdown;
    @BindView(R.id.zonePizzalinkDropdown)
    AppDropdownView zonePizzalinkDropdown;
    @BindView(R.id.registerButton) Button registerButton;

    @BindString(R.string.alert_fill_all_fields) String fillAllFieldsText;
    @BindString(R.string.alert_invalid_email) String validEmailText;
    @BindString(R.string.alert_invalid_post_code) String invalidPostcodeText;
    @BindString(R.string.alert_passwords_not_matched) String passwordsNotMatchedText;
    @BindString(R.string.alert_select_country_first) String selectCountryFirstText;

    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_register);
        ButterKnife.bind(this);
        getCityList();
        //getCountryList();
        //setTestFields();
    }

    @OnClick({R.id.cityPizzalinkDropdown, R.id.countryPizzalinkDropdown,
            R.id.zonePizzalinkDropdown, R.id.registerButton})
    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.registerButton:
                ViewHelper.hideKeyboard();
                if(checkFields())
                    registerUser();
                break;
        }
    }

    private boolean checkFields(){

        for(AppEditText appEditText : appEditTextList){
            if(appEditText.isEmpty()){
                DialogHelper.showAlertDialog(this, fillAllFieldsText);
                return false;
            }
        }

        if(!appEditTextList.get(3).isEmail()){
            DialogHelper.showAlertDialog(this, validEmailText);
            return false;
        }

        if(!appEditTextList
                .get(4)
                .getText()
                .toLowerCase()
                .equals(
                        appEditTextList
                                .get(5)
                                .getText()
                                .toLowerCase())){
            DialogHelper.showAlertDialog(this, passwordsNotMatchedText);
            return false;
        }

        if(appEditTextList.get(7).getText().length() != 4){
            DialogHelper.showAlertDialog(this, invalidPostcodeText);
            return false;
        }

        /*
        if(selectedCityModel == null ||
                selectedCountryModel == null ||
                selectedZoneModel == null){
            DialogHelper.showAlertDialog(this, fillAllFieldsText);
            */

        if(selectedCityModel == null){
            DialogHelper.showAlertDialog(this, fillAllFieldsText);
            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 registerUser(){
        DialogHelper.showLoadingDialog();
        Call<ResponseObject<UserModel>> call = ApiService.apiInterface.register(
                SessionHelper.getSelectedStore().getStoreName(),
                getRegisterParams());
        call.enqueue(new Callback<ResponseObject<UserModel>>() {
            @Override
            public void onResponse(Call<ResponseObject<UserModel>> call, Response<ResponseObject<UserModel>> response) {
                DialogHelper.hideLoadingDialog();
                if(response.isSuccessful() &&
                        response.body().getData() != null &&
                        response.body().isSuccess()){
                    response.body().getData().checkNull();
                    SharedPrefsHelper.saveUser(response.body().getData());
                    CustomerTokenModel customerTokenModel = response.body().getData().getToken();
                    customerTokenModel.setStoreOfToken(SessionHelper.getSelectedStore());
                    SharedPrefsHelper.saveCustomerToken(customerTokenModel);
                    SharedPrefsHelper.setCustomerLoggedIn(true);
                    SessionHelper.saveUserMainAddress(
                            new AddressModel(appEditTextList.get(6).getText() + ", " + appEditTextList.get(7).getText() + ", " + selectedCityModel.getCity())
                    );
                    startActivity(new Intent(RegisterActivity.this, MainActivity.class));
                    finishAffinity();
                }
                else
                    ApiErrorUtils.parseError(response);
            }

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

    private HashMap<String, Object> getRegisterParams(){
        HashMap<String, Object> params = new HashMap<>();
        params.put("firstname", appEditTextList.get(0).getText());
        params.put("lastname", appEditTextList.get(1).getText());
        params.put("telephone", appEditTextList.get(2).getText());
        params.put("email", appEditTextList.get(3).getText());
        params.put("password", appEditTextList.get(4).getText());
        params.put("password1", appEditTextList.get(5).getText());
        params.put("address_1", appEditTextList.get(6).getText());
        params.put("address_2", "");
        params.put("city", selectedCityModel.getCity());
        params.put("postcode", appEditTextList.get(7).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 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 setTestFields(){
        appEditTextList.get(0).getEditText().setText("testname");
        appEditTextList.get(1).getEditText().setText("testsurname");
        appEditTextList.get(2).getEditText().setText("1234567892");
        appEditTextList.get(3).getEditText().setText("test5@test.com");
        appEditTextList.get(4).getEditText().setText("test");
        appEditTextList.get(5).getEditText().setText("test");
        appEditTextList.get(6).getEditText().setText("test address 1");
        appEditTextList.get(7).getEditText().setText("test postcode");
    }

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

    }

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

}
