package edu_cn.pku.course.fragments;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.widget.LinearLayout;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import edu_cn.pku.course.CourseInfo;
import edu_cn.pku.course.Utils;
import edu_cn.pku.course.activities.R;
import edu_cn.pku.course.activities.SplashActivity;
import edu_cn.pku.course.adapter.CourseListRecyclerViewAdapter;

public class CourseListFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

    private CoursesLoadingTask mLoadingTask = null;
    private RecyclerView mRecyclerView = null;
    private boolean showLongPressHintFlag = false;
    private SwipeRefreshLayout mCourseListSwipeContainer;
    private CourseListRecyclerViewAdapter adapter;


    public CourseListFragment() {
        // Required empty public constructor
    }

    /**
     * 传递参数用的,这里没用到。
     *
     * @return A new instance of fragment CourseListFragment.
     */
    public static CourseListFragment newInstance() {
        CourseListFragment fragment = new CourseListFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    public void showLongPressHint() {
        if (mRecyclerView == null || !mRecyclerView.isAttachedToWindow()) {
            showLongPressHintFlag = true;
            return;
        }
        Snackbar.make(mRecyclerView, "温馨提示:长按课程可以置顶", Snackbar.LENGTH_LONG)
                .setAction("我知道了", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        SharedPreferences sharedPreferences = SplashActivity.contextOfApplication.getSharedPreferences("longPressHint", Context.MODE_PRIVATE);
                        SharedPreferences.Editor editor = sharedPreferences.edit();
                        editor.putBoolean("showed", true);
                        editor.apply();
                    }
                })
                .show();
        showLongPressHintFlag = false;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        if (getArguments() != null) {
//        }
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        LinearLayout linearLayout = (LinearLayout) inflater.inflate(R.layout.fragment_course_list, container, false);
        // 查找xml文件中的对象并保存进Java变量
        mRecyclerView = linearLayout.findViewById(R.id.recycler_courses);
        mCourseListSwipeContainer = linearLayout.findViewById(R.id.course_list_swipe_container);


        // 设置动画
        LayoutAnimationController animation = AnimationUtils.loadLayoutAnimation(getContext(), R.anim.layout_animation_fall_down);
        mCourseListSwipeContainer.setLayoutAnimation(animation);
        // 设置刷新的监听类为此类(监听函数onRefresh)
        mCourseListSwipeContainer.setOnRefreshListener(this);
        mCourseListSwipeContainer.setColorSchemeColors(getResources().getColor(R.color.colorPrimary), getResources().getColor(R.color.colorAccent));

        FragmentActivity fa = getActivity();
        // 为了消除编译器Warning,需要判断一下是不是null,其实这基本上不可能出现null
        if (fa == null) {
            return linearLayout;
        }
        // 将读取已置顶课程列表的SharedPreferences传递给CourseListRecyclerViewAdapter
        SharedPreferences sharedPreferences = fa.getSharedPreferences("pinnedCourseList", Context.MODE_PRIVATE);
        adapter = new CourseListRecyclerViewAdapter(new ArrayList<CourseInfo>(), sharedPreferences, this);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        mRecyclerView.setAdapter(adapter);

        try {
            String cachedCourseList = getCachedCourseList();
            if (cachedCourseList == null)
                throw new Exception();
            updateAdapter(cachedCourseList, false);
        } catch (Exception e) {
            // 显示Loading的小动画,并在后台读取课程列表
            showLoading(true);
            mLoadingTask = new CoursesLoadingTask();
            mLoadingTask.execute((Void) null);
        }
        return linearLayout;
    }

    @Override
    public void onRefresh() {
        if (mLoadingTask == null) {
            mLoadingTask = new CoursesLoadingTask();
            mLoadingTask.execute((Void) null);
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
    private void showLoading(final boolean show) {
        // 逐渐显示mRecyclerView的小动画
        int shortAnimTime = 200;

        mRecyclerView.setVisibility(show ? View.GONE : View.VISIBLE);
        mRecyclerView.animate().setDuration(shortAnimTime).alpha(
                show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mRecyclerView.setVisibility(show ? View.GONE : View.VISIBLE);
            }
        });

        mCourseListSwipeContainer.setRefreshing(show);
    }

    private void saveCachedCourseList(String rootNodeStr) throws Exception {
        FragmentActivity fa = getActivity();
        if (fa == null) {
            throw new Exception("Unknown Error: Null getActivity()!");
        }
        SharedPreferences sharedPreferences = fa.getSharedPreferences("cached_xml", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("course_list_str", rootNodeStr);
        editor.apply();
    }

    private String getCachedCourseList() throws Exception {
        FragmentActivity fa = getActivity();
        if (fa == null) {
            throw new Exception("Unknown Error: Null getActivity()!");
        }
        SharedPreferences sharedPreferences = fa.getSharedPreferences("cached_xml", Context.MODE_PRIVATE);
        return sharedPreferences.getString("course_list_str", null);
    }

    private void updateAdapter(String rootNodeStr, boolean showAnimation) {
        Node rootNode = Utils.stringToNode(rootNodeStr);
        if (rootNode != null) {

            FragmentActivity fa = getActivity();
            if (fa == null) {
                return;
            }
            SharedPreferences sharedPreferences = fa.getSharedPreferences("pinnedCourseList", Context.MODE_PRIVATE);
            Set<String> hset = sharedPreferences.getStringSet("key", null);
            if (hset == null)
                hset = new HashSet<>();

            ArrayList<CourseInfo> courses_list = new ArrayList<>();
            NodeList nCoursesList = rootNode.getFirstChild().getChildNodes();
            for (int temp = 0; temp < nCoursesList.getLength(); temp++) {
                CourseInfo ci = new CourseInfo((Element) nCoursesList.item(temp));
                if (hset.contains(ci.getRawCourseName()))
                    ci.setPinned(1);
                courses_list.add(ci);
            }

            adapter.updateList(courses_list);
            // 显示课程列表的fancy的动画
            if (showAnimation)
                mRecyclerView.scheduleLayoutAnimation();

            if (showLongPressHintFlag)
                showLongPressHint();
        }
    }

    @SuppressLint("StaticFieldLeak")
    private class CoursesLoadingTask extends AsyncTask<Void, Void, String> {

        CoursesLoadingTask() {
        }

        @Override
        protected String doInBackground(Void... params) {
            return Utils.courseHttpGetRequest("http://course.pku.edu.cn/webapps/Bb-mobile-bb_bb60/dashboard?course_type=ALL&with_notifications=false");
        }

        @Override
        protected void onPostExecute(final String str) {
            mLoadingTask = null;
            showLoading(false);

            // 出现了错误
            if (str.startsWith(Utils.errorPrefix)) {
                if (str.equals(Utils.errorPrefix + Utils.errorPasswordIncorrect)) {
                    // 密码错误
                    try {
                        Utils.SignOut(getActivity());
                    } catch (Exception e) {
                        if (mRecyclerView.isAttachedToWindow())
                            Snackbar.make(mRecyclerView, e.getMessage(), Snackbar.LENGTH_SHORT).show();
                    }
                } else {
                    // 其他网络错误
                    if (mRecyclerView.isAttachedToWindow())
                        Snackbar.make(mRecyclerView, str, Snackbar.LENGTH_SHORT).show();
                }
            } else {
                // 解析返回的HTML
                updateAdapter(str, true);
                try {
                    saveCachedCourseList(str);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        // 没什么用的函数
        @Override
        protected void onCancelled() {
            mLoadingTask = null;
            showLoading(false);
        }
    }
}