package com.efounder.chat.http.download;

import android.content.Context;

import com.alibaba.fastjson.util.IOUtils;
import com.efounder.chat.db.FileEntity;
import com.efounder.chat.item.ChatTipsMessageItem;
import com.efounder.chat.item.FileMessageItem;
import com.efounder.chat.struct.MessageChildTypeConstant;
import com.efounder.chat.struct.StructFactory;
import com.efounder.chat.utils.ThreadPoolUtils;
import com.efounder.constant.EnvironmentVariable;
import com.efounder.frame.utils.Constants;
import com.efounder.message.manager.JFMessageManager;
import com.efounder.message.struct.IMStruct002;
import com.efounder.util.AppContext;

import net.sf.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

import static com.efounder.frame.utils.Constants.CHAT_USER_ID;

/**
 * 下载任务
 * Created by zhangshunyun on 2017/7/13.
 */

public class DownloadTask extends ThreadPoolUtils.Task {
    private final String cloudBaseUrl;
    private String desFilePath;
    private String fileName;
    private DownloadInfo downloadInfo;
    private Context mContext;
    private OkHttpClient okHttpClient;
    private long contentLength;
    private String url;
    private long currentTimeMillis;
    private int index = 0;
    private String dir1 = "v2/files/dir/";
    private String dir2 = "/query";
    private int fromUserId;
    private byte toUserType;
    private IMStruct002 imStruct002;

    public DownloadTask(String id, String url, String fileName, String desFilePath,
                        String cloudBaseUrl, IMStruct002 imStruct002) {
        this.mContext = AppContext.getInstance();
        this.id = id;
        this.url = url;
        this.fileName = fileName;
        this.desFilePath = desFilePath;
        downloadInfo = DownloadManager.DOWNLOAD_INFO_HASHMAP.get(id);
        okHttpClient = new OkHttpClient();
        this.cloudBaseUrl = cloudBaseUrl;
        this.fromUserId = imStruct002.getFromUserId();
        this.toUserType = imStruct002.getToUserType();
        this.imStruct002 = imStruct002;
    }

    @Override
    protected void work() {
        downloadFile();
    }

    private void downloadFile() {
        InputStream in = null;
        FileOutputStream out = null;
        try {
            String fileid = downloadInfo.fileID;
            contentLength = getContentLength(fileid);
            long downloadLength = downloadInfo.downloadSize;
            Request request = new Request.Builder()
                    .addHeader("RANGE", "bytes=" + downloadLength + "-" + contentLength)
                    .get()
                    .url(url)
                    .build();
            Call call = okHttpClient.newCall(request);
            DownloadManager.downCalls.put(url, call);
            Response response = call
                    .execute();
            if (response.isSuccessful()) {
                long size = contentLength;
                downloadInfo.size = size;
                in = response.body().byteStream();
                File file2 = new File(desFilePath);
                out = new FileOutputStream(file2, true);//写文件的时候,以追加的方式去写
                int len = 0;
                byte[] buffer = new byte[256 * 1024];
                setState(State.DOWNLOADING);
                while (true) {
                    if (downloadInfo.state == State.DOWNLOAD_STOP) {
                        DownloadManager.getInstance().notifyObserves(downloadInfo.fileID);
                        DownloadManager.getInstance().notifyObservesDownload(downloadInfo.messageID);
                        FileEntity.saveEntityByAppId(downloadInfo, "stop", mContext);
                        break;
                    }
                    len = in.read(buffer);
                    out.write(buffer, 0, len);
                    // 显示进度
                    downloadInfo.downloadSize += len;
                    downloadInfo.progress = (int) (downloadInfo.downloadSize * 100 / contentLength);
                    DownloadManager.getInstance().notifyObserves(downloadInfo.fileID);

                    long time = System.currentTimeMillis() - currentTimeMillis;
                    if (time > 800) {
                        DownloadManager.getInstance().notifyObservesDownload(downloadInfo.messageID);
                        currentTimeMillis = System.currentTimeMillis();
                    } else if (downloadInfo.progress == 100) {
                        DownloadManager.getInstance().notifyObservesDownload(downloadInfo.messageID);
                    }

                    if (downloadInfo.downloadSize == downloadInfo.size) {
                        // 显示下载完成
                        setState(State.DOWNLOAD_COMPLETED);
//                        DownloadManager.getInstance().notifyObserves(downloadInfo.fileID);
                        FileEntity.saveEntityByAppId(downloadInfo, "done", mContext);
                        FileEntity.deleteEntity(downloadInfo, mContext);
                        DownloadManager.getInstance().notifyObservesDownload(downloadInfo.messageID);
                        //todo 发送文件接接收成功的消息 单聊才发
                        if (toUserType == StructFactory.TO_USER_TYPE_PERSONAL) {
                            sendReceivedFileMessage(fromUserId, imStruct002);
                        }
                        break;
                    }
                    if (downloadInfo.downloadSize > contentLength) {
                        setState(State.DOWNLOAD_ERROR);
                        File file = new File(desFilePath);
                        file.delete();
                        FileEntity.deleteEntity(downloadInfo, mContext);
                        DownloadManager.getInstance().notifyObservesDownload(downloadInfo.messageID);
                        DownloadManager.DOWNLOAD_INFO_HASHMAP.remove(downloadInfo.messageID);
                    }
                }
            } else {
                // 显示重试

                if (!DownloadManager.downCalls.containsKey(url)) {
                    setState(State.DOWNLOAD_STOP);
                } else {
                    setState(State.DOWNLOAD_ERROR);
                }
                FileEntity.saveEntityByAppId(downloadInfo, "error", mContext);
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 显示重试
            // 显示重试
            if (DownloadManager.downCalls.containsKey(url)) {
                setState(State.DOWNLOAD_ERROR);
                FileEntity.saveEntityByAppId(downloadInfo, "error", mContext);
                DownloadManager.getInstance().notifyObservesDownload(downloadInfo.messageID);
            } else {

                setState(State.DOWNLOAD_ERROR);
                File file = new File(desFilePath);
                file.delete();
                FileEntity.deleteEntity(downloadInfo, mContext);
                DownloadManager.getInstance().notifyObservesDownload(downloadInfo.messageID);
                DownloadManager.DOWNLOAD_INFO_HASHMAP.remove(downloadInfo.messageID);
            }

        } finally {
            IOUtils.close(out);
            IOUtils.close(in);
        }
    }

    /**
     * 发送文件接接收成功的消息(只有单聊才发)
     *
     * @param fromUserId
     */
    private void sendReceivedFileMessage(int fromUserId,IMStruct002 fileMessage) {
        int mySelfId = 0;
        try {
            mySelfId = Integer.valueOf(EnvironmentVariable.getProperty(CHAT_USER_ID));
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        if (fromUserId == mySelfId) {
            //消息来自自己，不需要发消息
            return;
        }
        net.sf.json.JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", ChatTipsMessageItem.TYPE_NOTIFY_RECEIVED_FILE);
        jsonObject.put("fileName", FileMessageItem.getFileName(fileMessage));
        IMStruct002 imStruct002 = new IMStruct002();
        imStruct002.setMessage(jsonObject.toString());
        imStruct002.setTime(System.currentTimeMillis());
        imStruct002.setToUserType(toUserType);
        imStruct002.setToUserId(fromUserId);
        imStruct002.setFromUserId(Integer.parseInt(EnvironmentVariable.getProperty(Constants.CHAT_USER_ID)));
        imStruct002.setMessageChildType(MessageChildTypeConstant.subtype_chat_tips);
        JFMessageManager.getInstance().sendMessage(imStruct002);
    }

    /**
     * 获取下载的总长度
     *
     * @param id
     * @return
     */
    public long getContentLength(String id) {
//TODO:方法一
//        Request request = new Request.Builder()
//                .url(downloadUrl)
//                .build();
//        try {
//            Response response = this.okHttpClient.newCall(request).execute();
//            if (response != null && response.isSuccessful()) {
//                long contentLength = response.body().contentLength();
//                response.close();
//                return contentLength;
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return 0;
// TODO:方法二 通过后台接口获取
        Request request = new Request.Builder()
                .url(cloudBaseUrl + dir1 + id + dir2)
                .get()
                .build();
//        Request request = new Request.Builder()
//                .url("http://www.pangcloud.cn:9123/panserver/v2/files/dir/" + id + "/query")
//                .get()
//                .build();
        Response response = null;
        String fileSize = "";
        try {
            response = new OkHttpClient().newCall(request).execute();
            ResponseBody body = response.body();
            String s = body.string();
            JSONObject jsonObject = JSONObject.fromObject(s);
//            JsonObject jsonObject = JSONUtil.parseJson(s);
            fileSize = jsonObject.get("fileSize").toString();
            return Long.parseLong(fileSize);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 设置下载状态
     *
     * @param state
     */
    public void setState(int state) {
        downloadInfo.state = state;
        DownloadManager.getInstance().notifyObserves(downloadInfo.messageID);
        // 保存状态
        FileEntity.saveEntityByAppId(downloadInfo, "cancel", mContext);
    }

    /**
     * 由DownloadManager进行调用，取消下载
     *
     * @param url
     */
    public void cancel(String url) {
        Call call = DownloadManager.downCalls.get(url);
        if (call != null) {
            call.cancel();//取消
        }
        DownloadManager.downCalls.remove(url);
        downloadInfo.state = State.DOWNLOAD_STOP;
        FileEntity.saveEntityByAppId(downloadInfo, "cancel", mContext);
    }
}
