package com.example.sleep;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.bigkoo.pickerview.builder.TimePickerBuilder;
import com.bigkoo.pickerview.listener.OnTimeSelectListener;
import com.bigkoo.pickerview.view.TimePickerView;
import com.example.sleep.calendarInfo.CustomDayView;
import com.example.sleep.database.GetRecord;
import com.example.sleep.service.GoSleepService;
import com.ldf.calendar.component.CalendarAttr;
import com.ldf.calendar.component.CalendarViewAdapter;
import com.ldf.calendar.interf.OnSelectDateListener;
import com.ldf.calendar.model.CalendarDate;
import com.ldf.calendar.view.MonthPager;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;

import static com.example.sleep.database.GetRecord.getRecord;

/**
 * 睡眠记录页面
 */
public class CalendarPage extends Activity {

    Button btn_left;
    Button btn_right;
    // 获取记录的对象
    GetRecord mGetRecord;
    // 记录数据的二维数组，用于标记每天是否有记录
    boolean[][] recordData;
    // 时间选择视图
    private TimePickerView pvTime;
    // 退出时间，用于控制双击返回键退出应用
    private long exitTime = 0;

    // 日历属性
    TextView tvYear;
    TextView tvMonth;
    CoordinatorLayout content;
    MonthPager monthPager;

    // 当前日历视图的集合
    private ArrayList<com.ldf.calendar.view.Calendar> currentCalendars = new ArrayList<>();
    // 日历视图适配器
    private CalendarViewAdapter calendarAdapter;
    // 日期选择监听器
    private OnSelectDateListener onSelectDateListener;
    // 当前日期
    private CalendarDate currentDate;
    // 是否已初始化标志
    private boolean initiated = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 设置布局文件
        setContentView(R.layout.calendar);
        // 获取记录对象
        mGetRecord = getRecord();
        // 获取日历视图
        monthPager = findViewById(R.id.calendar_view);
        // 初始化记录数据数组
        recordData = new boolean[13][];
        // 初始化视图和时间选择器
        initView();
        initTimePicker();
    }

    private void initView() {
        // 初始化记录数据，并根据每个月的天数查询是否有记录
        int dayNum;
        for (int m = 1; m <= 12; ++m) {
            if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) {
                dayNum = 31;
            } else if (m == 2) {
                dayNum = 28;
            } else {
                dayNum = 30;
            }
            recordData[m] = mGetRecord.queryByMonth(Integer.toString(m), dayNum);
        }

        // 初始化视图元素
        btn_left = findViewById(R.id.left);
        btn_right = findViewById(R.id.right);
        content = findViewById(R.id.content);
        tvYear = findViewById(R.id.show_year_view);
        tvMonth = findViewById(R.id.show_month_view);
        // 初始化当前日期
        initCurrentDate();
        // 初始化日历视图
        initCalendarView();
        // 初始化工具栏点击监听
        initToolbarClickListener();
    }

    /**
     * 初始化currentDate
     */
    private void initCurrentDate() {
        currentDate = new CalendarDate();
        // 设置年份
        tvYear.setText(String.format(getResources().getString(R.string.year), currentDate.getYear()));
        // 设置月份
        tvMonth.setText(String.format(getResources().getString(R.string.month), currentDate.getMonth()));
    }

    /**
     * 初始化CustomDayView，并作为CalendarViewAdapter的参数传入
     */
    private void initCalendarView() {
        // 初始化日历点击事件监听
        initListener();
        // 创建自定义日期视图
        CustomDayView customDayView = new CustomDayView(this, R.layout.custom_day);
        calendarAdapter = new CalendarViewAdapter(
                this,
                onSelectDateListener,
                CalendarAttr.CalendarType.MONTH,
                CalendarAttr.WeekArrayType.Monday,
                customDayView);// 创建日历视图适配器
        calendarAdapter.setOnCalendarTypeChangedListener(new CalendarViewAdapter.OnCalendarTypeChanged() {
            @Override
            // 日历类型改变时的操作
            public void onCalendarTypeChanged(CalendarAttr.CalendarType type) {
            }
        });
        // 初始化日历标记数据
        initMarkData();
        // 初始化月份切换功能
        initMonthPager();
    }

    //使用此方法回调日历点击事件
    private void initListener() {
        onSelectDateListener = new OnSelectDateListener() {
            @Override
            public void onSelectDate(CalendarDate date) {
                // 刷新点击日期的操作
                refreshClickDate(date);
                Intent i = new Intent();
                int d;
                d = date.getDay();
                if (recordData[date.month][d]) {
                    // 跳转到记录页面
                    i.setClass(CalendarPage.this, Record.class);
                    // 将日期信息传递到记录页面
                    i.putExtra("date", date.month + "-" + date.day);
                    CalendarPage.this.startActivity(i);
                } else {
                    // 提示没有记录信息
                    Toast.makeText(CalendarPage.this, "没有记录信息", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onSelectOtherMonth(int offset) {
                //偏移量 -1表示上一个月 ， 1表示下一个月
                monthPager.selectOtherMonth(offset);
            }
        };
    }

    //使用此方法初始化日历标记数据
    private void initMarkData() {
        HashMap<String, String> markData = new HashMap<>();
        //1表示红点，0表示灰点，只在日历上标注出灰点表示没有打卡的日期
        String s;
        int dayNum;
        for (int m = 1; m <= 12; m++) {
            if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) {
                dayNum = 31;
            } else if (m == 2) {
                dayNum = 28;
            } else {
                dayNum = 30;
            }
            for (int i = 1; i <= dayNum; i++) {
                if (recordData[m][i]) {
                    s = "2019-" + m + "-" + i;
                    // 标记为红点
                    markData.put(s, "1");
                }
            }
        }
        // 设置日历标记数据
        calendarAdapter.setMarkData(markData);
    }

    /**
     * 初始化monthPager，MonthPager继承自ViewPager
     */
    private void initMonthPager() {
        // 设置适配器
        monthPager.setAdapter(calendarAdapter);
        // 设置当前选中项为当天
        monthPager.setCurrentItem(MonthPager.CURRENT_DAY_INDEX);
        // 设置页面切换动画
        monthPager.setPageTransformer(false, new ViewPager.PageTransformer() {
            @Override
            public void transformPage(@NonNull View page, float position) {
                position = (float) Math.sqrt(1 - Math.abs(position));
                page.setAlpha(position);
            }
        });
        // 添加页面变化监听器
        monthPager.addOnPageChangeListener(new MonthPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // 页面滚动时的处理
            }

            @Override
            public void onPageSelected(int position) {
                // 页面选中时的处理
                currentCalendars = calendarAdapter.getPagers();
                if (currentCalendars.get(position % currentCalendars.size()) != null) {
                    CalendarDate date = currentCalendars.get(position % currentCalendars.size()).getSeedDate();
                    currentDate = date;
                    tvYear.setText(String.format(getResources().getString(R.string.year), date.getYear()));
                    tvMonth.setText(String.format(getResources().getString(R.string.month), date.getMonth()));
                }
            }
            @Override
            public void onPageScrollStateChanged(int state) {
                // 页面滚动状态改变时的处理
            }
        });
    }

    /**
     * 初始化对应功能的listener
     */
    private void initToolbarClickListener() {
        // 左按钮点击事件
        btn_left.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 切换到上一个月
                monthPager.setCurrentItem(monthPager.getCurrentPosition() - 1);
            }
        });
        // 右按钮点击事件
        btn_right.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 切换到下一个月
                monthPager.setCurrentItem(monthPager.getCurrentPosition() + 1);
            }
        });
    }

    /**
     * 初始化时间选择器
     */
    private void initTimePicker() {
        // 创建时间选择器
        pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
            @Override
            // 选中时间的回调处理
            public void onTimeSelect(Date date, View v) {
                Toast.makeText(CalendarPage.this, "设置成功！", Toast.LENGTH_SHORT).show();
                mGetRecord.updateRemind(getTime(date));
                stopGoSleepService();
                startGoSleepService();
            }
        })
                .setType(new boolean[]{false, false, false, true, true, false})// 默认全部显示
                .setCancelText("取消")//取消按钮文字
                .setSubmitText("确认")//确认按钮文字
                .setTitleSize(20)//标题文字大小
                .setTitleText("选择提醒时间")//标题文字
                .setOutSideCancelable(false)//点击屏幕，点在控件外部范围时，是否取消显示
                .isCyclic(true)//是否循环滚动
                .setTitleColor(Color.BLACK)//标题文字颜色
                .setSubmitColor(Color.BLUE)//确定按钮文字颜色
                .setCancelColor(Color.BLUE)//取消按钮文字颜色
                //.setTitleBgColor(0xFF666666)//标题背景颜色 Night mode
                //.setBgColor(0xFF333333)//滚轮背景颜色 Night mode
                .setLabel("年", "月", "日", "时", "分", "秒")//默认设置为年月日时分秒
                .isCenterLabel(false) //是否只显示中间选中项的label文字，false则每项item全部都带有label。
                .isDialog(true)//是否显示为对话框样式
                .build();

        // 设置时间选择器对话框样式
        Dialog mDialog = pvTime.getDialog();
        if (mDialog != null) {
            // 设置对话框在底部显示
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    Gravity.BOTTOM);

            params.leftMargin = 0;
            params.rightMargin = 0;
            pvTime.getDialogContainerLayout().setLayoutParams(params);

            Window dialogWindow = mDialog.getWindow();
            if (dialogWindow != null) {
                //修改动画样式
                dialogWindow.setWindowAnimations(com.bigkoo.pickerview.R.style.picker_view_slide_anim);
                dialogWindow.setGravity(Gravity.BOTTOM);
                dialogWindow.setDimAmount(0.1f);
            }
        }
    }

    private void refreshClickDate(CalendarDate date) {
        currentDate = date;
        tvYear.setText(String.format(getResources().getString(R.string.year), date.getYear()));
        tvMonth.setText(String.format(getResources().getString(R.string.month), date.getMonth()));
    }

    /**
     * 点击提醒按钮
     */
    public void onClickRemind(View v) {
        if (pvTime != null) {
            // 弹出时间选择器，传递参数过去，回调的时候则可以绑定此view
            pvTime.show(v);
        }
    }
    /**
     * 点击睡眠按钮
     */
    public void ClickSleep(View v) {
        // 跳转到MainActivity并关闭当前页面
        Intent i = new Intent();
        i.setClass(CalendarPage.this, MainActivity.class);
        CalendarPage.this.startActivity(i);
        CalendarPage.this.finish();
    }

    @Override
    // 当窗口焦点状态改变时调用，用于在应用获得焦点且未初始化时更新日历视图
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus && !initiated) {
            // 获取当天日期
            CalendarDate today = new CalendarDate();
            // 通知日历视图数据改变
            calendarAdapter.notifyDataChanged(today);
            // 设置初始化标志为true
            initiated = true;
        }
    }

    @Override
    // 按键按下事件监听，用于实现双击返回键退出应用
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
            if (System.currentTimeMillis() - exitTime > 2000) {
                // 判断两次点击返回键的时间间隔
                // 提示再次点击退出
                Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
                // 更新退出时间
                exitTime = System.currentTimeMillis();
            } else {
                // 关闭当前Activity
                finish();
                // 退出应用
                System.exit(0);
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    /**
     * 获取时间字符串
     */
    private String getTime(Date date) {
        return new SimpleDateFormat("HH:mm", Locale.getDefault()).format(date);
    }

    /**
     * 启动后台服务
     */
    public void startGoSleepService() {
        Intent ifSleepIntent = new Intent(this, GoSleepService.class);
        this.startService(ifSleepIntent);
    }

    /**
     * 停止后台服务
     */
    public void stopGoSleepService() {
        Intent ifSleepIntent = new Intent(this, GoSleepService.class);
        this.stopService(ifSleepIntent);
    }

    /**
     * 销毁Activity
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}