package com.example.nhocg.myseftcalendar.adapter;

import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.nhocg.myseftcalendar.R;
import com.example.nhocg.myseftcalendar.activities.AddEditDetailSubjectActivity;
import com.example.nhocg.myseftcalendar.activities.WeekLessonDetailActivity;
import com.example.nhocg.myseftcalendar.dialog.AddEditDetailCancelDialogFragment;
import com.example.nhocg.myseftcalendar.dialog.AddEditWeekLessonDialogFragment;
import com.example.nhocg.myseftcalendar.exception.NullObjectException;
import com.example.nhocg.myseftcalendar.helper.Constant;
import com.example.nhocg.myseftcalendar.helper.DBHelper;
import com.example.nhocg.myseftcalendar.helper.DateTimeHelper;
import com.example.nhocg.myseftcalendar.helper.FunctionHelper;
import com.example.nhocg.myseftcalendar.datas.WeekLessonDialogItem;
import com.example.nhocg.myseftcalendar.datas.entities.DayLesson;
import com.example.nhocg.myseftcalendar.datas.entities.Repeat;
import com.example.nhocg.myseftcalendar.datas.entities.WeekLesson;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.annotation.Nonnull;

import static com.example.nhocg.myseftcalendar.dialog.AddEditWeekLessonDialogFragment.AddEditWeekLessonDialogMode.WEEK_LESSON_DIALOG_EDIT_MODE;
import static com.example.nhocg.myseftcalendar.dialog.AddEditWeekLessonDialogFragment.DAY_LESSON_DIALOG_ITEM;
import static com.example.nhocg.myseftcalendar.dialog.AddEditWeekLessonDialogFragment.DAY_LESSON_DIALOG_ITEM_POS;
import static com.example.nhocg.myseftcalendar.dialog.AddEditWeekLessonDialogFragment.WEEK_LESSON_DIALOG_ITEM;
import static com.example.nhocg.myseftcalendar.dialog.AddEditWeekLessonDialogFragment.WEEK_LESSON_DIALOG_ITEM_POS;
import static com.example.nhocg.myseftcalendar.dialog.AddEditWeekLessonDialogFragment.WEEK_LESSON_DIALOG_MODE;
import static com.example.nhocg.myseftcalendar.dialog.AddEditWeekLessonDialogFragment.WEEK_LESSON_ID;

/**
 * Created by nhocg on 11/6/2017.
 */

public class WeekLessonDiaLogItemAdapter extends RecycleViewBaseAdapter<Object> {

    @Override
    public void onItemDismiss(final int position) {
        final Object o = getItem(position);
        if (o == null) return;
        removeFromAdapter(position);

        int resourStr;
        if (o instanceof WeekLessonDialogItem) {
            resourStr = R.string.week_lesson_deleted;
        } else {
            resourStr = R.string.day_lesson_deleted;
        }
        Snackbar.Callback SCallback = new Snackbar.Callback() {
            @Override
            public void onDismissed(Snackbar transientBottomBar, int event) {
                if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT || event == Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE
                        || event == Snackbar.Callback.DISMISS_EVENT_SWIPE || event == Snackbar.Callback.DISMISS_EVENT_MANUAL) {
                    deleteFromDB(o);
                } else if (event == Snackbar.Callback.DISMISS_EVENT_ACTION) {
                    undoRemoveFromAdapter(position, o);
                }
            }
        };
        FunctionHelper.makeLSnackbar(((AddEditDetailSubjectActivity) mContext).getCoordinatorLayout(), resourStr, SCallback, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
    }

    @Override
    protected void removeFromAdapter(int position) {
        if (getItem(position) instanceof WeekLessonDialogItem) {
            removeChildItem(position);
        }
        mListData.remove(position);
        mIsExpandPosList.remove(position);
        notifyItemRemoved(position);
    }

    @Override
    protected void undoRemoveFromAdapter(int pos, @NonNull Object o) {
        mListData.add(pos, o);
        mIsExpandPosList.add(pos, false);
        notifyItemInserted(pos);
    }

    @Override
    protected void deleteFromDB(@NonNull Object o) {
        DBHelper.DATABASE_CODE database_code;
        if (o instanceof WeekLessonDialogItem) {
            WeekLessonDialogItem weekLessonDialogItem = (WeekLessonDialogItem) o;
            if (weekLessonDialogItem.isOld()) {
                database_code = mDbHelper.deleteWeekLesson(weekLessonDialogItem.getWeekLesson().getWeek_lesson_id());
                if (database_code != DBHelper.DATABASE_CODE.DELETE_WEEK_LESSON_SUCCESS) {
                    FunctionHelper.makeLToast(mContext, mDbStringHelper.getDBString(database_code));
                    ((AddEditDetailSubjectActivity) mContext).finish();
                }
            }
        } else if (o instanceof DayLesson) {
            database_code = mDbHelper.deleteDayLesson(((DayLesson) o).getDay_lesson_id());
            if (database_code != DBHelper.DATABASE_CODE.DELETE_DAY_LESSON_SUCCESS) {
                FunctionHelper.makeLToast(mContext, mDbStringHelper.getDBString(database_code));
                ((AddEditDetailSubjectActivity) mContext).finish();
            }
        }
    }

    private class WeekLessonDiaLogItemViewHolder extends RecycleViewBaseViewHolder<WeekLessonDialogItem> {
        private TextView tv_repeat;
        private TextView tv_weekday;
        private TextView tv_location;
        private ViewGroup location_layout;
        private TextView tv_day;
        private TextView tv_time;
        private ImageView arrow;
        private TextView tv_status;

        private WeekLessonDiaLogItemViewHolder(View itemView) {
            super(mContext, itemView);
            tv_repeat = itemView.findViewById(R.id.week_lesson_dialog_item_repeat);
            tv_weekday = itemView.findViewById(R.id.week_lesson_dialog_item_weekday);
            tv_location = itemView.findViewById(R.id.week_lesson_dialog_item_location);
            location_layout = itemView.findViewById(R.id.week_lesson_dialog_item_location_layout);
            tv_day = itemView.findViewById(R.id.week_lesson_dialog_item_day);
            tv_time = itemView.findViewById(R.id.week_lesson_dialog_item_time);
            arrow = itemView.findViewById(R.id.arrow);
            tv_status = itemView.findViewById(R.id.week_lesson_dialog_item_status);
            if (popupMenu.getMenu().size() == 0) {
                popupMenu.inflate(R.menu.adapter_week_lesson_dialog_item_popup_menu);
            }
            itemView.setOnClickListener(null);
        }

        private void setInfo(@Nonnull WeekLessonDialogItem item) {
            WeekLesson weekLesson = item.getWeekLesson();
            String day = DateTimeHelper.getDayMonthYearString(weekLesson.getWeek_lesson_day_start()) + " - " +
                    DateTimeHelper.getDayMonthYearString(weekLesson.getWeek_lesson_day_end());

            tv_day.setText(day);
            tv_repeat.setText(getRepeatString(weekLesson.getRepeat_id()));
            tv_weekday.setText(getWeekdayString(weekLesson.getWeek_lesson_day_index()));

            String location = null;
            String time = null;
            if (!item.isOld()) {
                time = DateTimeHelper.getHourMinuteString(item.getMinute_start(), false, false) + " - " +
                        DateTimeHelper.getHourMinuteString(item.getMinute_end(), false, false);
                try {
                    location = mDbHelper.getLocation(item.getLocation_id(), null).getLocation_name();
                } catch (NullObjectException e) {
                    Log.d(TAG, e.toString());
                }
            }

            if (location == null) {
                location_layout.setVisibility(View.GONE);
            } else {
                tv_location.setText(location);
                location_layout.setVisibility(View.VISIBLE);
            }

            if (time == null) {
                tv_time.setVisibility(View.GONE);
            } else {
                tv_time.setText(time);
                tv_time.setVisibility(View.VISIBLE);
            }

            tv_repeat.setTextColor(mTextColor);
            tv_weekday.setTextColor(mTextColor);
            tv_location.setTextColor(mTextColor);
            tv_status.setTextColor(mTextColor);

            FunctionHelper.setColorDrawable(tv_repeat.getBackground(), mBgColor);
            FunctionHelper.setColorDrawable(tv_weekday.getBackground(), mBgColor);
            FunctionHelper.setColorDrawable(tv_location.getBackground(), mBgColor);
            FunctionHelper.setColorDrawable(tv_status.getBackground(), mBgColor);

            if (item.isOld()) {
                popupMenu.getMenu().findItem(R.id.menu_detail).setEnabled(true);
                itemView.setOnClickListener(this);
                arrow.setVisibility(View.VISIBLE);
                tv_status.setVisibility(View.GONE);
                if (item.isChange()) {
                    tv_status.setText(mStatus_Unsaved);
                    tv_status.setVisibility(View.VISIBLE);
                }
            } else {
                tv_status.setText(mStatus_New);
                tv_status.setVisibility(View.VISIBLE);
                popupMenu.getMenu().findItem(R.id.menu_detail).setEnabled(false);
                arrow.setVisibility(View.INVISIBLE);
            }

        }

        @Override
        public void onClick(View v) {
            int posClick = getAdapterPosition();

            if (mIsExpandPosList.get(posClick)) {
                mIsExpandPosList.set(posClick, false);
                doAnimationCollapse(arrow);
                removeChildItem(posClick);
            } else {
                mIsExpandPosList.set(posClick, true);
                doAnimationExpand(arrow);
                insertChildItem((int) WeekLessonDiaLogItemAdapter.this.getItemId(posClick), posClick);
            }
        }

        @Override
        protected boolean onEditItemClick() {
            int pos = getAdapterPosition();
            AddEditWeekLessonDialogFragment dialogFragment = new AddEditWeekLessonDialogFragment();
            dialogFragment.show(((AddEditDetailSubjectActivity) mContext).getSupportFragmentManager(), "");
            Bundle bundle = new Bundle();
            bundle.putInt(WEEK_LESSON_DIALOG_MODE, WEEK_LESSON_DIALOG_EDIT_MODE);
            bundle.putParcelable(WEEK_LESSON_DIALOG_ITEM, (WeekLessonDialogItem) getItem(pos));
            bundle.putInt(WEEK_LESSON_DIALOG_ITEM_POS, pos);
            dialogFragment.setArguments(bundle);
            return true;
        }

        @Override
        protected boolean onDetailItemClick() {
            int pos = getAdapterPosition();
            Bundle bundle = new Bundle();
            bundle.putInt(WEEK_LESSON_ID, (int) WeekLessonDiaLogItemAdapter.this.getItemId(pos));
            FunctionHelper.startNewActivity((AddEditDetailSubjectActivity) mContext,
                    WeekLessonDetailActivity.class, false, bundle);
            return true;
        }

        @Override
        protected boolean onGotoItemClick() {
            return false;
        }
    }

    private class DayLessonViewHolder extends RecycleViewBaseViewHolder<DayLesson> {
        private TextView tv_location;
        private TextView tv_time;
        private TextView tv_day;

        private DayLessonViewHolder(View itemView) {
            super(mContext, itemView);
            tv_time = itemView.findViewById(R.id.week_lesson_dialog_item_time);
            tv_location = itemView.findViewById(R.id.week_lesson_dialog_item_location);
            tv_day = itemView.findViewById(R.id.week_lesson_dialog_item_day);
            itemView.setOnLongClickListener(null);
            popupMenu.setOnMenuItemClickListener(null);
        }

        private void setInfo(@Nonnull DayLesson dayLesson) {

            boolean isCancel = dayLesson.isDay_lesson_is_cancel();

            FunctionHelper.setCancelTextView(tv_location, isCancel);
            FunctionHelper.setCancelTextView(tv_time, isCancel);
            FunctionHelper.setCancelTextView(tv_day, isCancel);

            String time = DateTimeHelper.getHourMinuteString(dayLesson.getDay_lesson_time_start(), false, false)
                    + " - " +
                    DateTimeHelper.getHourMinuteString(dayLesson.getDay_lesson_time_end(), false, false);
            tv_time.setText(time);

            String location = null;
            try {
                location = mDbHelper.getLocation(dayLesson.getLocation_id(), null).getLocation_name();
            } catch (NullObjectException e) {
                Log.d(TAG, e.toString());
            }
            tv_location.setText(location);
            tv_location.setTextColor(mTextColor);
            FunctionHelper.setColorDrawable(tv_location.getBackground(), mBgColor);

            String day = DateTimeHelper.getDayShortNameDayMonthYearString(dayLesson.getDay_lesson_time_start());
            tv_day.setText(day);
        }

        @Override
        public void onClick(View v) {
            int pos = getAdapterPosition();
            DayLesson dayLesson = (DayLesson) getItem(pos);
            if (dayLesson == null) return;

            AddEditDetailCancelDialogFragment dialogFragment = new AddEditDetailCancelDialogFragment();
            dialogFragment.show(((AddEditDetailSubjectActivity) mContext).getSupportFragmentManager(), "");
            Bundle bundle = new Bundle();
            bundle.putParcelable(DAY_LESSON_DIALOG_ITEM, dayLesson);
            bundle.putInt(DAY_LESSON_DIALOG_ITEM_POS, pos);
            dialogFragment.setArguments(bundle);
        }

        @Override
        protected boolean onEditItemClick() {
            return false;
        }

        @Override
        protected boolean onDetailItemClick() {
            return false;
        }

        @Override
        protected boolean onGotoItemClick() {
            return false;
        }

    }


    private static final String TAG = WeekLessonDiaLogItemAdapter.class.getSimpleName();

    private List<Boolean> mIsExpandPosList;
    private List<Repeat> mRepeatList;

    private String mStatus_New;
    private String mStatus_Unsaved;
    private int mTextColor;
    private int mBgColor;
    private Comparator<WeekLessonDialogItem> weekLessonDialogItemComparator = WeekLessonDialogItem.DAY_INCREASE;
    private Comparator<DayLesson> dayLessonComparator = DayLesson.DAY_INCREASE;

    public WeekLessonDiaLogItemAdapter(@Nonnull Context context, @Nonnull List<WeekLessonDialogItem> list, int text_color, int bg_color) {
        super(context, null);
        mIsExpandPosList = new ArrayList<>();
        Collections.sort(list, weekLessonDialogItemComparator);
        mListData.addAll(list);

        for (int i = 0; i < mListData.size(); i++) {
            mIsExpandPosList.add(false);
        }

        try {
            mRepeatList = mDbHelper.getRepeatList();
        } catch (NullObjectException e) {
            Log.d(TAG, e.toString());
        }

        mTextColor = text_color;
        mBgColor = bg_color;

        Resources resources = mContext.getResources();
        mStatus_New = resources.getString(R.string.status_new);
        mStatus_Unsaved = resources.getString(R.string.status_change);
    }

    @Override
    public void insertNewItem(@NonNull Object item) {
        if (!(item instanceof WeekLessonDialogItem)) return;
        mListData.add(item);
        mIsExpandPosList.add(false);
        notifyItemInserted(getItemCount() - 1);
    }

    @Override
    public void notifyItemChanged(@NonNull Object item, int pos) {
        if (pos < 0 || pos >= getItemCount()) return;

        if (item instanceof WeekLessonDialogItem) {
            WeekLessonDialogItem wItem = (WeekLessonDialogItem) item;
            if (wItem.isOld()) {
                wItem.setChange(true);
            }
            mListData.set(pos, wItem);
            notifyItemChanged(pos);
        } else if (item instanceof DayLesson) {
            DayLesson dItem = (DayLesson) item;
            mListData.set(pos, dItem);
            notifyItemChanged(pos);
        }
    }

    @Override
    public void reload(@NonNull List<?> list) {
        if (list.size() == 0 || !(list.get(0) instanceof WeekLessonDialogItem)) return;
        @SuppressWarnings("unchecked") List<WeekLessonDialogItem> listData = (List<WeekLessonDialogItem>) list;

        int i = 0;
        Object o;
        while (i < mListData.size()) {
            o = getItem(i);
            if (o == null) return;
            if (o instanceof DayLesson) {
                mListData.remove(i);
                mIsExpandPosList.remove(i);
            } else if (o instanceof WeekLessonDialogItem) {
                if (((WeekLessonDialogItem) o).isOld()) {
                    mListData.remove(i);
                    mIsExpandPosList.remove(i);
                } else {
                    i++;
                }
            }
        }

        Collections.sort(listData, weekLessonDialogItemComparator);
        mListData.addAll(0, listData);
        List<Boolean> booleans = new ArrayList<>();
        for (i = 0; i < listData.size(); i++) {
            booleans.add(false);
        }
        mIsExpandPosList.addAll(0, booleans);
        notifyDataSetChanged();
    }

    @Override
    public void onSortList(@Nonnull Comparator<?> comparator) {

    }

    public void setTextColor(int textColor) {
        mTextColor = textColor;
        notifyDataSetChanged();
    }

    public void setBgColor(int bgColor) {
        mBgColor = bgColor;
        notifyDataSetChanged();
    }


    @Override
    public int getItemViewType(int position) {
        if (getItem(position) instanceof WeekLessonDialogItem) {
            return 1;
        }
        return 2;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;
        switch (viewType) {
            case 1:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_week_lesson_dialog_item_week_lesson_item, parent, false);
                return new WeekLessonDiaLogItemViewHolder(view);
            case 2:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_day_lesson, parent, false);
                return new DayLessonViewHolder(view);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (holder.getItemViewType()) {
            case 1:
                WeekLessonDiaLogItemViewHolder itemHolder = (WeekLessonDiaLogItemViewHolder) holder;
                WeekLessonDialogItem item = (WeekLessonDialogItem) getItem(position);
                if (item == null) return;

                super.onBindViewHolder(holder, position);

                itemHolder.setInfo(item);

                break;
            case 2:
                DayLessonViewHolder item2Holder = (DayLessonViewHolder) holder;
                DayLesson dayLesson = (DayLesson) getItem(position);
                if (dayLesson == null) return;
                item2Holder.setInfo(dayLesson);
                break;
        }
    }



    private String getRepeatString(int id_repeat) {
        for (Repeat r : mRepeatList) {
            if (r.getRepeat_id() == id_repeat) {
                return String.valueOf(r.getRepeat_ts());
            }
        }
        return "";
    }

    private String getWeekdayString(int week_day_index) {
        return DateTimeHelper.getDayShortNameByIndex(week_day_index);
    }

    private void insertChildItem(int week_lesson_id, int parent_index) {
        Object o = getItem(parent_index);
        if (o == null || !(o instanceof WeekLessonDialogItem)) return;
        List<DayLesson> dayLessons = new ArrayList<>();
        try {
            dayLessons = mDbHelper.getDayLessonList(week_lesson_id, null,false);
        } catch (NullObjectException e) {
            Log.d(TAG, e.toString());
        }

        if (dayLessons.size() > 0) {
            Collections.sort(dayLessons, dayLessonComparator);
            mListData.addAll(parent_index + 1, dayLessons);
            List<Boolean> booleanList = new ArrayList<>();
            for (int i = 0; i < dayLessons.size(); i++) {
                booleanList.add(false);
            }
            mIsExpandPosList.addAll(parent_index + 1, booleanList);
            notifyItemRangeInserted(parent_index + 1, dayLessons.size());
        }

    }

    private void removeChildItem(int parent_index) {
        if (!(getItem(parent_index) instanceof WeekLessonDialogItem)) return;
        int i = parent_index + 1;
        while (i < mListData.size()) {
            Object o = getItem(i);
            if (o == null) return;
            if (o instanceof DayLesson) {
                mListData.remove(i);
                mIsExpandPosList.remove(i);
                notifyItemRemoved(i);
            } else {
                break;
            }
        }
    }

    @Override
    public long getItemId(int position) {
        Object o = getItem(position);
        if (o == null) return Constant.INT_NONE_VALUE;
        if (o instanceof WeekLessonDialogItem) {
            WeekLessonDialogItem weekLessonDialogItem = (WeekLessonDialogItem) o;
            return weekLessonDialogItem.getWeekLesson().getWeek_lesson_id();
        } else if (o instanceof DayLesson) {
            return ((DayLesson) o).getDay_lesson_id();
        }

        return Constant.INT_NONE_VALUE;
    }

    protected Object getItem(int pos) {
        return getItemCount() != 0 ? mListData.get(pos) : null;
    }

    public List<WeekLessonDialogItem> getList() {
        List<WeekLessonDialogItem> list = new ArrayList<>();
        for (Object o : mListData) {
            if (o instanceof WeekLessonDialogItem) {
                list.add((WeekLessonDialogItem) o);
            }
        }
        return list;
    }
}