package com.revoapp.calendar;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.TextView;

import com.revoapp.api.database.calendar.pojo.Events;
import com.revoapp.api.database.calendar.pojo.Pills;
import com.revoapp.api.utils.DateTimeConvert;
import com.revoapp.api.utils.Utils;
import com.revoapp.calendar.adapter.DayNameAdapter;
import com.revoapp.calendar.adapter.MonthAdapter;
import com.revoapp.calendar.database.DatabaseHandler;
import com.revoapp.calendar.database.PillsDatabaseHandler;
import com.revoapp.calendar.dialogs.AddEventDialog;
import com.revoapp.calendar.helper.SimpleDialogItem;
import com.revoapp.calendar.helper.ThemeHelper;
import com.revoapp.calendarapp.R;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Locale;

public class MonthActivity extends ParentActivity {
    private Context context;
    private GridView gridView;
    private MonthAdapter adapter;
    private ArrayList<SimpleDialogItem> days;
    private ArrayList<SimpleDialogItem> daysName;
    private TextView monthInfo;
    private ImageButton monthLeft, monthRight;
    public static int currentMonth;
    public static int currentYear;
    private Calendar globalCalendar;
    private Animation slideLeft, slideRight;
    private Handler mHandler;
    public static int selectedDay = -1;
    private int selectedGridViewItem = -1;
    private int previousDayCount;
    private ArrayList<Integer> arrayListIcons;
    private ArrayList<Events> eventsList;
    private ArrayList<Pills> pillsList;
    private static MonthActivity monthActivity;
    private int yearAfterRotate;
    private int monthAfterRotate;
    private int dayAfterRotate;
    private AddEventDialog addEventDialog;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.month_activity);

        monthActivity = this;
        context = this;
        Utils.disableLockScreen(this);

        if (savedInstanceState != null) {
            yearAfterRotate = savedInstanceState.getInt("year");
            monthAfterRotate = savedInstanceState.getInt("month");
            dayAfterRotate = savedInstanceState.getInt("day");
            initCalAfterRotate();
        } else {
            initCal();
        }

        if (savedInstanceState != null) {
            if (savedInstanceState.getBoolean("dialogAdd")) {
                addEventDialog = new AddEventDialog(context, monthActivity, savedInstanceState.getInt("numberOfScreen"), savedInstanceState.getStringArrayList("data"), savedInstanceState.getString("title"));
                addEventDialog.show();
//                InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
            }
        }
    }

    @Override
    public void onStop() {
        super.onStop();

        if (addEventDialog != null) {
            if (addEventDialog.isShowing()) {
                addEventDialog.dismiss();
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        refreshView();
        if (gridView != null) {
            monthInfo.setText(getMonthName(globalCalendar));
            adapter = new MonthAdapter(context, R.layout.month_gridview_item, days);

            gridView.setAdapter(adapter);

            gridView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    ViewGroup gridChild = (ViewGroup) gridView.getChildAt(selectedDay + previousDayCount - 1);
                    if (selectedGridViewItem != -1) {
                        ViewGroup gc = (ViewGroup) gridView.getChildAt(selectedGridViewItem);
                        if (gc != null && gc.getChildAt(0) != null)
                            gc.getChildAt(0).setBackgroundResource(ThemeHelper.get_component_cell_off());
                    }
                    if (gridChild != null) {
                        gridChild.getChildAt(0).setBackgroundResource(ThemeHelper.get_component_cell_on());
                        selectedGridViewItem = selectedDay + previousDayCount - 1;
                    }
                }
            }, 100);
        }
    }

    private void initCal() {
        globalCalendar = Calendar.getInstance();
        currentMonth = Calendar.getInstance().get(Calendar.MONTH);
        currentYear = Calendar.getInstance().get(Calendar.YEAR);
        selectedDay = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
    }

    private void initCalAfterRotate() {
        globalCalendar = Calendar.getInstance();
        currentMonth = monthAfterRotate;
        currentYear = yearAfterRotate;
        selectedDay = dayAfterRotate;
    }

    private void init() {
        pillsList = new ArrayList<Pills>();
        eventsList = new ArrayList<Events>();
        calendarDays();
        calendarDaysName();

        mHandler = new Handler();
        slideLeft = AnimationUtils.loadAnimation(this, R.anim.month_slide_left);

        slideRight = AnimationUtils.loadAnimation(this, R.anim.month_slide_from_left);

        slideRight.setAnimationListener(new AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                gridView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        gridView.startAnimation(slideLeft);
                        mHandler.post(mRunnable);
                    }
                }, 0);
            }
        });

        gridView = (GridView) findViewById(R.id.month_gridView);
        adapter = new MonthAdapter(context, R.layout.month_gridview_item, days);
        gridView.setAdapter(adapter);
        gridView.setOnItemClickListener(dayClickListener);
        gridView.setOnTouchListener(notScrollListener);

        GridView dayOfWeek = (GridView) findViewById(R.id.month_week_day_gridView);
        DayNameAdapter dayNameAdapter = new DayNameAdapter(context, R.layout.month_day_name_gridview_item, daysName);
        dayOfWeek.setAdapter(dayNameAdapter);
        dayOfWeek.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return event.getAction() == MotionEvent.ACTION_MOVE;
            }
        });

        monthInfo = (TextView) findViewById(R.id.month_info);
        monthInfo.setText(getMonthName(globalCalendar));

        monthLeft = (ImageButton) findViewById(R.id.month_left);
        monthLeft.setBackgroundResource(ThemeHelper.get_button_selector());
        monthLeft.setImageResource(ThemeHelper.get_icon50_arrow_left());
        monthLeft.setOnClickListener(chooseMonthListener);

        monthRight = (ImageButton) findViewById(R.id.month_right);
        monthRight.setBackgroundResource(ThemeHelper.get_button_selector());
        monthRight.setImageResource(ThemeHelper.get_icon50_arrow_right());
        monthRight.setOnClickListener(chooseMonthListener);

        View todayV = findViewById(R.id.today_linear);
        todayV.setBackgroundResource(ThemeHelper.get_button_selector());
        todayV.setOnClickListener(todayListener);

        TextView todayIcon = (TextView) findViewById(R.id.today_icon);
        todayIcon.setBackgroundResource(ThemeHelper.get_icon50_today());
        todayIcon.setText(new GregorianCalendar().get(GregorianCalendar.DAY_OF_MONTH) + "");
        todayIcon.setTextColor(context.getResources().getColorStateList(
                ThemeHelper.get_button_color_selector()));
        todayIcon.setTextSize((int) getResources().getDimension(R.dimen.calendar_header_text));
//        todayIcon.setTextSize(30);

        TextView todayText = (TextView) findViewById(R.id.today_text);
        todayText.setTextColor(context.getResources().getColorStateList(
                ThemeHelper.get_button_color_selector()));
        todayText.setTextSize((int) getResources().getDimension(R.dimen.calendar_header_text));
//        todayText.setTextSize(30);
        todayText.setTypeface(ThemeHelper.get_primary_font());

        Button butAddEvent = (Button) findViewById(R.id.add_event);
        butAddEvent.setOnClickListener(addEventListener);
        butAddEvent.setCompoundDrawablesWithIntrinsicBounds(ThemeHelper.get_icon50_add(), 0, 0, 0);
    }

    private void initCalendar() {
        globalCalendar = Calendar.getInstance();
        globalCalendar.set(MonthActivity.currentYear, MonthActivity.currentMonth, MonthActivity.selectedDay);

        monthInfo = (TextView) findViewById(R.id.month_info);
        monthInfo.setText(getMonthName(globalCalendar));
    }

    @SuppressLint("NewApi")
    private String getMonthName(Calendar calendar) {
        if (Locale.getDefault().toString().equals("pl_PL") || Locale.getDefault().toString().equals("pl")) {
            return getResources().getStringArray(R.array.months)[calendar.get(Calendar.MONTH)] + " " + currentYear;
        } else
            return calendar.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()) + " " + currentYear;
    }

    private void initCalendarIcons() {
        arrayListIcons = new ArrayList<Integer>();
        eventsList.clear();
        pillsList.clear();
        PillsDatabaseHandler db = new PillsDatabaseHandler(this);
        if (!db.isEmpty()) {
            pillsList.addAll(db.getAllPills(false));
        }

        DatabaseHandler database = new DatabaseHandler(context);
        eventsList.addAll(database.getAllEvents());
    }

    @Override
    public void refreshView() {
        initCalendar();
        init();
        adapter.notifyDataSetChanged();
        CalendarActivity.setTab(CalendarActivity.tabHost.getCurrentTab());
    }

    private void initCalendarDayIcons(int day) {
        ArrayList<Integer> iconTmp = new ArrayList<Integer>(arrayListIcons);
        iconTmp.remove((Object) ThemeHelper.get_icon50_menu_event());
        arrayListIcons = new ArrayList<Integer>(iconTmp);
        if (!eventsList.isEmpty()) {
            for (Events event : eventsList) {
                if (DateTimeConvert.compareDate(context, event.getDate(),
                        currentYear, currentMonth,
                        day)) {
                    arrayListIcons.add(ThemeHelper.get_icon50_menu_event());
                    break;
                }
            }
        }

        ArrayList<Integer> iconPillsTmp = new ArrayList<Integer>(arrayListIcons);
        iconPillsTmp.remove((Object) ThemeHelper.get_icon50_menu_pill());
        arrayListIcons = new ArrayList<Integer>(iconPillsTmp);
        if (!pillsList.isEmpty()) {
            for (Pills pill : pillsList) {
                if (DateTimeConvert.compareDate(context, pill.getmDateTime(),
                        currentYear, currentMonth,
                        day)) {
                    arrayListIcons.add(ThemeHelper.get_icon50_menu_pill());
                    break;
                }
            }
        }
    }

    public int getDaysInMonth(int monthNumber, int year) {
        int days = 0;
        if (monthNumber >= 0 && monthNumber < 12) {
            try {
                Calendar calendar = Calendar.getInstance();
                int date = 1;
                calendar.set(year, monthNumber, date);
                days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return days;
    }

    private void calendarDays() {
        initCalendarIcons();

        Calendar calendar = globalCalendar;
        int monthNr = currentMonth;
        int yearNr = calendar.get(Calendar.YEAR);
        int dayCount = getDaysInMonth(monthNr, yearNr);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        int dayOfTheWeek = calendar.get(Calendar.DAY_OF_WEEK);
        dayOfTheWeek -= 2;
        if (dayOfTheWeek == -1)
            dayOfTheWeek = 6;

        int prevMonthDayCount = getPreviousMonthDaysCount();
        int currentDay = getCurrentDayNumber();
        previousDayCount = 0;

        days = new ArrayList<SimpleDialogItem>();
        SimpleDialogItem item;
        for (int i = 0; i < dayOfTheWeek; i++) {
            item = new SimpleDialogItem(false, String.valueOf(prevMonthDayCount - dayOfTheWeek + i + 1));
            days.add(item);
            previousDayCount++;
        }

        for (int i = 1; i <= dayCount; i++) {
            if (i == currentDay && currentMonth == Calendar.getInstance().get(Calendar.MONTH) && currentYear == Calendar.getInstance().get(Calendar.YEAR))
                item = new SimpleDialogItem(true, true, String.valueOf(i));
            else
                item = new SimpleDialogItem(true, String.valueOf(i));

            if (currentMonth == Calendar.getInstance().get(Calendar.MONTH) && currentYear == Calendar.getInstance().get(Calendar.YEAR)) {
                initCalendarDayIcons(i);
                item.setIcons(arrayListIcons);
            } else if (currentMonth > Calendar.getInstance().get(Calendar.MONTH)) {
                initCalendarDayIcons(i);
                item.setIcons(arrayListIcons);
            } else if (currentYear > Calendar.getInstance().get(Calendar.YEAR)) {
                initCalendarDayIcons(i);
                item.setIcons(arrayListIcons);
            }

            days.add(item);
        }

        for (int i = 1; i <= 42 - dayCount - dayOfTheWeek; i++) {
            item = new SimpleDialogItem(false, String.valueOf(i));
            days.add(item);
        }
    }

    private int getPreviousMonthDaysCount() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(MonthActivity.currentYear, MonthActivity.currentMonth, MonthActivity.selectedDay);
        int monthNr = currentMonth;

        if (monthNr == Calendar.JANUARY) {
            calendar.add(Calendar.MONTH, -1);
        } else {
            calendar.add(Calendar.MONTH, -1);
        }
        return getDaysInMonth(calendar.get(Calendar.MONTH), calendar.get(Calendar.YEAR));
    }

    private int getCurrentDayNumber() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    @SuppressLint("NewApi")
    private void calendarDaysName() {
        Calendar cal = globalCalendar;

        daysName = new ArrayList<SimpleDialogItem>();
        for (int i = 2; i <= 8; i++) {
            if (i == 8)
                cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
            else
                cal.set(Calendar.DAY_OF_WEEK, i);
            daysName.add(new SimpleDialogItem(cal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault())));
        }
    }

    private OnClickListener chooseMonthListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.month_left) {
                if (currentMonth == 0) {
                    currentMonth = 11;
                    currentYear--;
                    globalCalendar.set(Calendar.YEAR, currentYear);
                } else
                    currentMonth--;
            } else if (v.getId() == R.id.month_right) {
                if (currentMonth == 11) {
                    currentMonth = 0;
                    currentYear++;
                    globalCalendar.set(Calendar.YEAR, currentYear);
                } else
                    currentMonth++;
            }

            globalCalendar.set(Calendar.MONTH, currentMonth);
            monthInfo.setText(getMonthName(globalCalendar));
            gridView.startAnimation(slideRight);
            calendarDays();
            adapter = new MonthAdapter(context, R.layout.month_gridview_item, days);
        }
    };

    private OnClickListener addEventListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            addEventDialog = new AddEventDialog(context, monthActivity);
            addEventDialog.show();
        }
    };

    private OnItemClickListener dayClickListener = new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                                long arg3) {
            if (position < previousDayCount) {
                monthLeft.performClick();
            } else if (position >= (getDaysInMonth(globalCalendar.get(Calendar.MONTH), globalCalendar.get(Calendar.YEAR)) + previousDayCount)) {
                monthRight.performClick();
            } else {
                if (selectedDay == position - previousDayCount + 1) {
                    CalendarActivity.setTab(2);
                } else {
                    selectedDay = position - previousDayCount + 1;

                    ViewGroup gridChild = (ViewGroup) gridView.getChildAt(position);
                    if (selectedGridViewItem != -1) {
                        ViewGroup gc = (ViewGroup) gridView.getChildAt(selectedGridViewItem);
                        gc.getChildAt(0).setBackgroundResource(ThemeHelper.get_component_cell_off());
                    }
                    gridChild.getChildAt(0).setBackgroundResource(ThemeHelper.get_component_cell_on());
                    selectedGridViewItem = position;
                }
            }
        }
    };

    private OnClickListener todayListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            boolean change = false;
            Calendar cal = Calendar.getInstance();
            if (selectedDay != getCurrentDayNumber()) {
                selectedDay = getCurrentDayNumber();
                globalCalendar.set(Calendar.DAY_OF_MONTH, selectedDay);
            }

            if (currentMonth != cal.get(Calendar.MONTH)) {
                currentMonth = cal.get(Calendar.MONTH);
                globalCalendar.set(Calendar.MONTH, currentMonth);
                change = true;
            }

            if (currentYear != cal.get(Calendar.YEAR)) {
                currentYear = cal.get(Calendar.YEAR);
                globalCalendar.set(Calendar.YEAR, currentYear);
                change = true;
            }

            if (change) {
                monthInfo.setText(getMonthName(globalCalendar));
                calendarDays();
                adapter = new MonthAdapter(context, R.layout.month_gridview_item, days);
                gridView.setAdapter(adapter);
            }

            gridView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    ViewGroup gridChild = (ViewGroup) gridView.getChildAt(selectedDay + previousDayCount - 1);
                    if (selectedGridViewItem != -1) {
                        ViewGroup gc = (ViewGroup) gridView.getChildAt(selectedGridViewItem);
                        gc.getChildAt(0).setBackgroundResource(ThemeHelper.get_component_cell_off());
                    }
                    gridChild.getChildAt(0).setBackgroundResource(ThemeHelper.get_component_cell_on());
                    selectedGridViewItem = selectedDay + previousDayCount - 1;
                }
            }, 100);
        }
    };

    private OnTouchListener notScrollListener = new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_MOVE) {
                return true;
            }
            return false;
        }
    };

    private final Runnable mRunnable = new Runnable() {
        public void run() {
            gridView.setAdapter(adapter);
            gridView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    ViewGroup gridChild = (ViewGroup) gridView.getChildAt(selectedDay + previousDayCount - 1);
                    if (selectedGridViewItem != -1) {
                        ViewGroup gc = (ViewGroup) gridView.getChildAt(selectedGridViewItem);
                        if (gc != null)
                            gc.getChildAt(0).setBackgroundResource(ThemeHelper.get_component_cell_off());
                    }
                    if (gridChild != null)
                        gridChild.getChildAt(0).setBackgroundResource(ThemeHelper.get_component_cell_on());
                    selectedGridViewItem = selectedDay + previousDayCount - 1;
                }
            }, 100);
        }
    };

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putInt("year", MonthActivity.currentYear);
        savedInstanceState.putInt("month", MonthActivity.currentMonth);
        savedInstanceState.putInt("day", MonthActivity.selectedDay);

        if (addEventDialog != null) {
            if (addEventDialog.isShowing()) {
                savedInstanceState.putBoolean("dialogAdd", true);
                savedInstanceState.putInt("numberOfScreen", addEventDialog.getNumberOfScreen());
                savedInstanceState.putStringArrayList("data", addEventDialog.getData());
                savedInstanceState.putString("title", addEventDialog.getTitle());
            }
        }
    }
}