package cn.com.countrygarden.bi.main.controller.marketing.backend;

import cn.com.countrygarden.bi.main.core.Response;
import cn.com.countrygarden.bi.main.core.Result;
import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.model.MarketingUploadFile;
import cn.com.countrygarden.bi.main.model.twerp.hm.TbSysUser;
import cn.com.countrygarden.bi.main.service.*;
import cn.com.countrygarden.bi.main.service.twerp.hm.TbSysUserService;
import cn.com.countrygarden.bi.main.util.MD5;
import cn.com.countrygarden.bi.main.util.WorkbookUtil;
import org.apache.commons.io.FilenameUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

@Controller("marketingBackendDataFileUploaderController")
@RequestMapping("/api/biapp/marketing/backend/data")
public class DataFileUploaderController {

    private final Logger logger = LoggerFactory.getLogger(DataFileUploaderController.class);

    @Autowired
    private TbSysUserService userService;
    @Autowired
    private MarketingUploadFileService uploadFileService;
    @Autowired
    private MarketingQuotaService quotaService;
    @Autowired
    private MarketingContractService contractService;
    @Autowired
    private MarketingChargeService chargeService;
    @Autowired
    private MarketingProposalService proposalService;


    /**
     * 数据上传
     *
     * @param type
     * @param multipartFile
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/upload", produces = "application/json;charset=utf-8", method = RequestMethod.POST)
    public Result upload(@RequestParam(value = "type", defaultValue = "1", required = true) String type,
                         @RequestParam(value = "uploadfile", defaultValue = "", required = true) MultipartFile multipartFile,
                         HttpServletRequest request, HttpServletResponse response) throws ServiceException {
        Map<String, Object> data = new HashMap<>();

        if (multipartFile == null) {
            throw new ServiceException("请选择需要上传的文件");
        }

        switch (type) {
            case MarketingUploadFile.FILE_TYPE_MISSION_QUOTA:
//            case MarketingUploadFile.FILE_TYPE_CONTRACT:
//            case MarketingUploadFile.FILE_TYPE_CHARGE:
//            case MarketingUploadFile.FILE_TYPE_PROPOSAL:
                break;
            default:
                throw new ServiceException("不支持的数据类型");
        }

        CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) multipartFile;

        // 保存文件并生成上传记录
        String basePath = request.getServletContext().getRealPath("");
        TbSysUser sysUser = userService.getCurrentSysUser();
        MarketingUploadFile uploadFile = moveUploadFile(
                sysUser,
                type,
                commonsMultipartFile,
                basePath
        );

        data.put("id", uploadFile.getId());
        data.put("name", uploadFile.getName());
        data.put("path", uploadFile.getPath());
        // TODO 处理上传数据
        data.put(
                "success",
                parseUploadFile(
                        uploadFile,
                        basePath + uploadFile.getPath(),
                        sysUser
                )
        );

        return Response.response(data);
    }

    /**
     * 保存上传文件，同时生成上传记录
     *
     * @param sysUser
     * @param type
     * @param multipartFile
     * @param basePath
     * @return
     */
    private MarketingUploadFile moveUploadFile(
            TbSysUser sysUser,
            String type,
            CommonsMultipartFile multipartFile,
            String basePath
    ) {
        MarketingUploadFile uploadFile = new MarketingUploadFile();
        Instant instant = Instant.now();
        LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

        String fileName = multipartFile.getOriginalFilename();
        String saveDirectory = "/uploadFile/" + dateTime.getYear() + "/" + dateTime.getMonthValue() + "/" + dateTime.getDayOfMonth();
        String saveFileName = saveDirectory + "/" + MD5.GetMD5Code(dateTime.toString()) + "." + FilenameUtils.getExtension(fileName);

        File dir = new File(basePath + saveDirectory);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        File saveFile = new File(basePath + saveFileName);

        try {
            multipartFile.getFileItem().write(saveFile);

            uploadFile.setType(Byte.valueOf(type));
            uploadFile.setName(fileName);
            uploadFile.setPath(saveFileName);
            uploadFile.setCreateBy(sysUser.getUserCode());
            uploadFile.setGmtCreate(Date.from(instant));
            uploadFile.setGmtModified(null);
            uploadFileService.save(uploadFile);

            logger.info("uploadFile save id: " + uploadFile.getId());
        } catch (Exception e) {
            logger.error("moveUploadFile", e);
            throw new ServiceException("无法保存上传文件：" + e.getMessage());
        }

        return uploadFile;
    }

    /**
     * 解析并保存上传数据
     *
     * @param uploadFile
     * @param realPath
     * @param sysUser
     * @return
     */
    private boolean parseUploadFile(MarketingUploadFile uploadFile, String realPath, TbSysUser sysUser) {
        Workbook workbook = WorkbookUtil.readFromFile(realPath);
        switch (String.valueOf(uploadFile.getType())) {
            case MarketingUploadFile.FILE_TYPE_MISSION_QUOTA:
                workbook = quotaService.processingExcelValue(workbook, uploadFile, sysUser);
                break;
            case MarketingUploadFile.FILE_TYPE_CONTRACT:
                workbook = contractService.processingExcelValue(workbook, uploadFile, sysUser);
                break;
            case MarketingUploadFile.FILE_TYPE_CHARGE:
                workbook = chargeService.processingExcelValue(workbook, uploadFile, sysUser);
                break;
            case MarketingUploadFile.FILE_TYPE_PROPOSAL:
                workbook = proposalService.processingExcelValue(workbook, uploadFile, sysUser);
                break;
            default:
                throw new ServiceException("不支持的数据类型");
        }

        try {
            FileOutputStream outputStream = new FileOutputStream(realPath);
            workbook.write(outputStream);
        } catch (FileNotFoundException e) {
            throw new ServiceException("无法保存处理结果：文件不存在");
        } catch (IOException e) {
            throw new ServiceException("无法保存处理结果：" + e.getMessage());
        }

        return true;
    }
}
