package com.maxiee.heartbeat.ui;

import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.maxiee.heartbeat.R;
import com.maxiee.heartbeat.common.FileUtils;
import com.maxiee.heartbeat.common.GalleryUtils;
import com.maxiee.heartbeat.common.TimeUtils;
import com.maxiee.heartbeat.common.tagview.Tag;
import com.maxiee.heartbeat.common.tagview.TagView;
import com.maxiee.heartbeat.database.utils.EventUtils;
import com.maxiee.heartbeat.database.utils.ImageUtils;
import com.maxiee.heartbeat.database.utils.LabelUtils;
import com.maxiee.heartbeat.database.utils.ThoughtUtils;
import com.maxiee.heartbeat.model.Event;
import com.maxiee.heartbeat.model.Image;
import com.maxiee.heartbeat.model.Label;
import com.maxiee.heartbeat.model.Thoughts;
import com.maxiee.heartbeat.ui.adapter.ThoughtTimeaxisAdapter;
import com.maxiee.heartbeat.ui.common.BaseActivity;

import java.util.ArrayList;

import butterknife.Bind;
import butterknife.ButterKnife;

/**
 * Created by maxiee on 15-6-13.
 */
public class EventDetailActivity extends BaseActivity {
    private final static String TAG = EventDetailActivity.class.getSimpleName();

    public static final String EXTRA_NAME = "id";
    private static final int ADD_IMAGE = 1127;
    private static final int LONG_IMAGE_IMAGE_MAX_HEIGHT = 300;

    private long mId;
    private Event mEvent;

    @Bind(R.id.tv_event)        TextView mTvEvent;
    @Bind(R.id.recyclerview)    RecyclerView mRecyclerView;
    @Bind(R.id.tagview)         TagView mTagView;
    @Bind(R.id.tv_time)         TextView mTvTime;
    @Bind(R.id.backdrop)        ImageView mImageBackDrop;
    @Bind(R.id.card_event)      View mCardEvent;
    @Bind(R.id.add_imgae)       TextView mAddImageText;
    @Bind(R.id.header)          View mHeaderView;

    private LinearLayoutManager mLayoutManager;
    private ThoughtTimeaxisAdapter mAdapter;

    private Image mImage;
    private Thoughts mThoughts;
    private String mSortingType;
    private boolean mHasImage = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event_detail);
        ButterKnife.bind(this);

        Intent intent = getIntent();
        mId = intent.getLongExtra(EXTRA_NAME, -1);

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
        mSortingType = sp.getString("time_axis_sorting", "0");

        final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        setTitle("");
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);

        mEvent = EventUtils.getEvent(this, mId);

        mTagView.setOnTagClickListener(new TagView.OnTagClickListener() {
            @Override
            public void onTagClick(Tag tag, int position) {
                Intent i = new Intent();
                i.setAction(Intent.ACTION_MAIN);
                i.setClass(EventDetailActivity.this, LabelDetailActivity.class);
                i.putExtra("tag_text", tag.text);
                startActivity(i);
            }
        });

        mTvTime.setText(TimeUtils.parseTime(this, mEvent.getTimestamp()));

        mCardEvent.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Intent i = new Intent(EventDetailActivity.this, AddEventActivity.class);
                i.putExtra(AddEventActivity.ID_EVENT_MODIFY, mId);
                startActivity(i);
                return true;
            }
        });

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(EventDetailActivity.this, AddEditThoughtActivity.class);
                i.putExtra(AddEditThoughtActivity.MODE, AddEditThoughtActivity.MODE_NEW);
                i.putExtra(AddEditThoughtActivity.EVENT_KEY, mId);
                startActivity(i);
            }
        });

        mThoughts = ThoughtUtils.getThoughtsByEventId(this, mId);
        mAdapter = new ThoughtTimeaxisAdapter(mThoughts);
        mRecyclerView.setAdapter(mAdapter);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.transparent));
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        mEvent = EventUtils.getEvent(this, mId);
        mTvEvent.setText(mEvent.getEvent());
        mTvTime.setText(TimeUtils.parseTime(this, mEvent.getTimestamp()));
        mThoughts = ThoughtUtils.getThoughtsByEventId(this, mEvent.getId());
        mAdapter.setData(mThoughts);
        mAdapter.notifyDataSetChanged();
        initImage();
        updateTagView();
    }

    private void initImage() {
        mImage = ImageUtils.getImageByEventId(this, mEvent.getId());
        if (mImage == null) {
            mAddImageText.setVisibility(View.VISIBLE);
            mAddImageText.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    GalleryUtils.openGallery(EventDetailActivity.this);
                }
            });
        } else {
            changeHeaderToImage();
            mAddImageText.setVisibility(View.INVISIBLE);
            Glide.with(this)
                    .load(GalleryUtils.getImagePath(mImage.getPath()))
                    .into(mImageBackDrop);
            mImageBackDrop.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent i = new Intent(EventDetailActivity.this, GalleryActivity.class);
                    i.putExtra(GalleryActivity.EVENT_ID, mEvent.getId());
                    startActivity(i);
                }
            });
        }
    }

    private void changeHeaderToImage() {
        mHeaderView.setVisibility(View.GONE);
        mImageBackDrop.setVisibility(View.VISIBLE);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_event_detail, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == android.R.id.home) {
            this.onBackPressed();
            return true;
        }
        if (id == R.id.long_iamge) {
//            generateLongImage();
            new LongImageTask().execute();
        }
        return super.onOptionsItemSelected(item);
    }

    public void updateTagView() {
        mTagView.clear();
        ArrayList<Label> labels = LabelUtils.getLabelsByEvent(this, mEvent);
        for (Label l : labels) mTagView.addTag(new Tag(l.getLabel()));
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        String path = GalleryUtils.onActivityResult(this, requestCode, resultCode, data);
        if (path != null) ImageUtils.addImage(this, mEvent.getId(), path);
        initImage();
    }

    private class LongImageTask extends AsyncTask<Void, Integer, Void> {
        private ProgressDialog progressDialog;
        private Canvas mBitmapHolder;
        private int mWidth;
        private Bitmap mBitmap;
        private View mView;
        private TextView mTv;
        private ImageView mIv;
        private TextView mTvOrder;
        private TextView mTvTime;
        private View mPoint;
        private LinearLayout mLL;
        private int mYPos = 0;
        private int mHeight = 0;

        @Override
        protected void onPreExecute() {
            progressDialog = new ProgressDialog(EventDetailActivity.this);
            progressDialog.setMessage(getString(R.string.generating));
            progressDialog.setCancelable(false);
            progressDialog.show();

//            mCardEvent.setBackgroundColor(ContextCompat.getColor(EventDetailActivity.this, android.support.v7.cardview.R.color.cardview_light_background));

            // create a parent layout of time-axis item
            FrameLayout mFl = new FrameLayout(EventDetailActivity.this);
            mFl.setBackgroundColor(ContextCompat.getColor(EventDetailActivity.this, R.color.window_background));

            // get display width
            DisplayMetrics displaymetrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
            mWidth = displaymetrics.widthPixels;

            // create time-axis item view from layout
            mView = getLayoutInflater().inflate(R.layout.item_thought_timeaxis, mFl);
            mTv = (TextView) mView.findViewById(R.id.tv_thought);
            mIv = (ImageView) mView.findViewById(R.id.image_thought);
            mTvOrder = (TextView) mView.findViewById(R.id.tv_order);
            mTvTime = (TextView) mView.findViewById(R.id.tv_time);
            mPoint = mView.findViewById(R.id.time_point);

            setPointColor();

            createBottomLogoLayout();
        }

        private void setPointColor() {
            final TypedValue typedValue = new TypedValue();
            getTheme().resolveAttribute(R.attr.colorAccent, typedValue, true);
            int color = typedValue.data;
            Drawable d = ContextCompat.getDrawable(EventDetailActivity.this, R.drawable.circle_timeaxis);
            d.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
            mPoint.setBackgroundDrawable(d);
        }

        private void createBottomLogoLayout() {
            mLL = new LinearLayout(EventDetailActivity.this);
            mLL.setBackgroundColor(ContextCompat.getColor(EventDetailActivity.this, R.color.window_background));
            ViewGroup.LayoutParams LLParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 100);
            mLL.setLayoutParams(LLParams);
            mLL.setOrientation(LinearLayout.HORIZONTAL);
            mLL.setPadding(24, 0, 0, 0);
            mLL.setGravity(Gravity.CENTER_VERTICAL);
            ImageView icon = new ImageView(EventDetailActivity.this);
            icon.setScaleType(ImageView.ScaleType.CENTER_CROP);
            icon.setImageDrawable(ContextCompat.getDrawable(EventDetailActivity.this, R.mipmap.ic_launcher));
            mLL.addView(icon);
            TextView hb = new TextView(EventDetailActivity.this);
            hb.setText("@心动小分队");
            mLL.addView(hb);
            mLL.measure(View.MeasureSpec.makeMeasureSpec(mWidth, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
            mHeight += mLL.getMeasuredHeight();
        }

        @Override
        protected Void doInBackground(Void... params) {
            mHeight += measureViewsHeight(mWidth);

            Log.d("maxiee", "生成Bitmap:" + String.valueOf(mWidth) + "," + String.valueOf(mHeight));
            mBitmap = Bitmap.createBitmap(
                    mWidth,
                    mHeight,
                    Bitmap.Config.RGB_565);
            mBitmapHolder = new Canvas(mBitmap);

            if (mImage != null) publishProgress(-2);//backdrop
            publishProgress(-1);//event card
            for (int i=0; i<mThoughts.length(); i++) {
                publishProgress(i);
            }
            publishProgress(-3);
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            int progress = values[0];
            if (progress == -2) {
                // draw backdrop
                if (mImage != null) {
                    int backDropHeight = mImageBackDrop.getMeasuredHeight();
                    mImageBackDrop.layout(0, 0, mWidth, backDropHeight);
                    mImageBackDrop.buildDrawingCache();
                    Bitmap backDropBitmap = mImageBackDrop.getDrawingCache();
                    if (backDropBitmap != null) {
                        mBitmapHolder.drawBitmap(backDropBitmap, 0, 0, null);
                    }
                    mYPos += backDropHeight;
                }
            }
            else if (progress == -1) {
                // draw cardview
                int cardEventHeight = mCardEvent.getMeasuredHeight();
                mCardEvent.layout(0, 0, mWidth, cardEventHeight);
                mCardEvent.buildDrawingCache();
                Bitmap eventBitmap = mCardEvent.getDrawingCache();
                if (eventBitmap != null) {
                    mBitmapHolder.drawBitmap(eventBitmap, 0, mYPos, null);
                }
                mYPos += cardEventHeight;
            } else if (progress == -3) {
                mLL.layout(0, 0, mWidth, mLL.getMeasuredHeight());
                Log.d("maxiee", "llMeasureH:" + String.valueOf(mLL.getMeasuredHeight()));
                mLL.buildDrawingCache();
                Bitmap b = mLL.getDrawingCache();
                if (b != null) {
                    Log.d("maxiee", "Logo不为空");
                    mBitmapHolder.drawBitmap(b, 0, mYPos, null);
                }
            } else if (progress >= 0) {
                // draw item
                Bitmap itemBitmap;
                int childHeight;

                mTv.setText(mThoughts.get(progress).getThought());
                mTvOrder.setText(getOrder(progress, mThoughts.length()));
                long time = mThoughts.get(progress).getTimeStamp();
                mTvTime.setText(TimeUtils.parseTime(EventDetailActivity.this, time));
                if (mThoughts.get(progress).hasImage()) {
                    mIv.setVisibility(View.VISIBLE);
                    Bitmap bmp = loadBitmap(mTv.getMeasuredWidth(), LONG_IMAGE_IMAGE_MAX_HEIGHT, mThoughts.get(progress).getPath());
                    mIv.setImageBitmap(bmp);
                } else {
                    mIv.setVisibility(View.GONE);
                }
                mView.measure(View.MeasureSpec.makeMeasureSpec(mWidth, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                childHeight = mView.getMeasuredHeight();
                mView.layout(0, 0, mWidth, childHeight);
                mView.buildDrawingCache();
                itemBitmap = mView.getDrawingCache();
                if (itemBitmap != null) {
                    mBitmapHolder.drawBitmap(itemBitmap, 0, mYPos, null);
                }
                mView.destroyDrawingCache();
                mYPos += childHeight;
            }
        }

        @Override
        protected void onPostExecute(Void aVoid) {
//            drawViews(mView, mBitmapHolder, mWidth);
            String s = FileUtils.saveLongImage(EventDetailActivity.this, mBitmap);
            progressDialog.cancel();
            if (!s.isEmpty()) {
                try {
                    Log.d("maxiee", "地址:" + s);
                    sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + s)));
                } catch (Exception e) {e.printStackTrace();}
                AlertDialog.Builder builder = new AlertDialog.Builder(
                        EventDetailActivity.this,
                        R.style.AppTheme_Dialog);
                builder.setTitle(getString(R.string.long_image));
                builder.setMessage(getString(R.string.generate_ok) + s);
                builder.setCancelable(false);
                final String path = s;
                builder.setPositiveButton(R.string.view, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent();
                        intent.setAction(Intent.ACTION_VIEW);
                        intent.setDataAndType(Uri.parse("file://" + path), "image/*");
                        startActivity(intent);
                        dialog.cancel();
                    }
                });
                builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });
                builder.show();
            } else {
                Toast.makeText(EventDetailActivity.this, getString(R.string.add_failed), Toast.LENGTH_LONG).show();
            }
        }

        private int measureViewsHeight(int width) {
            int height = 0;

            if (mImage != null) height += mImageBackDrop.getMeasuredHeight();

            height += mCardEvent.getMeasuredHeight();

            mView.measure(View.MeasureSpec.makeMeasureSpec(mWidth, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
            int screenWidth = mTv.getMeasuredWidth();
            mIv.setVisibility(View.GONE);

            // get Size
            int rvItemNum = mThoughts.length();
            for (int i=0; i<rvItemNum; i++) {
                mTv.setText(mThoughts.get(i).getThought());
                if (mThoughts.get(i).hasImage()) {
                    mIv.setVisibility(View.VISIBLE);
                    Bitmap bmp = loadBitmap(screenWidth, LONG_IMAGE_IMAGE_MAX_HEIGHT, mThoughts.get(i).getPath());
                    mIv.setImageBitmap(bmp);
                } else {
                    mIv.setVisibility(View.GONE);
                }
                mView.measure(View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                height += mView.getMeasuredHeight();
            }
            return height;
        }

        private Bitmap loadBitmap(int reqWidth, int reqHeight, String path) {
            path = GalleryUtils.getImagePath(path);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(path, options);
            int imageWidth = options.outWidth;
            int imageHeight = options.outHeight;
            int inSampleSize = 1;

            if (imageWidth > reqWidth) {

                final int halfHeight = imageHeight / 2;
                final int halfWidth = imageWidth / 2;

                while ((halfHeight / inSampleSize) > reqHeight) {
                    inSampleSize *= 2;
                }
            }
            options.inJustDecodeBounds = false;
            options.inSampleSize = inSampleSize;
            Bitmap b =  BitmapFactory.decodeFile(path, options);
            int orientation = 1;
            try {
                ExifInterface exif = new ExifInterface(path);
                orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
            } catch (Exception e) {e.printStackTrace();}
            Matrix matrix = new Matrix();
            switch (orientation) {
                case 2:
                    matrix.setScale(-1, 1);
                    break;
                case 3:
                    matrix.setRotate(180);
                    break;
                case 4:
                    matrix.setRotate(180);
                    matrix.postScale(-1, 1);
                    break;
                case 5:
                    matrix.setRotate(90);
                    matrix.postScale(-1, 1);
                    break;
                case 6:
                    matrix.setRotate(90);
                    break;
                case 7:
                    matrix.setRotate(-90);
                    matrix.postScale(-1, 1);
                    break;
                case 8:
                    matrix.setRotate(-90);
                    break;
                default:
                    return b;
            }
            try {
                Bitmap oriented = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, true);
                b.recycle();
                return oriented;
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
                return b;
            }
        }
    }

    private String getOrder(int position, int length) {
        String order;
        if (mSortingType.equals("0")) {
            switch (position) {
                case 0:
                    order = getString(R.string.firtime);
                    break;
                case 1:
                    order = getString(R.string.sectime);
                    break;
                default:
                    order = String.valueOf(position + 1) + ".";
                    break;
            }
        } else {
            if (position == length - 1) {
                order = getString(R.string.firtime);
            } else if (position == length - 2) {
                order = getString(R.string.sectime);
            } else {
                order = String.valueOf(length - position) + ".";
            }
        }
        return order;
    }
}
