package com.ibeetl.admin.console.web;

import com.ibeetl.admin.console.service.DictConsoleService;
import com.ibeetl.admin.console.web.dto.DictExcelImportData;
import com.ibeetl.admin.console.web.query.CoreDictQuery;
import com.ibeetl.admin.core.annotation.Function;
import com.ibeetl.admin.core.annotation.RequestBodyPlus;
import com.ibeetl.admin.core.entity.CoreDict;
import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.file.FileItem;
import com.ibeetl.admin.core.file.FileService;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.util.PlatformException;
import com.ibeetl.admin.core.util.ValidateConfig;
import com.ibeetl.admin.core.web.JsonResult;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.beetl.sql.core.page.DefaultPageRequest;
import org.beetl.sql.core.page.PageRequest;
import org.beetl.sql.core.page.PageResult;
import org.jxls.common.Context;
import org.jxls.reader.ReaderBuilder;
import org.jxls.reader.ReaderConfig;
import org.jxls.reader.XLSReadMessage;
import org.jxls.reader.XLSReadStatus;
import org.jxls.reader.XLSReader;
import org.jxls.util.JxlsHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * 字典数据管理接口
 */
@Slf4j
@RequestMapping("dicts")
@RestController
public class DictConsoleElController {

  @Autowired
  private DictConsoleService dictService;

  @Autowired
  FileService fileService;

  @Autowired
  CorePlatformService platformService = null;

  @GetMapping("/list")
  @Function("dict.query")
  public JsonResult<PageResult> list(CoreDictQuery condtion) {

    PageRequest page = condtion.getPageRequest();
    PageResult<CoreDict> pageResult = dictService
        .queryByCondition(page);
    return JsonResult.success(pageResult);
  }

  @PostMapping("/add")
  @Function("dict.add")
  public JsonResult add(@RequestBody @Validated(ValidateConfig.ADD.class) CoreDict dict) {

    dict.setCreateTime(new Date());
    dictService.save(dict);
    platformService.clearDictCache();
    return JsonResult.success();
  }

  @PutMapping("/update")
  @Function("dict.update")
  public JsonResult<String> update(
      @RequestBody @Validated(ValidateConfig.UPDATE.class) CoreDict dict) {

    boolean success = dictService.update(dict);
    if (success) {
      platformService.clearDictCache();
      return JsonResult.success();
    } else {
      return JsonResult.failMessage("保存失败");
    }
  }

  @GetMapping("/view/{id}")
  @Function("dict.query")
  public JsonResult<CoreDict> queryInfo(@PathVariable("id") @NotNull Long id) {

    CoreDict dict = dictService.queryById(id);
    return JsonResult.success(dict);
  }

  @DeleteMapping("/delete")
  @Function("dict.delete")
  public JsonResult delete(@NotEmpty @RequestBodyPlus("ids") List<Long> ids) {

    dictService.batchDelCoreDict(ids);
    platformService.clearDictCache();
    return JsonResult.success();
  }

  @GetMapping("/excel/export")
  @Function("dict.export")
  public JsonResult<String> export(CoreDictQuery condtion,
      HttpServletResponse response) {

    String excelTemplate = "excelTemplates/admin/dict/dict_collection_template.xls";
    PageRequest<CoreUser> page = DefaultPageRequest.of(1,Integer.MAX_VALUE);
    // 取出全部符合条件的
    List<CoreDict> dicts = dictService.queryExcel(page);
    try (InputStream is =
        Thread.currentThread().getContextClassLoader().getResourceAsStream(excelTemplate)) {
      if (is == null) {
        throw new PlatformException("模板资源不存在：" + excelTemplate);
      }
      FileItem item = fileService.createFileTemp("dict_collection.xls");
      OutputStream os = item.openOutpuStream();
      Context context = new Context();
      context.putVar("dicts", dicts);
      JxlsHelper.getInstance().processTemplate(is, os, context);
      os.close();
      // 下载参考FileSystemContorller
      return JsonResult.success(item.getPath());
    } catch (IOException e) {
      throw new PlatformException(e.getMessage());
    }
  }

  @PostMapping("/excel/import")
  @Function("dict.import")
  public JsonResult importExcel(@RequestParam("file") MultipartFile file) throws Exception {

    if (file.isEmpty()) {
      return JsonResult.fail();
    }
    InputStream ins = file.getInputStream();

    InputStream inputXML =
        Thread.currentThread()
            .getContextClassLoader()
            .getResourceAsStream("excelTemplates/admin/dict/dict_mapping.xml");
    XLSReader mainReader = ReaderBuilder.buildFromXML(inputXML);
    InputStream inputXLS = ins;
    List<DictExcelImportData> dicts = new ArrayList<DictExcelImportData>();
    Map beans = new HashMap();
    beans.put("list", dicts);
    ReaderConfig.getInstance().setSkipErrors(true);
    XLSReadStatus readStatus = mainReader.read(inputXLS, beans);
    List<XLSReadMessage> errors = readStatus.getReadMessages();
    if (!errors.isEmpty()) {
      StringBuilder sb = new StringBuilder();
      for (XLSReadMessage msg : errors) {
        sb.append(parseXLSReadMessage(msg));
        sb.append(",");
      }
      sb.setLength(sb.length() - 1);
      return JsonResult.failMessage("解析excel出错:" + sb.toString());
    }
    //        this.dictService.batchInsert(dicts);//layui对话框不能正确处理http 500错误，改成下面方式
    //        return JsonResult.success();
    try {
      this.dictService.batchInsert(dicts);
      return JsonResult.success();
    } catch (Exception ex) {
      return JsonResult.failMessage(ex.getMessage());
    }
  }

  /*xlsReader 设计有问题，还需要通过解析msg知道错误位置在哪里*/
  private String parseXLSReadMessage(XLSReadMessage msg) {
    //        String message = "Can't read cell " + getCellName(mapping, rowShift) + " on " +
    // cursor.getSheetName() + " spreadsheet";
    String str = msg.getMessage();
    int start = "Can't read cell ".length();
    int end = str.indexOf("on");
    return str.substring(start, end);
  }

}
