package com.google.lizlooney.shoppinglist;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Set;

/**
 * Activity class for editing an item on the shopping list.
 *
 * @author lizlooney@gmail.com (Liz Looney)
 */
public final class EditItem extends Activity {
  public static final String ITEM_DESCRIPTION = "item_description";
  public static final String ITEM_CATEGORY = "item_category";
  public static final String ITEM_AUTO_DELETE = "item_auto_delete";
  public static final String ITEM_STORES = "item_stores";
  public static final String ITEM_AISLES = "item_aisles";
  public static final String ALL_CATEGORIES = "all_categories";
  public static final String ALL_AISLES = "all_aisles";
  public static final String ALL_STORES = "all_stores";

  private static final String LOG_TAG = "ShoppingList-EditItem";
  private static final int CHOOSE_STORES_REQUEST_CODE = 1;

  private final Set<String> allCategories = new TreeSet<>();
  private final Set<String> allStores = new TreeSet<>();
  private final Set<String> allAisles = new TreeSet<>();

  private EditText descriptionEditText;
  private Spinner categorySpinner;
  private ArrayAdapter<String> categoryAdapter;
  private LinearLayout storeAislesContainer;
  private final List<Spinner> aisleSpinners = new ArrayList<>();
  private Button chooseStoresButton;
  private Button okButton;

  private final Map<String, String> itemStoreAisles = new TreeMap<>();

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.edit_item);

    descriptionEditText = findViewById(R.id.description);
    categorySpinner = findViewById(R.id.category);
    storeAislesContainer = findViewById(R.id.storeAislesContainer);
    chooseStoresButton = findViewById(R.id.chooseStores);
    final CheckBox autoDeleteCheckBox = findViewById(R.id.autoDelete);
    Button deleteButton = findViewById(R.id.deleteNow);
    okButton = findViewById(R.id.ok);
    Button cancelButton = findViewById(R.id.cancel);

    Intent startIntent = getIntent();

    Collections.addAll(allCategories, startIntent.getStringArrayExtra(ALL_CATEGORIES));
    Collections.addAll(allStores, startIntent.getStringArrayExtra(ALL_STORES));
    Collections.addAll(allAisles, startIntent.getStringArrayExtra(ALL_AISLES));

    // description
    if (startIntent.hasExtra(ITEM_DESCRIPTION)) {
      String description = startIntent.getStringExtra(ITEM_DESCRIPTION);
      descriptionEditText.setText(description);
      descriptionEditText.setSelection(description.length());
      descriptionEditText.requestLayout();
    }
    descriptionEditText.addTextChangedListener(new TextChangeAdapter() {
      @Override
      public void textChanged(String s) {
        String description = s.trim();
        okButton.setEnabled(description.length() > 0);
      }
    });

    // category
    categoryAdapter = new ArrayAdapter<>(this, R.layout.spinner_item);
    categoryAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
    categorySpinner.setAdapter(categoryAdapter);
    Utils.updateSpinner(
        categorySpinner,
        categoryAdapter,
        allCategories,
        startIntent.getStringExtra(ITEM_CATEGORY));

    // stores and aisles
    String[] itemStores = startIntent.getStringArrayExtra(ITEM_STORES);
    if (itemStores == null) {
      itemStores = new String[0];
    }
    String[] itemAisles = startIntent.getStringArrayExtra(ITEM_AISLES);
    if (itemAisles == null) {
      itemAisles = new String[0];
    }
    if (itemStores.length == itemAisles.length) {
      for (int i = 0; i < itemStores.length; i++) {
        String store = itemStores[i];
        String aisle = itemAisles[i];
        itemStoreAisles.put(store, aisle);
      }
    }
    fillStoreAislesContainer();

    chooseStoresButton.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View view) {
            chooseStores();
          }
        });

    // auto-delete
    autoDeleteCheckBox.setChecked(startIntent.getBooleanExtra(ITEM_AUTO_DELETE, false));

    // delete button
    if (startIntent.hasExtra(ITEM_DESCRIPTION)) {
      deleteButton.setOnClickListener(
          new OnClickListener() {
            @Override
            public void onClick(View view) {
              AlertDialog alertDialog =
                  new AlertDialog.Builder(EditItem.this)
                      .setTitle(getString(R.string.DeleteNow))
                      .setMessage(getString(R.string.DeleteNowConfirm))
                      .setNegativeButton(
                          android.R.string.cancel, (dialog, which) -> dialog.cancel())
                      .setPositiveButton(
                          getString(android.R.string.ok),
                          new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                              dialog.dismiss();
                              // To delete the item, set the result with no intent.
                              setResult(Activity.RESULT_OK);
                              finish();
                            }
                          })
                      .create();
              alertDialog.show();
            }
          });
    } else {
      // Can't delete the item because it hasn't been added yet.
      deleteButton.setVisibility(View.GONE);
    }

    // ok and cancel buttons
    okButton.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View view) {
        String descriptionString = descriptionEditText.getText().toString().trim();
        if (descriptionString.length() > 0) {
          Intent resultIntent = new Intent();
          resultIntent.putExtra(ITEM_DESCRIPTION, descriptionString);
          String categoryString = (String) categorySpinner.getSelectedItem();
          resultIntent.putExtra(ITEM_CATEGORY, categoryString);
          boolean autoDeleteBoolean = autoDeleteCheckBox.isChecked();
          resultIntent.putExtra(ITEM_AUTO_DELETE, autoDeleteBoolean);

          List<String> itemStores = new ArrayList<>();
          List<String> itemAisles = new ArrayList<>();
          for (Map.Entry<String, String> entry : itemStoreAisles.entrySet()) {
            itemStores.add(entry.getKey());
            itemAisles.add(entry.getValue());
          }
          String[] itemStoresArray = itemStores.toArray(new String[0]);
          resultIntent.putExtra(ITEM_STORES, itemStoresArray);
          String[] itemAislesArray = itemAisles.toArray(new String[0]);
          resultIntent.putExtra(ITEM_AISLES, itemAislesArray);

          setResult(Activity.RESULT_OK, resultIntent);
          finish();
        }
      }
    });
    cancelButton.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View view) {
        finish();
      }
    });

    initDisplay();
  }

  private void initDisplay() {
    if (categorySpinner.getHeight() == 0) {
      new Handler()
          .post(
              new Runnable() {
                @Override
                public void run() {
                  initDisplay();
                }
              });
      return;
    }

    categorySpinner.setDropDownVerticalOffset(categorySpinner.getHeight());
    for (Spinner aisleSpinner : aisleSpinners) {
      aisleSpinner.setDropDownVerticalOffset(aisleSpinner.getHeight());
    }
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    menu.add(getString(R.string.AddCategory))
        .setOnMenuItemClickListener(
            new OnMenuItemClickListener() {
              @Override
              public boolean onMenuItemClick(MenuItem menuItem) {
                Utils.addValueToSpinners(EditItem.this, getString(R.string.AddCategory),
                    allCategories, categorySpinner);
                return true;
              }
            });

    menu.add(getString(R.string.AddAisle))
        .setOnMenuItemClickListener(
            new OnMenuItemClickListener() {
              @Override
              public boolean onMenuItemClick(MenuItem menuItem) {
                Utils.addValueToSpinners(EditItem.this, getString(R.string.AddAisle),
                    allAisles, aisleSpinners.toArray(new Spinner[0]));
                return true;
              }
            });

    return true;
  }

  private void fillStoreAislesContainer() {
    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int storeWidth = (int) (size.x * 0.55);

    storeAislesContainer.removeAllViews();
    aisleSpinners.clear();

    for (Map.Entry<String, String> entry : itemStoreAisles.entrySet()) {
      final String store = entry.getKey();
      String aisle = entry.getValue();

      LinearLayout row = new LinearLayout(this);

      // Create a TextView for the store.
      TextView storeTextView = new TextView(this);
      Utils.setColors(storeTextView);
      storeTextView.setText(store);
      row.addView(storeTextView, new LayoutParams(storeWidth, LayoutParams.WRAP_CONTENT, 0f));

      // Create a Spinner for the aisle.
      Spinner aisleSpinner = new Spinner(this);
      aisleSpinners.add(aisleSpinner);
      ArrayAdapter<String> aisleAdapter = new ArrayAdapter<>(this, R.layout.spinner_item_right);
      aisleAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item_right);
      aisleSpinner.setAdapter(aisleAdapter);
      aisleSpinner.setBackgroundTintList(ColorStateList.valueOf(0xFF00FFFF));
      aisleSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long id) {
          String selectedAisle = (String) adapterView.getItemAtPosition(pos);
          itemStoreAisles.put(store, selectedAisle);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {}
      });
      Utils.updateSpinner(
          aisleSpinner,
          aisleAdapter,
          allAisles,
          aisle);
      row.addView(aisleSpinner, new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1f));

      // Add the row to the storeAislesContainer.
      storeAislesContainer.addView(row);
    }
  }

  private void chooseStores() {
    Intent activityIntent = new Intent();
    activityIntent.setClass(this, ChooseStores.class);
    String[] itemStoresArray = itemStoreAisles.keySet().toArray(new String[0]);
    activityIntent.putExtra(ChooseStores.ITEM_STORES, itemStoresArray);
    String[] allStoresArray = allStores.toArray(new String[0]);
    activityIntent.putExtra(ChooseStores.ALL_STORES, allStoresArray);
    try {
      startActivityForResult(activityIntent, CHOOSE_STORES_REQUEST_CODE);
    } catch (ActivityNotFoundException e) {
      Log.e(LOG_TAG, "startActivityForResult threw ActivityNotFoundException", e);
    }
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CHOOSE_STORES_REQUEST_CODE) {
      if (resultCode == Activity.RESULT_OK && data != null) {
        allStores.clear();
        Collections.addAll(allStores, data.getStringArrayExtra(ChooseStores.ALL_STORES));

        String[] itemStores = data.getStringArrayExtra(ChooseStores.ITEM_STORES);
        Map<String, String> oldStoreAisles = new TreeMap<>(itemStoreAisles);
        itemStoreAisles.clear();
        for (String store : itemStores) {
          String aisle = oldStoreAisles.get(store);
          if (aisle == null) {
            aisle = "1";
          }
          itemStoreAisles.put(store, aisle);
        }

        fillStoreAislesContainer();
      }
    }
  }
}
