package com.zhaohaoting.framework.abs;

import android.content.pm.PackageManager;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.zhaohaoting.framework.R;
import com.zhaohaoting.framework.abs.contract.BaseContract;
import com.zhaohaoting.framework.mvchelper.task.TaskHelper;
import com.zhaohaoting.framework.ui.dialog.loading.LoadingDialog;
import com.zhaohaoting.framework.utils.DensityUtil;
import com.zhaohaoting.framework.utils.ToastUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by zhaohaoting on 2015/7/16.
 * desc:
 */
public abstract class AbsDialogFragment<PRESENTER extends BaseContract.BasePresenter> extends DialogFragment implements BaseContract.BaseView {
    public final String TAG = this.getClass().getSimpleName();
    protected boolean isVisible = false;
    protected PRESENTER presenter;
    protected TaskHelper taskHelper;
    protected View contentView;
    /**
     * databinding
     */
    protected ViewDataBinding rootDataBinding;
    public BaseActivity activity;
    protected int statusBarHeight;
    protected LoadingDialog loadingDialog;
    protected FragmentManager fragmentManager;
    protected Bundle savedInstanceStat;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        PRESENTER presenter = getPresenter();
        if (presenter != null) {
            getLifecycle().addObserver(presenter);//添加LifecycleObserver
        }
        getLifecycle().addObserver(getTaskHelper());
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        isVisible = isVisibleToUser;
    }

    protected void initStatus() {
    }

    @Override
    public void onStart() {
        super.onStart();
        getDialog().getWindow().setBackgroundDrawableResource(R.color.transparent);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        activity = (BaseActivity) getActivity();
        this.savedInstanceStat = savedInstanceState;
        initStatus();
        if (contentView == null) {
            rootDataBinding = DataBindingUtil.inflate(inflater, getLayoutResId(), container, false);
            contentView = rootDataBinding.getRoot();
            loadingDialog = new LoadingDialog(getActivity());
            statusBarHeight = DensityUtil.getStatusBarHeight(activity);
            fragmentManager = getChildFragmentManager();
            initialize();
        }
        return contentView;
    }

    protected abstract void initialize();

    private boolean isHidden = true;//当前页面是否隐藏
    private boolean isLoad = false;//当前页面是否刷新过数据(freshUI)

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        isHidden = hidden;
        if (!hidden) {
            initStatus();
            freshUI();
            isLoad = true;
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        isHidden = true;
    }

    @Override
    public void onResume() {
        super.onResume();
        if (isHidden && !isLoad) {
            freshUI();
            isLoad = false;
            isHidden = false;
        }
    }


    public void freshUI() {

    }

    protected PRESENTER getPresenter() {
        if (presenter == null) {
            presenter = initPresenter();
        }
        return presenter;
    }

    protected abstract PRESENTER initPresenter();

    @Override
    public TaskHelper getTaskHelper() {
        if (taskHelper == null) {
            taskHelper = new TaskHelper();
        }
        return taskHelper;
    }

    @Override
    public void showLoading(Object... task) {
        loadingDialog.show();
        if (task != null && task.length > 0)
            loadingDialog.setOnDismissListener(dialog -> getTaskHelper().cancel(task));
    }

    @Override
    public void dismissLoading(Object... task) {
        loadingDialog.dismiss();
    }

    private Handler handler;

    protected final void postRunnable(final Runnable runnable) {
        getHandler().post(new Runnable() {
            @Override
            public void run() {
                // validate
                // TODO use getActivity ?
                if (!isAdded()) {
                    return;
                }

                // run
                runnable.run();
            }
        });
    }

    public Handler getHandler() {
        if (handler == null) handler = new Handler();
        return handler;
    }

    protected final void postDelayed(final Runnable runnable, long delay) {
        getHandler().postDelayed(new Runnable() {
            @Override
            public void run() {
                // validate
                // TODO use getActivity ?
                if (!isAdded()) {
                    return;
                }

                // run
                runnable.run();
            }
        }, delay);
    }

    private List<String> permissionsList = new ArrayList<>();

    public void judgePermission(int requestCode, String... permissions) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            permissionsList.clear();
            for (String permission : permissions) {
                if (getActivity().checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                    permissionsList.add(permission);
                }
            }
            if (permissionsList.size() == 0) {
                requestPermissionSuccess(requestCode);
            } else {
                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), requestCode);
            }
        } else {
            requestPermissionSuccess(requestCode);
        }
    }

    @Override
    public void onRequestPermissionsResult(final int requestCode, String[] permissions, int[] grantResults) {
        for (int i = 0; i < grantResults.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                requestPermissionFailure(requestCode);
                ToastUtils.show(getResources().getString(R.string.need_permission));
                return;
                // 用户不同意，却还要展示 向用户展示该权限作用
//                if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {
//                    if (customDialog == null) {
//                        customDialog = UIutils.showCustomDialog(this, getString(R.string.tips), getResources().getString(R.string.need_permission), true)
//                                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
//                                    @Override
//                                    public void onClick(DialogInterface dialog, int which) {
//                                        getPermissionSuccess(requestCode,false);
//                                    }
//                                })
//                                .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
//                                    @Override
//                                    public void onClick(DialogInterface dialog, int which) {
//                                        getPermissionSuccess(requestCode,false);
//                                    }
//                                }).create();
//                        customDialog.show();
//                    }
//                    return;
//                }
            }
        }
        requestPermissionSuccess(requestCode);
    }

    /**
     * 成功获取权限
     *
     * @param requestCode
     */
    public void requestPermissionSuccess(int requestCode) {
    }

    /**
     * 获取权限失败
     *
     * @param requestCode
     */
    public void requestPermissionFailure(int requestCode) {

    }

    private List<AbsV4Fragment> fragments = new ArrayList<>();

    protected void addFragment(AbsV4Fragment fragment, int container) {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        for (AbsV4Fragment currentFragment : fragments) {
            if (currentFragment.isAdded()) {
                fragmentTransaction.hide(currentFragment);
            }
        }
        if (fragment.isAdded()) {
            fragmentTransaction.show(fragment).commitAllowingStateLoss();
        } else {
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.add(container, fragment).commitAllowingStateLoss();
            fragments.add(fragment);
        }
    }

    protected void clearFragment() {
        while (fragmentManager.getBackStackEntryCount() != 0) {
            fragmentManager.popBackStackImmediate();
        }
    }

    public void show(FragmentManager manager) {
        try {
            Field mDismissed = DialogFragment.class.getDeclaredField("mDismissed");
            Field mShownByMe = DialogFragment.class.getDeclaredField("mShownByMe");
            mDismissed.setAccessible(true);
            mDismissed.set(this, false);
            mShownByMe.setAccessible(true);
            mShownByMe.set(this, true);
            FragmentTransaction fragmentTransaction = manager.beginTransaction();
            fragmentTransaction.add(this, "TipDialog");
            fragmentTransaction.commitAllowingStateLoss();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        try {
            Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (rootDataBinding != null)
            rootDataBinding.unbind();
    }

    public abstract int getLayoutResId();
}