package digital.laboratory.platform.entrustment.controller;

import digital.laboratory.platform.common.core.constant.CommonConstants;
import digital.laboratory.platform.common.core.constant.OSSDirectoryConstants;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.entrustment.entity.EntrustmentIdentificationMaterial;
import digital.laboratory.platform.entrustment.handler.AppStartupRunner;
import digital.laboratory.platform.entrustment.service.EntrustmentIdentificationMaterialService;
import digital.laboratory.platform.entrustment.service.SampleBoxService;
import digital.laboratory.platform.sewage.utils.QRCodeUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;

@RestController
@RequiredArgsConstructor
@RequestMapping("/papp/entrustment/common")
@Api(tags = "000-基础功能")
public class CommonController {
	private final EntrustmentIdentificationMaterialService entrustmentIdentificationMaterialService;
	private final OssFile ossFile;

	private final SampleBoxService sampleBoxService;

	/**
	 * 根据模板生成检材标签的 html, 供 qz 打印使用
	 *
	 * @return R<CaseEventVO>
	 */
	@ApiOperation(value = "根据模板生成检材标签的 html, 供 qz 打印使用", notes = "根据模板生成检材标签的 html, 供 qz 打印使用")
	@GetMapping("/imlabel/{id}")
	public String getIdentificationMaterialLabel(@PathVariable("id") String id, HttpServletResponse httpServletResponse) throws Exception {
		String templateFileName = AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_LABEL_TEMPLATE_IDENTIFICATION_MATERIAL);

		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ossFile.fileGet(OSSDirectoryConstants.TEMPLATE_DIRECTORY + "/"+ templateFileName, bos);
		String templateString = bos.toString("UTF-8");
		bos.close();

		try {
			// 设置自定义指令使用的类
			Velocity.setProperty("userdirective",
					"digital.laboratory.platform.entrustment.misc.VelocityQRCodeImage," +
					"digital.laboratory.platform.entrustment.misc.VelocityBarCodeImage");
			//初始化模板
			Velocity.init();
			//获取上下文
			VelocityContext context = new VelocityContext();
			//把数据填入上下文
			EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(id);
			if (im == null) {
				throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", id));
			}
			context.put("im", im);

			StringWriter w = new StringWriter();
			Velocity.evaluate(context, w, "Velocity",  templateString);
			w.flush();
			return w.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


	/**
	 * 生成 QRCODE 图像
	 *
	 * @param code QRCODE字符串
	 *
	 * @return R<CaseEventVO>
	 */
	@ApiOperation(value = "生成 QRCODE 图像", notes = "生成 QRCODE 图像")
	@GetMapping("/qrcode/{code}")
	public void genQRCode(@PathVariable("code") String code, HttpServletResponse httpServletResponse) throws IOException {
		try {
			// QR Code
			httpServletResponse.setContentType("image/png");
			BufferedImage qrImage = QRCodeUtils.genQRCode(code, 150, 150);
			ImageIO.write(qrImage, "png", httpServletResponse.getOutputStream());
		} catch (Exception e) {
			httpServletResponse.sendError(501, e.toString());
		}
	}

	/**
	 * 生成 QRCODE 图像
	 *
	 * @param code QRCODE字符串
	 *
	 * @return R<CaseEventVO>
	 */
	@ApiOperation(value = "生成 QRCODE 图像 Base64", notes = "生成 QRCODE 图像 Base64")
	@GetMapping("/qrcode64/{code}")
	public String getQRCodeImageBase64(@PathVariable("code") String code, HttpServletResponse httpServletResponse) throws IOException {
		// QR Code
		return QRCodeUtils.getQRCodeImageBase64(code, 150, 150);
	}


	/**
	 * 生成 BARCODE 图像
	 *
	 * @param code QRCODE字符串
	 *
	 * @return R<CaseEventVO>
	 */
	@ApiOperation(value = "生成 QRCODE 图像", notes = "生成 QRCODE 图像")
	@GetMapping("/barcode/{code}")
	public void getBarCodeImage(@PathVariable("code") String code, @RequestParam(value = "h", required = false) Integer h, @RequestParam(value = "w", required = false) Integer w, HttpServletResponse httpServletResponse) throws IOException {
		int width = 400;
		int height = 30;
		if ((w != null) && (w > 0)) {
			width = w;
		}
		if ((h != null) && (h > 0)) {
			height = h;
		}

		try {
			// QR Code
			httpServletResponse.setContentType("image/png");
			BufferedImage qrImage = QRCodeUtils.getBarCode128Image(code, width, height);
			ImageIO.write(qrImage, "png", httpServletResponse.getOutputStream());
		} catch (Exception e) {
			httpServletResponse.sendError(501, e.toString());
		}
	}

	/**
	 * 生成 BARCODE 图像
	 *
	 * @param code QRCODE字符串
	 *
	 * @return R<CaseEventVO>
	 */
	@ApiOperation(value = "生成 BARCODE 图像 Base64", notes = "生成 BARCODE 图像 Base64")
	@GetMapping("/barcode64/{code}")
	public String getBarCodeImageBase64(@PathVariable("code") String code, @RequestParam(value = "h", required = false) Integer h, @RequestParam(value = "w", required = false) Integer w, HttpServletResponse httpServletResponse) throws IOException {
		int width = 400;
		int height = 30;
		if ((w != null) && (w > 0)) {
			width = w;
		}
		if ((h != null) && (h > 0)) {
			height = h;
		}

		return QRCodeUtils.getBarCode128ImageBase64(code, width, height);
	}


	//盒子标签打印

	/**
	 * 打印盒子的标签
	 * @param sampleBoxID
	 * @return
	 * @throws Exception
	 */
	@ApiOperation(value = "打印盒子标签", notes = "根据盒子ID，打印盒子标签")
	@GetMapping("/printBoxLabelBarCode/{sampleBoxID}")
	public String getSampleBoxLabel(@PathVariable("sampleBoxID") String sampleBoxID) throws Exception{
		return sampleBoxService.buildSampleBoxLabelContent(sampleBoxID);
	}
}
