package com.example.jens.myapplication.booking;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.example.jens.myapplication.R;
import com.example.jens.myapplication.domain.Person;
import com.example.jens.myapplication.domain.User;
import com.example.jens.myapplication.domain.binding.PersonValidatorBinding;
import com.example.jens.myapplication.domain.binding.ValidatorBinding;
import com.example.jens.myapplication.domain.validator.PersonValidator;
import com.example.jens.myapplication.sam.JoetzApplication;
import com.example.jens.myapplication.sam.MyFragment;
import com.example.jens.myapplication.sam.MySaveableFragment;
import com.example.jens.myapplication.util.ActivityUtils;
import com.example.jens.myapplication.util.BindingUtils;
import com.example.jens.myapplication.view.MyLinearLayout;

import org.joda.time.DateTime;

import java.util.LinkedList;
import java.util.List;

/**
 * A simple {@link android.app.Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link BookingContactFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link BookingContactFragment#newInstance} factory method to
 * create an instance of this fragment.
 *
 */
public class BookingContactFragment extends MyFragment implements MySaveableFragment {
    public static final String ARG_PERSON = "person";
    public static final String ARG_CHECKED = "checked";

    private OnFragmentInteractionListener mListener;

    private MyLinearLayout llyRootLinearLayout;

    private boolean mInitChecked = false;
    private CheckBox mChkIsContact;

    private EditText mTxtRijksRegisterNummer;
    private EditText mTxtFirstName;
    private EditText mTxtLastName;
    private EditText mTxtDob;
    private EditText mTxtStreet;
    private EditText mTxtHouseNumber;
    private EditText mTxtBus;
    private EditText mTxtCity;
    private EditText mTxtPostalCode;
    private EditText mTxtEmail;
    private EditText mTxtTelephone;

    private Button mBtnNext;
    private Button mBtnClose;

    private ImageView mImgInfoContactpersoon;

    private Person mPerson;
    private PersonValidator personValidator;
    private List<ValidatorBinding> mBindings;
    private ValidatorBinding mDobBinding;

    public static BookingContactFragment newInstance(Bundle bundle) {
        BookingContactFragment fragment = new BookingContactFragment();
        /*if(person != null){
            Bundle b = new Bundle();
            b.putParcelable(ARG_PERSON, person);
            fragment.setArguments(b);
        }*/
        if(bundle != null){
            fragment.setArguments(bundle);
        }
        return fragment;
    }
    public BookingContactFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle bundle = null;
        if(getArguments() != null){
            //mPerson = getArguments().getParcelable(ARG_PERSON);
            bundle = getArguments();
            mPerson = bundle.getParcelable(ARG_PERSON);
            mInitChecked = bundle.getBoolean(ARG_CHECKED);
        }else{
            mPerson = new Person();
            mInitChecked = false;
        }
//        if(savedInstanceState != null){
//            mPerson = savedInstanceState.getParcelable(ARG_PERSON);
//            mInitChecked = savedInstanceState.getBoolean(ARG_CHECKED);
//            bundle = savedInstanceState.getBundle(ARG_BUNDLE);
//        }
    }

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

        llyRootLinearLayout = (MyLinearLayout) rootView.findViewById(R.id.llyRootLinearLayout);
        llyRootLinearLayout.setOnDispatchTouchEventListener(new MyLinearLayout.OnDispatchTouchEventListener() {
            @Override
            public void onDispatchTouchEvent(MotionEvent e) {
                clearFocus();
            }
        });

        mChkIsContact = (CheckBox) rootView.findViewById(R.id.chkIsContact);
        mChkIsContact.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener(){
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                isContactCheckedChanged(isChecked);
            }
        });

        mImgInfoContactpersoon = (ImageView) rootView.findViewById(R.id.imgInfoContactpersoon);
        mImgInfoContactpersoon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openInfoContactpersoon();
            }
        });

        mTxtRijksRegisterNummer = (EditText) rootView.findViewById(R.id.txtRijksRegisterNummer);
        mTxtFirstName = (EditText) rootView.findViewById(R.id.txtFirstName);
        mTxtLastName = (EditText) rootView.findViewById(R.id.txtLastName);
        mTxtDob = (EditText) rootView.findViewById(R.id.txtDateOfBirth);
        mTxtStreet= (EditText) rootView.findViewById(R.id.txtStreet);
        mTxtHouseNumber = (EditText) rootView.findViewById(R.id.txtHouseNumber);
        mTxtBus = (EditText) rootView.findViewById(R.id.txtBus);
        mTxtCity = (EditText) rootView.findViewById(R.id.txtCity);
        mTxtPostalCode = (EditText) rootView.findViewById(R.id.txtPostalCode);
        mTxtEmail = (EditText) rootView.findViewById(R.id.txtEmail);
        mTxtTelephone = (EditText) rootView.findViewById(R.id.txtTelephone);

        mBtnClose = (Button) rootView.findViewById(R.id.btnCancel);
        mBtnNext = (Button) rootView.findViewById(R.id.btnNext);

        mBtnClose.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                cancelBooking();
            }
        });

        mBtnNext.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                goNext();
            }
        });

        mBindings = new LinkedList<ValidatorBinding>();
        personValidator = new PersonValidator(mPerson);
        initBindings();

        //validateAll();

        mChkIsContact.setChecked(mInitChecked);

        return rootView;
    }

    private void isContactCheckedChanged(boolean isChecked) {
        User user = JoetzApplication.getContext().getLoginManager().getUser();
        Person uPerson = user.getPerson();
        BindingUtils.fillViewOnCheck(mTxtRijksRegisterNummer, uPerson.getRijksRegisterNummer(), isChecked);
        BindingUtils.fillViewOnCheck(mTxtFirstName, uPerson.getFirstName(), isChecked);
        BindingUtils.fillViewOnCheck(mTxtLastName, uPerson.getLastName(), isChecked);
        BindingUtils.fillViewOnCheck(mTxtStreet, uPerson.getStreet(), isChecked);
        if(uPerson.getHouseNumber() > 0){
            BindingUtils.fillViewOnCheck(mTxtHouseNumber, uPerson.getHouseNumber(), isChecked);
        }
        BindingUtils.fillViewOnCheck(mTxtBus, uPerson.getBus(), isChecked);
        BindingUtils.fillViewOnCheck(mTxtCity, uPerson.getCity(), isChecked);
        if(uPerson.getPostalCode() > 0){
            BindingUtils.fillViewOnCheck(mTxtPostalCode, uPerson.getPostalCode(), isChecked);
        }
        BindingUtils.fillViewOnCheck(mTxtEmail, uPerson.getEmail(), isChecked);
        BindingUtils.fillViewOnCheck(mTxtTelephone, uPerson.getPhone(), isChecked);

        //DOB binding does not fill Person
        if(isChecked){
            if(uPerson.getDateOfBirth() != null){
                mPerson.setDateOfBirth(uPerson.getDateOfBirth());
                mDobBinding.fillValue();
                mTxtDob.setEnabled(false);
            }
        }else{
            mPerson.setDateOfBirth(null);
            mDobBinding.getView().setText("");
            mTxtDob.setEnabled(true);
        }

        if(isChecked){
            validateAll();
            removeErrorsOnEnabledFields();
        }
    }

    private void removeErrorsOnEnabledFields(){
        for(ValidatorBinding binding : mBindings){
            EditText v = binding.getView();
            if(v.isEnabled()){
                v.setError(null);
            }
        }
    }

    private void openInfoContactpersoon(){
        new AlertDialog.Builder(getActivity())
                .setMessage(R.string.info_contactpersoon)
                .setNeutralButton(R.string.ok, null)
                .create().show();
    }

    private void chooseDob(){
        ActivityUtils.chooseDateOfBirth(getActivity(), mPerson, new ActivityUtils.OnDateChosenListener() {
            @Override
            public void onDateChosen(int year, int monthOfYear, int dayOfMonth) {
                mPerson.setDateOfBirth(new DateTime(year, monthOfYear, dayOfMonth, 0, 0));
                mDobBinding.fillValue();
                mDobBinding.validate();
                mTxtDob.requestFocus();
            }
        });
    }

    private void goNext(){
        validateAll();
        boolean error = false;
        for(ValidatorBinding b : mBindings){
            if(b.getView().getError() != null){
                error = true;
                break;
            }
        }
        if(error){
            Toast.makeText(getActivity(), R.string.error_errors_exist, Toast.LENGTH_SHORT).show();
        }else{
            mListener.onFinishContactPerson();
        }
    }

    private void cancelBooking(){
        mListener.cancelBooking();
    }

    private void clearFocus(){
        View view = getActivity().getCurrentFocus();
        if(view == null || view == llyRootLinearLayout){
            return;
        }
        llyRootLinearLayout.requestFocus();
    }

    private void initBindings(){
        mBindings.add(new PersonValidatorBinding(personValidator,
                mTxtRijksRegisterNummer, PersonValidatorBinding.FIELD_RIJKSREGISTERNUMMER,
                mTxtRijksRegisterNummer.getHint().toString()));

        mBindings.add(new PersonValidatorBinding(personValidator,
                mTxtFirstName, PersonValidatorBinding.FIELD_FIRST_NAME,
                mTxtFirstName.getHint().toString()));

        mBindings.add(new PersonValidatorBinding(personValidator,
                mTxtLastName, PersonValidatorBinding.FIELD_LAST_NAME,
                mTxtLastName.getHint().toString()));

        mBindings.add(new PersonValidatorBinding(personValidator,
                mTxtStreet, PersonValidatorBinding.FIELD_STREET,
                mTxtStreet.getHint().toString()));

        mBindings.add(new PersonValidatorBinding(personValidator,
                mTxtHouseNumber, PersonValidatorBinding.FIELD_HOUSE_NUMBER,
                mTxtHouseNumber.getHint().toString()));

        mBindings.add(new PersonValidatorBinding(personValidator,
                mTxtBus, PersonValidatorBinding.FIELD_BUS,
                mTxtBus.getHint().toString(), false));

        mBindings.add(new PersonValidatorBinding(personValidator,
                mTxtCity, PersonValidatorBinding.FIELD_CITY,
                mTxtCity.getHint().toString()));

        mBindings.add(new PersonValidatorBinding(personValidator,
                mTxtPostalCode, PersonValidatorBinding.FIELD_POSTAL_CODE,
                mTxtPostalCode.getHint().toString()));

        mBindings.add(new PersonValidatorBinding(personValidator,
                mTxtEmail, PersonValidatorBinding.FIELD_EMAIL,
                mTxtEmail.getHint().toString()));

        mBindings.add(new PersonValidatorBinding(personValidator,
                mTxtTelephone, PersonValidatorBinding.FIELD_PHONE,
                mTxtTelephone.getHint().toString()));

        mDobBinding = new PersonValidatorBinding(personValidator,
                mTxtDob, PersonValidatorBinding.FIELD_DATE_OF_BIRTH,
                mTxtDob.getHint().toString());
        mDobBinding.addOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if(hasFocus){
                    chooseDob();
                }
            }
        });
        mBindings.add(mDobBinding);
    }

    private void validateAll(){
        for(ValidatorBinding binding : mBindings){
            binding.validate();
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        passBundleToParent();
        mListener = null;
    }

    @Override
    public void passBundleToParent() {
        Bundle bundle = new Bundle();
        bundle.putParcelable(ARG_PERSON, mPerson);
        bundle.putBoolean(ARG_CHECKED, mChkIsContact.isChecked());
        mListener.passContactBundle(bundle);
    }

    public interface OnFragmentInteractionListener {
        public void onFinishContactPerson();
        public void cancelBooking();
        public void passContactBundle(Bundle bundle);
    }

}
