package com.fxy.common;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Message;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

import com.elvishew.xlog.XLog;
import com.fxy.R;
import com.fxy.adapter.GridImageAdapter;
import com.fxy.baselibrary.bean.BaseEventBusBean;
import com.fxy.baselibrary.util.DateUtil;
import com.fxy.baselibrary.util.JsonUtil;
import com.fxy.baselibrary.util.RxTimeTool;
import com.fxy.bean.ActionBean;
import com.fxy.constant.EventCode;
import com.fxy.constant.SPCache;
import com.fxy.net.MyDialogCallback;
import com.fxy.realm.AsyncUploadRealm;
import com.fxy.utils.UploadUtils;
import com.fxy.view.FullyGridLayoutManager;
import com.google.gson.Gson;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.permissions.Permission;
import com.luck.picture.lib.permissions.RxPermissions;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.model.Response;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONObject;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import io.reactivex.functions.Consumer;
import io.realm.Realm;
import io.realm.RealmQuery;
import io.realm.RealmResults;

public class AsyncPictureUpload {
    private final Activity mActivity;
    private final Context mContext;


    private String uploadType = "";
    //文件上传类型
    protected String fileKey = "";

    //通知地址
    private String notifyUrl = "";

    //唯一标识
    private String uniqueTag = "";

    //通知地址
    private HashMap<String, Object> notifyParam  = new HashMap<>();


    private HashMap<String, Object> limitOperate  = new HashMap<>();

    protected Realm mRealm;
    private List<AsyncUploadRealm> awaitUploadList=new ArrayList<>();


    //
    private List<LocalMedia> selectList = new ArrayList<>();
    //上传图片路径
    private ArrayList<String> ossPhotoList =new ArrayList<>();

    private String mPrefix="tally";

    //是否停止上传
    private String resourceUrl = "";

    private String resourceType = "";

    private String resourcePrefix = "/fxy";

    private OssService ossService;

    private CosService cosService;

    private boolean allowUpload = true;

    //
    private boolean isAllRePush =false;

    private boolean debug = false;
    public void setDebug(boolean debug) {
        this.debug = debug;
    }
    public AsyncPictureUpload(Activity activity){
        mActivity = activity;
        mContext  = activity.getBaseContext();
        initData();
    }



    private void initData() {
        SPCache spCache = SPCache.getInstance(mContext);
        resourceUrl    = spCache.getResourceHost()+"/";
        resourceType   = spCache.getResourceType();
        resourcePrefix = spCache.getResourcePrefix();
        mRealm = Realm.getDefaultInstance();
        if (mActivity != null && mActivity.getClass()!=null){
            uploadType = mActivity.getClass().getSimpleName();
        }

        limitOperate = new HashMap<>();
        uniqueTag =  this.fileKey+UUID.randomUUID().toString();
    }



    public void setUploadType(String fileKey) {
        this.fileKey = fileKey;
    }



    public void  setNotifyParam( HashMap<String, Object> map){
        this.notifyParam = map;
    }

    //操作限制
    public void setLimitOperate(HashMap<String, Object> map){
        this.limitOperate = map;
    }



    public int getAwaitNum(){
        RealmResults<AsyncUploadRealm> realmResults  = mRealm.where(AsyncUploadRealm.class)
                .equalTo("isDelete",0)
                .equalTo("pushStatus",0)
                .equalTo("uploadType",uploadType)
                .sort("pushStatus").findAll();
        realmResults.load();
        return  realmResults.size();
    }
    public int getAwaitNum(String[] uploadTypeList){
        RealmResults<AsyncUploadRealm> realmResults  = mRealm.where(AsyncUploadRealm.class)
                .equalTo("isDelete",0)
                .equalTo("pushStatus",0)
                .in("uploadType",uploadTypeList)
                .sort("pushStatus").findAll();
        realmResults.load();
        return  realmResults.size();
    }

    /**
     * 获取待上传数量
     * @return
     */
    public int getAwaitUploadListNum(){
        return  awaitUploadList.size();
    }

    /**
     * 获取所有待推送数据
     * @return
     */
    public int getAllAwaitNum(){

        if (isAllRePush){
            Integer[] pushStatus = {0,1};
            RealmResults<AsyncUploadRealm> realmResults  = mRealm.where(AsyncUploadRealm.class)
                    .equalTo("isDelete",0)
                    .in("pushStatus",pushStatus)
                    .sort("pushStatus").findAll();
            realmResults.load();
            return  realmResults.size();
        }else{
            RealmResults<AsyncUploadRealm> realmResults  = mRealm.where(AsyncUploadRealm.class)
                    .equalTo("isDelete",0)
                    .equalTo("pushStatus",0)
                    .sort("pushStatus").findAll();
            realmResults.load();
            return  realmResults.size();
        }

    }

    /**
     * 返回错误数量
     * @return int
     */
    public int getFailNum(){
        Integer[] pushStatus = {1};
        RealmResults<AsyncUploadRealm> realmResults  = mRealm.where(AsyncUploadRealm.class)
                .equalTo("isDelete",0)
                .in("pushStatus",pushStatus)
                .sort("pushStatus").findAll();
        realmResults.load();
        return  realmResults.size();
    }


    @SuppressLint("HandlerLeak")
    private Handler uploadHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            HashMap<String,Object> hashMap = new HashMap<>();
            hashMap.put("fileKey",fileKey);

             try {

                //XLog.e(msg);
                int current = (Integer) msg.arg1;

                switch (msg.what){
                    case 0:
                        Toast.makeText(mActivity, "error", Toast.LENGTH_SHORT).show();
                        break;
                    case 1://失败

                        if (awaitUploadList.size()>0){

                            AsyncUploadRealm asyncUploadRealm = awaitUploadList.get(current);
                            awaitUploadList.remove(current);
                            resultUpload(asyncUploadRealm.getId(),0,"");
                            String message = (String) msg.obj;
                            if (!message.isEmpty() && mActivity!=null){
                                Toast.makeText(mActivity, message, Toast.LENGTH_SHORT).show();
                            }
                            hashMap.put("error",(String) msg.obj);
                            hashMap.put("result","error");
                            hashMap.put("realmId",asyncUploadRealm.getId());
                        }

                        break;
                    case 2://成功
                         //表示数据存在
                        if (awaitUploadList.size()>0){
                            AsyncUploadRealm asyncUploadRealm = awaitUploadList.get(current);
                            awaitUploadList.remove(current);
                            resultUpload(asyncUploadRealm.getId(),1,(String) msg.obj);
                            hashMap.put("result","success");
                            hashMap.put("realmId",asyncUploadRealm.getId());
                        }
                        break;
                    case 3:
                        //设置进度条
                        hashMap.put("result","process");
                        hashMap.put("process",(int)msg.arg2);
                        if (awaitUploadList.get(current)!=null){
                            hashMap.put("realmId",awaitUploadList.get(current).getId());
                        }

                        EventBus.getDefault().post(new BaseEventBusBean<>(EventCode.file_upload_progress_lister,hashMap));
                        return;
                    case 4:
                        //获取上传状态
                        return;
                    default:
                        break;
                }




            } catch (Exception e) {
                XLog.e(e.getMessage());
                e.printStackTrace();
                // 通过接口对象传上传状态
                hashMap.put("error",e.getMessage());
            }

             EventBus.getDefault().post(new BaseEventBusBean<>(EventCode.file_upload_lister,hashMap));
        }
    };




    // 调用回调方法
    //uploadChangeListener.uploadResult(false);

    public void filedUpload(int num){


        // 例如 LocalMedia 里面返回三种path
        // 1.media.getPath(); 为原图path
        // 2.media.getCutPath();为裁剪后path，需判断media.isCut();是否为true
        // 3.media.getCompressPath();为压缩后path，需判断media.isCompressed();是否为true
        // 如果裁剪并压缩了，以取压缩路径为准，因为是先裁剪后压缩的
        LocalMedia localMedia = awaitUploadList.get(num).getLocalMedia();
        String urlPath =localMedia.getPath();
        if (urlPath.isEmpty()){
            setPushStatus(awaitUploadList.get(num).getId(),1,1);
            Message msg = new Message();
            msg.obj = "文件路径不为空";
            msg.what = 1;
            uploadHandler.sendMessage(msg);

            return;
        }

        if (localMedia.isCompressed() && localMedia.getCompressPath()!=null){
            if (new File(localMedia.getCompressPath()).exists()){
                urlPath = localMedia.getCompressPath();
            }
        }

        if (!new File(urlPath).exists()){
            XLog.d("文件不存在本地路径"+urlPath+",拍照时间："+awaitUploadList.get(num).getCreateTime());
            setPushStatus(awaitUploadList.get(num).getId(),1,1);
            Message msg = new Message();
            msg.obj = "文件路径不存在";
            msg.what = 1;
            uploadHandler.sendMessage(msg);
            return;
        }


        String fileName = "";
        String path_prefix = "";

        String ossUrl = awaitUploadList.get(num).getOssUrl();
        fileKey = awaitUploadList.get(num).getNotifyKey();
        if (!ossUrl.isEmpty()){

            String[] urlArr = ossUrl.split("/");
            fileName = urlArr[urlArr.length-1];

            //用户循环路径
            for (int i = 0; i <urlArr.length -1  ; i++) {
                if (!urlArr[i].isEmpty()){
                    path_prefix =   path_prefix.concat(urlArr[i]).concat("/");
                }
            }


        }else{
            path_prefix = resourcePrefix + "/android/" + mPrefix + "/" + RxTimeTool.getYestoryDate("yyyyMMd") + "/";
            String fileSuffix = urlPath.lastIndexOf(".")>-1 ? urlPath.substring(urlPath.lastIndexOf(".")) : "";
            fileName = UUID.randomUUID().toString() + fileSuffix;
        }


        if (resourceType.equals("tencent")){
            if (cosService==null){
                cosService  = new CosService(mActivity.getBaseContext(), path_prefix.toString());
            }
            //new cosThread(urlPath, fileName , num).start();
            cosService.cosUpload(urlPath, fileName , num,uploadHandler, path_prefix.toString());

        }else{
            if (ossService ==null){
                ossService = new OssService(mActivity, path_prefix.toString());
            }
            ossService.ossUpload(urlPath, fileName , num,uploadHandler, path_prefix.toString());
            //ossService.ossUpload(urlPath, fileName , num,uploadHandler);

        }
        // task.cancel(); // 可以取消任务
        // task.waitUntilFinished(); // 可以等待直到任务完成
    }







    //存储数据问题
    private void asyncUpload(){


        if (!getIsNetwork()){
            //无网络时在请求检查是否有网络
            return;
        }

        if (awaitUploadList==null || awaitUploadList.size()==0){
            Integer[] isFinish = {0,2};
            RealmResults<AsyncUploadRealm> realmResults  = getBatchUploadRealm();
            awaitUploadList.addAll(realmResults);
        }



        if (awaitUploadList.size()>0){
            filedUpload(0);
        }
    }

    //临时处理数据用
    private void tmpData(){
        if (awaitUploadList.size()==0 && debug){

            HashMap<String,String> mapUrl= new HashMap<>();
            mapUrl.put("dd31ae2f-dd02-46b2-bfdb-eb721ea11066","/prod/fxy/android/detection/20240923/d3e5552e-344c-4c74-be91-468cbb22f22c.JPEG");

            // 使用entrySet()遍历
            for (Map.Entry<String, String> entry : mapUrl.entrySet()) {
                System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());

                String realmId = entry.getKey();
                String ossUrl = entry.getValue();
                mRealm.beginTransaction();
                RealmResults<AsyncUploadRealm> realmResults ;

                RealmQuery<AsyncUploadRealm> queryRealm =  mRealm.where(AsyncUploadRealm.class)
                        .equalTo("id",  realmId);
                realmResults = queryRealm.sort("createTime").findAll();
                for (AsyncUploadRealm item : realmResults) {
                    if (!ossUrl.isEmpty()){
                        item.setOssUrl(ossUrl);
                    }
                }
                realmResults.load();
                mRealm.commitTransaction();
                awaitUploadList.addAll(realmResults);
            }
            XLog.d("总查询"+(awaitUploadList.size())+"条历史数据");
            XLog.d(awaitUploadList);

            debug = false;
        }
    }
    public static long getNextTimestamp(int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }

    //取消任务
    public void taskCancel(){

    }

    public void setStartUpload(){
        allowUpload = true;
        asyncUpload();
        UploadUtils.delInterfaceRequestTime(mContext);
    }
    public void setIsAllRePush(){
        isAllRePush = true;
    }

    public void setStopUpload(){
        allowUpload = false;
        if(ossService !=null){
            ossService.taskCancel();
        }
        EventBus.getDefault().post(new UploadProgressEvent(0));
    }

    /**
     * 设置是否完成
     * @param realmId String
     * @param  isFinish Integer
     */
    private void setIsFinish(String realmId,Integer isFinish){
        //更新值
        mRealm.beginTransaction();
        AsyncUploadRealm myObject = mRealm.where(AsyncUploadRealm.class).equalTo("id",realmId).findFirst();
        assert myObject != null;
        myObject.setIsFinish(isFinish);
        mRealm.commitTransaction();
    }

    private void setPushStatus(String realmId,Integer pushStatus,int isDelete){
        //更新值
        mRealm.beginTransaction();
        AsyncUploadRealm myObject = mRealm.where(AsyncUploadRealm.class).equalTo("id",realmId).findFirst();
        assert myObject != null;
        myObject.setPushStatus(pushStatus);
        myObject.setIsDelete(isDelete);

        mRealm.commitTransaction();
    }


    private RealmResults<AsyncUploadRealm> getBatchUploadRealm(){
        //更新值
        mRealm.beginTransaction();
        Integer[] isFinish = {0,1,2};
        RealmResults<AsyncUploadRealm> realmResults ;
        RealmQuery<AsyncUploadRealm> queryRealm =  mRealm.where(AsyncUploadRealm.class)
                .in("isFinish",isFinish)
                .equalTo("isDelete",0);
        if (isAllRePush){
            Integer[] pushStatus = {0,1};
            queryRealm.in("pushStatus",pushStatus)
//                    .equalTo("notifyKey",fileKey)
//                    .equalTo("uploadType",uploadType)
                    ;
            isAllRePush = false;
        }else{
            queryRealm.equalTo("pushStatus",0)
//                    .equalTo("notifyKey",fileKey)
//                    .equalTo("uploadType",uploadType)
                    ;
        }
        realmResults = queryRealm.sort("createTime").findAll();


        // 遍历结果并修改
        for (AsyncUploadRealm item : realmResults) {
            item.setIsFinish(1);
        }
        realmResults.load();
        mRealm.commitTransaction();
        return realmResults;
    }



    /**
     * 上传结果
     * @param tmpRealmId String
     * @param status Integer
     * @param photoPath String
     */
    private void resultUpload(String tmpRealmId,Integer status,String photoPath){
        if (tmpRealmId!=null && !tmpRealmId.isEmpty()){

            //遍历删除
            if (awaitUploadList.size()>0){
                for (int i=0;i<awaitUploadList.size();i++){
                    if (awaitUploadList.get(i).getId().equals(tmpRealmId)){
                        awaitUploadList.remove(i);
                        break;
                    }
                }
            }


            //更新值
            mRealm.beginTransaction();
            AsyncUploadRealm myObject = mRealm.where(AsyncUploadRealm.class).equalTo("id",tmpRealmId).findFirst();
            assert myObject != null;
            int rePush = myObject.getRePush();
            int pushStatus = 2;
            if (status==0){
                pushStatus = rePush>4 ? 1 : 0;
            }

            if (myObject.getPushStatus()!=3){
                myObject.setPushStatus(pushStatus);
            }
            //已完成则不需要再更新
            if (myObject.getIsFinish() != 3){
                myObject.setIsFinish( status == 1 ? 3 : 2);
            }
            if (status == 1){
                myObject.setOssUrl(photoPath);
            }else{
                myObject.setRePush(myObject.getRePush()+1);
            }
            mRealm.commitTransaction();

        }

        allowUpload = UploadUtils.getUploadIsContinue(mContext);
        //可以允许上传
        if (allowUpload){
            //上传完，继续执行
            asyncUpload();
        }

    }

    //异步通知结果
    private void  asyncNotify(AsyncUploadRealm myObject){
        try {
            JSONObject jsonObject = new JSONObject(myObject.getNotifyParam());
            jsonObject.put(myObject.getNotifyKey(),myObject.getOssUrl());
            jsonObject.put("realm_id",myObject.getId());
            jsonObject.put("unique_tag",myObject.getUniqueTag());
            final String tmpRealmId1 = myObject.getId();
            OkGo.<String>post(myObject.getNotifyUrl()).upJson(jsonObject)
                    .execute(new MyDialogCallback(mContext, true, false) {
                        @Override
                        public void onSuccess(Response<String> response) {
                            super.onSuccess(response);
                            try {
                                ActionBean bean = JsonUtil.getObject(response.body(), ActionBean.class);
                                if(bean.code == 1){
                                    setIsFinish(tmpRealmId1,3);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                XLog.e("回传图片地址错误",e.getMessage());
                                setIsFinish(tmpRealmId1,2);
                            }
                        }
                    });
        } catch (Exception e) {
            e.printStackTrace();
            XLog.e("异步通知"+e.getMessage());

        }
    }

    /**
     * 获取当前网络
     * @return Boolean
     */
    private Boolean getIsNetwork(){
        boolean isNetwork = false;

        try {
            if (mActivity==null){
                return  isNetwork;
            }

            ConnectivityManager connectivityManager = (ConnectivityManager) mActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (connectivityManager == null) {
                //XLog.d( "无法获取ConnectivityManager实例");
                return  isNetwork;
            }
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            if (networkInfo != null) {
                //XLog.d( "当前网络状态：" + networkInfo.getState());
                isNetwork = true;
            } else {
                //XLog.d( "当前无网络连接");
                isNetwork = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return  isNetwork;
    }

    //销毁
    public void removeHandler(){
        if (uploadHandler!=null){
            uploadHandler.removeCallbacksAndMessages(null);
        }
    }
}
