package com.ozs.da.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import com.ozs.da.entity.dataquality.ListDataDTO;
import com.ozs.da.entity.dataquality.QuerySqlDTO;
import com.ozs.da.entity.dataquality.UpdateDataDTO;
import com.ozs.da.service.DataQualityService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.ozs.da.entity.remotedb.MdmInfoDatabase;
import com.ozs.da.entity.remotedb.MdmInfoTable;
import com.ozs.da.utils.R;
import com.ozs.da.utils.S;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * @ClassName: DataQualityController
 * @Description:数据质量相关接口
 * @author: Zhao You Kai
 * @date: Apr 3, 2019 2:05:29 PM
 */
@Api(value = "数据质量相关接口")
@RestController
public class DataQualityController {

	private static final Logger log = LogManager.getLogger(DataQualityController.class);

	@Autowired
	private DataQualityService dataQualityService;

	// @Autowireod
	// private AccountApi accountApi;

	@ApiOperation("获取数据库列表--非原始库")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "resourceName", value = "数据资源名称（模糊搜索）", required = false, paramType = "query", dataType = "String") })
	@GetMapping("/da/dataQuality/listDatabase")
	public R<List<MdmInfoDatabase>> listDatabase(
			@RequestParam(name = "resourceName", required = false) String resourceName) {
		try {
			return dataQualityService.listDatabase(resourceName);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
			return new R<>(S.ERROR);
		}
	}

	@ApiOperation("通过数据库ID获取表数据列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "databaseId", value = "数据库ID", required = true, paramType = "query", dataType = "String") })
	@GetMapping("/da/dataQuality/listTableByDatabaseId")
	public R<List<MdmInfoTable>> listTableByDatabaseId(
			@RequestParam(name = "databaseId", required = true) String databaseId) {
		try {
			return dataQualityService.listTableByDatabaseId(databaseId);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
			return new R<>(S.ERROR);
		}
	}

	@ApiOperation("通过表ID获取字段信息列表")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "tableId", value = "表ID", required = false, paramType = "query", dataType = "String") })
	@GetMapping("/da/dataQuality/getQuerySql")
	public R<QuerySqlDTO> getQuerySql(@RequestParam(name = "tableId", required = true) String tableId) {
		try {
			return dataQualityService.getQuerySql(tableId);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
			return new R<>(S.ERROR);
		}
	}

	@ApiOperation("获取表中数据接口")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "tableId", value = "数据表ID", required = true, paramType = "query", dataType = "String"),
			@ApiImplicitParam(name = "primarySql", value = "主键部分sql", required = true, paramType = "query", dataType = "String"),
			@ApiImplicitParam(name = "qureySql", value = "查询部分sql", required = true, paramType = "query", dataType = "String"),
			@ApiImplicitParam(name = "page", value = "当前页数", required = false, paramType = "query", dataType = "Integer"),
			@ApiImplicitParam(name = "pageSize", value = "每页条数", required = false, paramType = "query", dataType = "Integer") })
	@GetMapping("/da/dataQuality/listData")
	public R<ListDataDTO> listData(@RequestParam(name = "tableId", required = true) String tableId,
                                   @RequestParam(name = "primarySql", required = true) String primarySql,
                                   @RequestParam(name = "qureySql", required = true) String qureySql,
                                   @RequestParam(required = false, defaultValue = "1") Integer page,
                                   @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
		try {
			return dataQualityService.listData(tableId, primarySql + qureySql, page, pageSize);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
			return new R<>(S.ERROR);
		}
	}

	@ApiOperation("修改表中数据接口")
	@PostMapping("/da/dataQuality/updateData")
	public R<String> updateData(@RequestBody UpdateDataDTO updateData) {
		try {
			return dataQualityService.updateData(updateData);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
			return new R<>(S.ERROR);
		}
	}

	@ApiOperation("删除表中数据接口")
	@PostMapping("/da/dataQuality/deleteData")
	public R<String> deleteData(@RequestBody UpdateDataDTO updateData) {
		try {
			return dataQualityService.deleteData(updateData);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
			return new R<>(S.ERROR);
		}
	}

	@ApiOperation("下载模板")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "tableId", value = "数据表ID", required = true, paramType = "query", dataType = "String"),
			@ApiImplicitParam(name = "primarySql", value = "主键部分sql", required = true, paramType = "query", dataType = "String"),
			@ApiImplicitParam(name = "qureySql", value = "查询部分sql", required = true, paramType = "query", dataType = "String"), })
	@GetMapping("/da/dataQuality/downloadTemplateData")
	public void downloadTemplateColums(@RequestParam(name = "tableId", required = true) String tableId,
			@RequestParam(name = "primarySql", required = true) String primarySql,
			@RequestParam(name = "qureySql", required = true) String qureySql, HttpServletResponse response)
			throws Exception {
		InputStream inputStream = null;
		ServletOutputStream servletOutputStream = null;
		File f = null;
		try {
			// 文件名
			String fileName = "template-data.xlsx";
			String filePath = dataQualityService.downloadTemplateData(fileName.substring(0, fileName.lastIndexOf(".")),
					tableId, primarySql + qureySql);
			response.setContentType("application/vnd.ms-excel");
			response.addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
			response.addHeader("charset", "utf-8");
			response.addHeader("Pragma", "no-cache");
			String encodeName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
			response.setHeader("Content-Disposition",
					"attachment; filename=\"" + encodeName + "\"; filename*=utf-8''" + encodeName);
			f = new File(filePath);
			inputStream = new FileInputStream(f);
			servletOutputStream = response.getOutputStream();
			IOUtils.copy(inputStream, servletOutputStream);
			response.flushBuffer();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (servletOutputStream != null) {
					servletOutputStream.close();
					servletOutputStream = null;
				}
				if (inputStream != null) {
					inputStream.close();
					f.delete();
					inputStream = null;
				}
				// 召唤jvm的垃圾回收器
				System.gc();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	@ApiOperation(value = "字段模板上传")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "tableId", value = "表Id", required = true, paramType = "form", dataType = "String"),
			@ApiImplicitParam(name = "file", value = "报表文件", required = true, paramType = "form", dataType = "__file") })
	@PostMapping(value = "/da/dataQuality/uploadTemplateData", consumes = "multipart/*", headers = "content-type=multipart/form-data")
	public R<String> loadTemplateData(@RequestParam("file") MultipartFile file,
			@RequestParam("tableId") String tableId) {
		try {
			return dataQualityService.loadTemplateData(tableId, file);
		} catch (Exception e) {
			e.printStackTrace();
			return new R<>(S.ERROR);
		}
	}

}
