package org.wordpress.android.editor;

import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;

import org.json.JSONException;
import org.json.JSONObject;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.MediaUtils;
import org.wordpress.android.util.ToastUtils;

import java.util.Arrays;
import java.util.Map;

/**
 * A full-screen DialogFragment with image settings.
 *
 * Modifies the action bar - host activity must call {@link ImageSettingsDialogFragment#dismissFragment()}
 * when the fragment is dismissed to restore it.
 */
public class ImageSettingsDialogFragment extends DialogFragment {
    public static final int IMAGE_SETTINGS_DIALOG_REQUEST_CODE = 5;
    public static final String IMAGE_SETTINGS_DIALOG_TAG = "image-settings";

    private JSONObject mImageMeta;
    private int mMaxImageWidth;

    private EditText mTitleText;
    private EditText mCaptionText;
    private EditText mAltText;
    private Spinner mAlignmentSpinner;
    private String[] mAlignmentKeyArray;
    private EditText mLinkTo;
    private EditText mWidthText;
    private CheckBox mFeaturedCheckBox;

    private boolean mIsFeatured;

    private Map<String, String> mHttpHeaders;

    private CharSequence mPreviousActionBarTitle;
    private boolean mPreviousHomeAsUpEnabled;
    private View mPreviousCustomView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);

        ActionBar actionBar = getActionBar();
        if (actionBar == null) {
            return;
        }

        actionBar.show();

        mPreviousActionBarTitle = actionBar.getTitle();
        mPreviousCustomView = actionBar.getCustomView();

        final int displayOptions = actionBar.getDisplayOptions();
        mPreviousHomeAsUpEnabled = (displayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;

        actionBar.setTitle(R.string.image_settings);
        actionBar.setDisplayHomeAsUpEnabled(true);
        if (getResources().getBoolean(R.bool.show_extra_side_padding)) {
            actionBar.setHomeAsUpIndicator(R.drawable.ic_close_padded);
        } else {
            actionBar.setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
        }

        // Show custom view with padded Save button
        actionBar.setDisplayShowCustomEnabled(true);
        actionBar.setCustomView(R.layout.image_settings_formatbar);

        actionBar.getCustomView().findViewById(R.id.menu_save).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mImageMeta = extractMetaDataFromFields(mImageMeta);

                String imageRemoteId = "";
                try {
                    imageRemoteId = mImageMeta.getString("attachment_id");
                } catch (JSONException e) {
                    AppLog.e(AppLog.T.EDITOR, "Unable to retrieve featured image id from meta data");
                }

                Intent intent = new Intent();
                intent.putExtra("imageMeta", mImageMeta.toString());

                mIsFeatured = mFeaturedCheckBox.isChecked();
                intent.putExtra("isFeatured", mIsFeatured);

                if (!imageRemoteId.isEmpty()) {
                    intent.putExtra("imageRemoteId", Integer.parseInt(imageRemoteId));
                }

                getTargetFragment().onActivityResult(getTargetRequestCode(), getTargetRequestCode(), intent);

                restorePreviousActionBar();
                getFragmentManager().popBackStack();
                ToastUtils.showToast(getActivity(), R.string.image_settings_save_toast);
            }
        });
    }

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

        ImageView thumbnailImage = (ImageView) view.findViewById(R.id.image_thumbnail);
        TextView filenameLabel = (TextView) view.findViewById(R.id.image_filename);
        mTitleText = (EditText) view.findViewById(R.id.image_title);
        mCaptionText = (EditText) view.findViewById(R.id.image_caption);
        mAltText = (EditText) view.findViewById(R.id.image_alt_text);
        mAlignmentSpinner = (Spinner) view.findViewById(R.id.alignment_spinner);
        mLinkTo = (EditText) view.findViewById(R.id.image_link_to);
        SeekBar widthSeekBar = (SeekBar) view.findViewById(R.id.image_width_seekbar);
        mWidthText = (EditText) view.findViewById(R.id.image_width_text);
        mFeaturedCheckBox = (CheckBox) view.findViewById(R.id.featuredImage);

        // Populate the dialog with existing values
        Bundle bundle = getArguments();
        if (bundle != null) {
            try {
                mImageMeta = new JSONObject(bundle.getString("imageMeta"));

                mHttpHeaders = (Map) bundle.getSerializable("headerMap");

                final String imageSrc = mImageMeta.getString("src");
                final String imageFilename = imageSrc.substring(imageSrc.lastIndexOf("/") + 1);

                loadThumbnail(imageSrc, thumbnailImage);
                filenameLabel.setText(imageFilename);

                mTitleText.setText(mImageMeta.getString("title"));
                mCaptionText.setText(mImageMeta.getString("caption"));
                mAltText.setText(mImageMeta.getString("alt"));

                String alignment = mImageMeta.getString("align");
                mAlignmentKeyArray = getResources().getStringArray(R.array.alignment_key_array);
                int alignmentIndex = Arrays.asList(mAlignmentKeyArray).indexOf(alignment);
                mAlignmentSpinner.setSelection(alignmentIndex == -1 ? 0 : alignmentIndex);

                mLinkTo.setText(mImageMeta.getString("linkUrl"));

                mMaxImageWidth = MediaUtils.getMaximumImageWidth(mImageMeta.getInt("naturalWidth"),
                        bundle.getString("maxWidth"));

                setupWidthSeekBar(widthSeekBar, mWidthText, mImageMeta.getInt("width"));

                boolean featuredImageSupported = bundle.getBoolean("featuredImageSupported");
                if (featuredImageSupported) {
                    mFeaturedCheckBox.setVisibility(View.VISIBLE);
                    mIsFeatured = bundle.getBoolean("isFeatured", false);
                    mFeaturedCheckBox.setChecked(mIsFeatured);
                }
            } catch (JSONException e1) {
                AppLog.d(AppLog.T.EDITOR, "Missing JSON properties");
            }
        }

        mTitleText.requestFocus();

        return view;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        ActionBar actionBar = getActionBar();
        if (actionBar != null) {
            actionBar.show();
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        if (menu != null) {
            menu.clear();
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == android.R.id.home) {
            dismissFragment();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private ActionBar getActionBar() {
        if (getActivity() instanceof AppCompatActivity) {
            return ((AppCompatActivity) getActivity()).getSupportActionBar();
        } else {
            return null;
        }
    }

    /**
     * To be called when the fragment is being dismissed, either by ActionBar navigation or by pressing back in the
     * navigation bar.
     * Displays a confirmation dialog if there are unsaved changes, otherwise undoes the fragment's modifications to
     * the ActionBar and restores the last visible fragment.
     */
    public void dismissFragment() {
        try {
            JSONObject newImageMeta = extractMetaDataFromFields(new JSONObject());

            for (int i = 0; i < newImageMeta.names().length(); i++) {
                String name = newImageMeta.names().getString(i);
                if (!newImageMeta.getString(name).equals(mImageMeta.getString(name))) {
                    showDiscardChangesDialog();
                    return;
                }
            }

            if (mFeaturedCheckBox.isChecked() != mIsFeatured) {
                // Featured image status has changed
                showDiscardChangesDialog();
                return;
            }
        } catch (JSONException e) {
            AppLog.d(AppLog.T.EDITOR, "Unable to update JSON array");
        }

        getTargetFragment().onActivityResult(getTargetRequestCode(), getTargetRequestCode(), null);
        restorePreviousActionBar();
        getFragmentManager().popBackStack();
    }

    private void restorePreviousActionBar() {
        ActionBar actionBar = getActionBar();
        if (actionBar != null) {
            actionBar.setTitle(mPreviousActionBarTitle);
            actionBar.setHomeAsUpIndicator(null);
            actionBar.setDisplayHomeAsUpEnabled(mPreviousHomeAsUpEnabled);

            actionBar.setCustomView(mPreviousCustomView);
            if (mPreviousCustomView == null) {
                actionBar.setDisplayShowCustomEnabled(false);
            }
        }
    }

    /**
     * Displays a dialog asking the user to confirm that they want to exit, discarding unsaved changes.
     */
    private void showDiscardChangesDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(getString(R.string.image_settings_dismiss_dialog_title));
        builder.setPositiveButton(getString(R.string.discard), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                getTargetFragment().onActivityResult(getTargetRequestCode(), getTargetRequestCode(), null);
                restorePreviousActionBar();
                getFragmentManager().popBackStack();
            }
        });

        builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                dialog.dismiss();
            }
        });

        AlertDialog dialog = builder.create();
        dialog.show();
    }

    /**
     * Extracts the meta data from the dialog fields and updates the entries in the given JSONObject.
     */
    private JSONObject extractMetaDataFromFields(JSONObject metaData) {
        try {
            metaData.put("title", mTitleText.getText().toString());
            metaData.put("caption", mCaptionText.getText().toString());
            metaData.put("alt", mAltText.getText().toString());
            if (mAlignmentSpinner.getSelectedItemPosition() < mAlignmentKeyArray.length) {
                metaData.put("align", mAlignmentKeyArray[mAlignmentSpinner.getSelectedItemPosition()]);
            }
            metaData.put("linkUrl", mLinkTo.getText().toString());

            int newWidth = getEditTextIntegerClamped(mWidthText, 10, mMaxImageWidth);
            metaData.put("width", newWidth);
            metaData.put("height", getRelativeHeightFromWidth(newWidth));
        } catch (JSONException e) {
            AppLog.d(AppLog.T.EDITOR, "Unable to build JSON object from new meta data");
        }

        return metaData;
    }

    private void loadThumbnail(final String src, final ImageView thumbnailImage) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                if (isAdded()) {
                    final Uri localUri = Utils.downloadExternalMedia(getActivity(), Uri.parse(src), mHttpHeaders);

                    if (getActivity() != null) {
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                thumbnailImage.setImageURI(localUri);
                            }
                        });
                    }
                }
            }
        });

        thread.start();
    }

    /**
     * Initialize the image width SeekBar and accompanying EditText
     */
    private void setupWidthSeekBar(final SeekBar widthSeekBar, final EditText widthText, int imageWidth) {
        widthSeekBar.setMax(mMaxImageWidth / 10);

        if (imageWidth != 0) {
            widthSeekBar.setProgress(imageWidth / 10);
            widthText.setText(String.valueOf(imageWidth) + "px");
        }

        widthSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (progress == 0) {
                    progress = 1;
                }
                widthText.setText(progress * 10 + "px");
            }
        });

        widthText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus) {
                    widthText.setText("");
                }
            }
        });

        widthText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                int width = getEditTextIntegerClamped(widthText, 10, mMaxImageWidth);
                widthSeekBar.setProgress(width / 10);
                widthText.setSelection((String.valueOf(width).length()));

                InputMethodManager imm = (InputMethodManager) getActivity()
                        .getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(widthText.getWindowToken(),
                        InputMethodManager.RESULT_UNCHANGED_SHOWN);

                return true;
            }
        });
    }

    /**
     * Return the integer value of the width EditText, adjusted to be within the given min and max, and stripped of the
     * 'px' units
     */
    private int getEditTextIntegerClamped(EditText editText, int minWidth, int maxWidth) {
        int width = 10;

        try {
            if (editText.getText() != null)
                width = Integer.parseInt(editText.getText().toString().replace("px", ""));
        } catch (NumberFormatException e) {
            AppLog.e(AppLog.T.EDITOR, e);
        }

        width = Math.min(maxWidth, Math.max(width, minWidth));

        return width;
    }

    /**
     * Given the new width, return the proportionally adjusted height, given the dimensions of the original image
     */
    private int getRelativeHeightFromWidth(int width) {
        int height = 0;

        try {
            int naturalHeight = mImageMeta.getInt("naturalHeight");
            int naturalWidth = mImageMeta.getInt("naturalWidth");

            float ratio = (float) naturalHeight / naturalWidth;
            height = (int) (ratio * width);
        } catch (JSONException e) {
            AppLog.d(AppLog.T.EDITOR, "JSON object missing naturalHeight or naturalWidth property");
        }

        return height;
    }
}
