package ai.pai.lensman.session;

import android.os.AsyncTask;

import com.android.common.executors.ThreadExecutor;
import com.android.common.utils.LogHelper;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;

import ai.pai.lensman.bean.PhotoBean;
import ai.pai.lensman.bean.SessionBean;
import ai.pai.lensman.box.BoxUrlContainer;
import ai.pai.lensman.utils.Constants;
import ai.pai.lensman.utils.HttpPostTask;

public class SessionInteractor {

    private SessionBean sessionBean;
    private Timer timer;
    private SessionListener listener;
    private HttpPostTask sessionStartTask;
    private HttpPostTask sessionEndTask;

    private static final String TAG = "SessionInteractor";

        public SessionInteractor(SessionBean sessionBean, SessionListener listener) {
        this.listener = listener;
        this.sessionBean = sessionBean;
    }

    public interface SessionListener {

        void onSessionStartSuccess(String session);
        void onSessionStartError(String session);
        void onSessionPhotoCaptured(PhotoBean bean);
        void onSessionEnd(String session);
    }

    public void startSession(){
        cancelTask(sessionStartTask);
        HashMap<String,String> params = new HashMap<>();
        params.put("lensman",sessionBean.lensmanId);
        params.put("session",sessionBean.sessionId);
        sessionStartTask = new HttpPostTask(params){
            @Override
            protected boolean parseResponse(String response) {
                LogHelper.d(TAG,"startSession get response string = "+response);
                try{
                    JSONObject json = new JSONObject(response);
                    int status = json.getInt("status");
                    if(status == 200){
                        return true;
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
                return false;
            }

            @Override
            protected void onPostFail() {
                super.onPostFail();
                listener.onSessionStartError(sessionBean.sessionId);
            }

            @Override
            protected void onPostSuccess() {
                super.onPostSuccess();
                listener.onSessionStartSuccess(sessionBean.sessionId);
                startCapture();
            }
        };
        sessionStartTask.executeOnExecutor(ThreadExecutor.getInstance().getExecutor(), BoxUrlContainer.SESSION_START_URL);
    }

    public void startCapture() {
        if(timer!=null){
            timer.cancel();
            timer = null;
        }
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                fetchThumbnailTask();
            }
        },1000,5000);
    }

    private void fetchThumbnailTask(){
        HashMap<String,String> params = new HashMap<>();
        params.put("lensman",sessionBean.lensmanId);
        params.put("session",sessionBean.sessionId);
        HttpPostTask fetchThumbnailTask = new HttpPostTask(params){
            ArrayList<PhotoBean> photoList = new ArrayList<>();
            @Override
            protected boolean parseResponse(String response) {
                LogHelper.d(TAG,"fetchThumbnailTask get response string = "+response);
                try{
                    JSONObject json = new JSONObject(response);
                    int status = json.getInt("status");
                    if(status == 200){
                        JSONObject data = json.getJSONObject("data");
                        JSONArray files = data.getJSONArray("files");
                        if(files!=null && files.length()>0){
                            for(int k = 0 ; k< files.length();k++){
                                JSONObject file = files.getJSONObject(k);
                                PhotoBean bean = new PhotoBean();
                                bean.photoName = file.getString("name");
                                bean.photoId = file.getLong("id");
                                bean.photoPath = file.getString("path");
                                bean.captureTime = bean.photoId;
                                bean.isRawPhoto = false;
                                bean.isUploaded = false;
                                bean.sessionId = sessionBean.sessionId;
                                bean.lensmanId = sessionBean.lensmanId;
                                bean.sessionSeq = sessionBean.sessionSeq;
                                bean.sessionDate = sessionBean.sessionDate;
                                photoList.add(bean);
                            }
                        }else{
                            //TODO for test
                            PhotoBean bean = new PhotoBean();
                            long milisec = System.currentTimeMillis();
                            bean.photoName = milisec+".jpg";
                            bean.photoId = milisec;
                            bean.photoPath = "http://e.hiphotos.baidu.com/image/h%3D200/sign=31e61d6532f33a87816d071af65d1018/95eef01f3a292df504213240b4315c6035a87381.jpg";
                            bean.captureTime = bean.photoId;
                            bean.isRawPhoto = false;
                            bean.isUploaded = false;
                            bean.sessionId = sessionBean.sessionId;
                            bean.lensmanId = sessionBean.lensmanId;
                            bean.sessionSeq = sessionBean.sessionSeq;
                            bean.sessionDate = sessionBean.sessionDate;
                            photoList.add(bean);
                        }
                        return true;
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
                return false;
            }

            @Override
            protected void onPostFail() {
                super.onPostFail();
            }

            @Override
            protected void onPostSuccess() {
                super.onPostSuccess();
                for(PhotoBean bean :photoList){
                    new SavePhotoTask(bean).executeOnExecutor(ThreadExecutor.getInstance().getExecutor(),bean);
                }
            }
        };
        fetchThumbnailTask.executeOnExecutor(ThreadExecutor.getInstance().getExecutor(), BoxUrlContainer.FETCH_THUMBNAIL_URL);
    }


    class SavePhotoTask extends AsyncTask<PhotoBean, Integer, Boolean> {

        private PhotoBean photoBean;
        public SavePhotoTask(PhotoBean bean){
            this.photoBean = bean;
        }

        @Override
        protected Boolean doInBackground(PhotoBean... params) {
            PhotoBean photoBean = params[0];
            String  path = BoxUrlContainer.PHOTO_PATH_PREFIX_URL+photoBean.photoPath;
            //TODO for test
            if(photoBean.photoPath.contains("baidu")){
                path = photoBean.photoPath;
            }
            LogHelper.d(TAG,"保存照片到本地，图片链接地址为"+path);
            FileOutputStream fOut = null;
            HttpURLConnection conn = null;
            InputStream inStream = null;
            try {
                URL url = new URL(path);
                conn = (HttpURLConnection) url.openConnection();
                conn.setConnectTimeout(5 * 1000);
                conn.setRequestMethod("GET");
                inStream = conn.getInputStream();
                if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
                    String dirPath = Constants.APP_IMAGE_DIR +File.separator+photoBean.sessionId+File.separator+Constants.THUMBNAIL_DIR_NAME;
                    File dir = new File(dirPath);
                    dir.mkdirs();
                    File file = new File(dir, photoBean.photoName);
                    fOut = new FileOutputStream(file);
                    byte[] buffer = new byte[2048];
                    int len ;
                    while((len=inStream.read(buffer))!=-1){
                        fOut.write(buffer,0,len);
                        fOut.flush();
                    }
                    fOut.flush();
                    LogHelper.d(TAG,"保存照片到本地，图片保存至"+file.getAbsolutePath()+"图片大小为"+file.length()+"字节\n\n");
                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try{
                    inStream.close();
                    conn.disconnect();
                    fOut.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            return false;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if (result) {
                listener.onSessionPhotoCaptured(photoBean);
            }else{
                new SavePhotoTask(photoBean).executeOnExecutor(ThreadExecutor.getInstance().getExecutor(),photoBean);
            }
        }
    }


    public void endSession(){
        cancelTask(sessionEndTask);
        HashMap<String,String> params = new HashMap<>();
        params.put("lensman",sessionBean.lensmanId);
        params.put("session",sessionBean.sessionId);
        sessionEndTask = new HttpPostTask(params);
        sessionEndTask.executeOnExecutor(ThreadExecutor.getInstance().getExecutor(), BoxUrlContainer.SESSION_END_URL);
        if(timer!=null){
            timer.cancel();
            timer = null;
        }
        listener.onSessionEnd(sessionBean.sessionId);
    }

    public void deletePhoto(){
        HashMap<String,String> params = new HashMap<>();
        params.put("lensman",sessionBean.lensmanId);
        params.put("session",sessionBean.sessionId);
        HttpPostTask deleteTask = new HttpPostTask(params);
        deleteTask.executeOnExecutor(ThreadExecutor.getInstance().getExecutor(), BoxUrlContainer.DELETE_PHOTO_URL);
    }

    private void cancelTask(HttpPostTask task){
        if(task==null){
            return;
        }
        if(task.getStatus()== AsyncTask.Status.RUNNING){
            task.cancel(true);
        }
    }

}
