package com.iformall.controller.template;

import com.alibaba.fastjson.JSONArray;
import com.iformall.annotation.SystemControllerLog;
import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.controller.base.BaseController;
import com.iformall.controller.mem.ImportTemplateTask;
import com.iformall.domain.po.MallUserInfo;
import com.iformall.enums.EnumImportType;
import com.iformall.exception.MallinkException;
import com.iformall.utils.Constant;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author gongbiao
 */
@RestController
@RequestMapping("wxImportTemplate")
@Api(description = "模板导入")
public class WxImportTemplateController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private String fmUploadDir;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    private ImportTemplateTask importTemplateTask;

    private void set_redis_value(String importKey, String allCount, String allSuccessCount, String processCount, String failCount, boolean fail) {
        stringRedisTemplate.opsForHash().put(importKey, "allCount", allCount);
        stringRedisTemplate.opsForHash().put(importKey, "allSuccessCount", allSuccessCount);
        stringRedisTemplate.opsForHash().put(importKey, "processCount", processCount);
        stringRedisTemplate.opsForHash().put(importKey, "failCount", failCount);
        if (fail) {
            stringRedisTemplate.expire(importKey, 10, TimeUnit.SECONDS);
        }
    }

    @PostMapping(value = "/importTemplate", consumes = "multipart/*")
    @SystemControllerLog(description = "导入数据")
    public ResultData importTemplate(@RequestParam("file") MultipartFile mFile, @RequestParam("type") Integer type) {
        logger.debug("[" + getIpAddr() + "] WxImportTemplateController::importTemplate");
        if (mFile.isEmpty()) {
            throw new MallinkException(Result.ERROR, "上传文件不能为空");
        }
        //得到当前用户ID
        String typeStr = EnumImportType.getEnum(type).getMessage();
        final MallUserInfo user = getUser();
        String userId = typeStr + "_" + user.getId();
        String importKey = Constant.importMemPrev + userId;
        final String tenantId = getTenantId();

        //查询当前用户得到的值是否为空，为空继续，不为空，返回模板正在导入
        Boolean allCount = stringRedisTemplate.opsForHash().hasKey(importKey, "allCount");
        if (allCount) {
            return new ResultData(Result.SUCCESS, "模板正在导入");
        }

        stringRedisTemplate.opsForHash().putIfAbsent(importKey, "allCount", 0 + "");
        stringRedisTemplate.expire(importKey, 30, TimeUnit.MINUTES);
        stringRedisTemplate.opsForHash().putIfAbsent(importKey, "allSuccessCount", 0 + "");
        stringRedisTemplate.opsForHash().putIfAbsent(importKey, "processCount", "");
        stringRedisTemplate.opsForHash().putIfAbsent(importKey, "failCount", "");

        String fpath = fmUploadDir;
        File targetFile = new File(fpath);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        String fileName = type + ".xlsx";
        int dot = mFile.getOriginalFilename().lastIndexOf('.');
        fileName = fileName + mFile.getOriginalFilename().substring(dot, mFile.getOriginalFilename().length());

        File lFile = new File(fpath + File.separator + fileName);

        FileOutputStream fos = null;
        BufferedInputStream fs = null;
        try {
            fos = new FileOutputStream(lFile);
            fs = (BufferedInputStream) mFile.getInputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = fs.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
            fos.close();
            fs.close();
        } catch (Exception e) {
            stringRedisTemplate.expire(importKey, 3, TimeUnit.SECONDS);
            stringRedisTemplate.opsForHash().putIfAbsent(importKey, "allCount", "1");
            stringRedisTemplate.opsForHash().putIfAbsent(importKey, "failCount", "1");
            logger.error(e.getMessage());
            return new ResultData(ErrorCode.MEM_IMPORT_ERR.getCode(), "模板上传失败");
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    stringRedisTemplate.expire(importKey, 3, TimeUnit.SECONDS);
                    stringRedisTemplate.opsForHash().putIfAbsent(importKey, "allCount", "1");
                    stringRedisTemplate.opsForHash().putIfAbsent(importKey, "failCount", "1");
                    logger.error(e.getMessage());
                    return new ResultData(ErrorCode.MEM_IMPORT_ERR.getCode(), "模板上传失败");
                }
            }
            if (fs != null) {
                try {
                    fs.close();
                } catch (IOException e) {
                    stringRedisTemplate.expire(importKey, 3, TimeUnit.SECONDS);
                    stringRedisTemplate.opsForHash().putIfAbsent(importKey, "allCount", "1");
                    stringRedisTemplate.opsForHash().putIfAbsent(importKey, "failCount", "1");
                    logger.error(e.getMessage());
                    return new ResultData(ErrorCode.MEM_IMPORT_ERR.getCode(), "模板上传失败");
                }
            }
        }
        if (type.equals(EnumImportType.MEMBER.getCode())) {
            importTemplateTask.importMemberData(lFile, user, importKey, tenantId);
        } else if (type.equals(EnumImportType.SHOP_RENT.getCode()) || type.equals(EnumImportType.POINT_RENT.getCode())
                || type.equals(EnumImportType.SHOP_PROPERTY.getCode()) || type.equals(EnumImportType.POINT_PROPERTY.getCode())) {
            importTemplateTask.importBillData(lFile, user, importKey, tenantId);
        } else if (type.equals(EnumImportType.DAILY.getCode()) || type.equals(EnumImportType.OTHER.getCode())
                || type.equals(EnumImportType.OTHER_DEPOSIT.getCode())) {
            importTemplateTask.importBillDataOther(lFile, user, importKey, tenantId);
        }
        return new ResultData(Result.SUCCESS, "模板正在导入");
    }


    @GetMapping("/queryTemplateCount")
    @SystemControllerLog(description = "导入数据查询")
    public ResultData queryTemplateCount(@RequestParam("type") Integer type) {
        String typeStr = EnumImportType.getEnum(type).getMessage();
        String importKey = Constant.importMemPrev + typeStr + "_" + getUser().getId();
        Map entries = stringRedisTemplate.opsForHash().entries(importKey);
        logger.info(JSONArray.toJSONString(entries) + ">>>>>>>>>>>>>>>>>>>>>1");
        if (entries.size() < 4) {
            entries.clear();
            return new ResultData(Result.SUCCESS, "ok", entries);
        }
        String allCount = entries.get("allCount").toString();
        String allSuccessCount = entries.get("allSuccessCount").toString();
        String processCount = entries.get("processCount").toString();
        String failCount = entries.get("failCount").toString();

        if (StringUtils.isNotBlank(failCount) && allCount.equals(failCount)) {//stringRedisTemplate.expire(userId,1,TimeUnit.SECONDS);
            logger.info(JSONArray.toJSONString(entries) + ">>>>>>>>>>>>>>>>>>>>>2");
            //完全失败
            stringRedisTemplate.opsForHash().delete(importKey, "allCount");
            stringRedisTemplate.opsForHash().delete(importKey, "allSuccessCount");
            stringRedisTemplate.opsForHash().delete(importKey, "processCount");
            stringRedisTemplate.opsForHash().delete(importKey, "failCount");
            return new ResultData(ErrorCode.MEM_IMPORT_ERR);
        }
        //导入完成
        if (StringUtils.isNotBlank(allSuccessCount) && allSuccessCount.equals(processCount)) {
            ResultData ok = new ResultData(Result.SUCCESS, "ok", entries);
            stringRedisTemplate.opsForHash().delete(importKey, "allCount");
            stringRedisTemplate.opsForHash().delete(importKey, "allSuccessCount");
            stringRedisTemplate.opsForHash().delete(importKey, "processCount");
            stringRedisTemplate.opsForHash().delete(importKey, "failCount");
            return ok;
        }
        return new ResultData(Result.SUCCESS, "查询成功", entries);
    }

}