/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.finance.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springblade.audit.entity.BladeReportTask;
import org.springblade.audit.service.IBladeReportTaskService;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.SecureUtil;
import org.springblade.core.tool.api.R;
import org.springblade.finance.dto.InnerAccountExcel;
import org.springblade.finance.entity.DealUserAccounts;
import org.springblade.finance.entity.InnerAccount;
import org.springblade.finance.entity.InnerDealDetail;
import org.springblade.finance.service.DealUserAccountsService;
import org.springblade.finance.service.IInnerAccountService;
import org.springblade.finance.service.IInnerDealDetailService;
import org.springblade.system.client.UserClient;
import org.springblade.system.client.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 内部结算-结算单表 控制器
 *
 * @author zbc
 * @since 2022-07-20
 */
@RestController
@RequestMapping("finance/innerAccount")
@Api(value = "内部结算-结算单表", tags = "内部结算-结算单表接口")
@Slf4j
public class InnerAccountController {

	@Autowired
	private IBladeReportTaskService bladeReportTaskService;

	@Autowired
	private IInnerDealDetailService innerDealDetailService;

	@Autowired
	private IInnerAccountService innerAccountService;

	@Autowired
	private DealUserAccountsService dealUserAccountsService;

	@Autowired
	private UserClient userService;


	/**
	 * @param query
	 * @return
	 */
	@GetMapping("/page")
	@ApiOperation(value = "分页查询内部结算数据")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "company", value = "结算方名称", dataType = "string", required = false),
		@ApiImplicitParam(name = "dealType", value = "结算单类型", dataType = "string", required = false),
		@ApiImplicitParam(name = "startTime", value = "开始月份(格式：yyyyMM)", dataType = "string", required = false),
		@ApiImplicitParam(name = "endTime", value = "结束月份(格式：yyyyMM)", dataType = "string", required = false)
	})
	public R<IPage<InnerAccount>> page(String company,String dealType, String startTime, String endTime, Query query){
		if(query.getSize() == null){
			query.setSize(5);
		}
		LambdaQueryWrapper<InnerAccount> queryWrapper = Wrappers.<InnerAccount>lambdaQuery();
		if(StringUtils.isNotBlank(company)){
			queryWrapper.eq(InnerAccount::getCompany,company);
		}
		if(StringUtils.isNotBlank(dealType)){
			queryWrapper.eq(InnerAccount::getDealType,dealType);
		}
		if(StringUtils.isNotEmpty(startTime)) {
			int startDate = Integer.valueOf(startTime);
			queryWrapper.ge(InnerAccount::getThemonth, startDate);
		}
		if(StringUtils.isNotEmpty(endTime)) {
			int endDate = Integer.valueOf(endTime);
			queryWrapper.le(InnerAccount::getThemonth, endDate);
		}
		IPage<InnerAccount> pageResult = innerAccountService.page(Condition.getPage(query), queryWrapper.orderByDesc(InnerAccount::getThemonth));
		return R.data(pageResult);
	}


	@Value("${blade.file.uploadPath}")
	private String picDir;



	@GetMapping("/beforeChrist/export")
	@ApiOperation(value = "导出内部结算表BC")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "company", value = "结算方名称", dataType = "string", required = false),
		@ApiImplicitParam(name = "dealType", value = "结算类型。1：有效用户；2：会员权益；3：出账用户； ", dataType = "Integer", required = false),
		@ApiImplicitParam(name = "startTime", value = "开始月份(格式：yyyyMM)", dataType = "string", required = false),
		@ApiImplicitParam(name = "endTime", value = "结束月份(格式：yyyyMM)", dataType = "string", required = false)
	})
	public R beforeChristExport(String company,String dealType,String startTime,String endTime, HttpServletResponse response) throws Exception {
		LambdaQueryWrapper<InnerAccount> queryWrapper = Wrappers.<InnerAccount>lambdaQuery();
		if(StringUtils.isNotEmpty(company)) {
			queryWrapper.eq(InnerAccount::getCompany, company);
		}
		if(StringUtils.isNotBlank(dealType)){
			queryWrapper.eq(InnerAccount::getDealType,dealType);
		}
		if(StringUtils.isNotEmpty(startTime)) {
			int startDate = Integer.valueOf(startTime);
			queryWrapper.ge(InnerAccount::getThemonth, startDate);
		}
		if(StringUtils.isNotEmpty(endTime)) {
			int endDate = Integer.valueOf(endTime);
			queryWrapper.le(InnerAccount::getThemonth, endDate);
		}

		//不包括本月数据
		/*Integer thisMonth = Integer.valueOf(DateTimeFormatter.ofPattern("yyyyMM").format(LocalDate.now()));
		queryWrapper.lt(InnerAccount::getThemonth, thisMonth);*/

		List<InnerAccount> dbAccountList = null;
		dbAccountList = innerAccountService.list(queryWrapper.orderByDesc(InnerAccount::getThemonth));


		List<InnerAccountExcel> accountList = new ArrayList<InnerAccountExcel>();

		if(dbAccountList != null && !dbAccountList.isEmpty()) {
			for (InnerAccount innerAccount : dbAccountList) {
				InnerAccountExcel excel = new InnerAccountExcel();
				BeanUtil.copyProperties(innerAccount, excel);
				accountList.add(excel);
			}
		}

		Long userId = SecureUtil.getUserId();
		UserModel byId = userService.getById(userId);
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
		String format = simpleDateFormat.format(new Date());
		String tempFileName = "内部结算-"+byId.getRealName() + "-结算表-" + format + RandomUtil.randomString(2) + ".xlsx";

		BladeReportTask bladeReportTask = new BladeReportTask();
		bladeReportTask.setReportName(tempFileName);
		bladeReportTask.setReportType(2);
		bladeReportTask.setReportStatus(1);
		bladeReportTask.setDownloadStatus(1);
		bladeReportTask.setCreateUser(userId);
		bladeReportTask.setCreateTime(new Date());
		boolean res = bladeReportTaskService.save(bladeReportTask);
		String filePath = picDir + tempFileName;
		Long beginTime = System.currentTimeMillis();
		if(res){
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						//String filePath = "D:/boyuan/work2/excel/" + tempFileName;
						EasyExcel.write(filePath, InnerAccountExcel.class).sheet().doWrite(accountList);
						Long endTime = System.currentTimeMillis();
						String opetime = (endTime - beginTime) + "ms";
						bladeReportTask.setUseTime(opetime);
						bladeReportTask.setReportUrl("uploads/" + tempFileName);
						bladeReportTask.setReportStatus(2);
						bladeReportTask.setDownloadStatus(1);
						bladeReportTaskService.updateById(bladeReportTask);
					} catch (Exception e) {
						bladeReportTask.setReportStatus(3);
						bladeReportTask.setDownloadStatus(1);
						bladeReportTaskService.updateById(bladeReportTask);
						e.printStackTrace();
					}
				}
			}).start();
		}else {
			bladeReportTask.setReportStatus(3);
			bladeReportTaskService.updateById(bladeReportTask);
			return R.fail("导出任务提交失败");
		}
		return R.success("导出任务提交成功");
	}


	/**
	 * @throws Exception
	 */
	@GetMapping("/downloadPdf")
	@ApiOperation(value = "下载内部结算单PDF")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "sid", value = "序号", dataType = "Integer", required = true)
	})
	public void downloadPdf(@RequestParam String sid, HttpServletResponse response) throws Exception {
		LambdaQueryWrapper<InnerAccount> queryWrapper = Wrappers.lambdaQuery(InnerAccount.class).eq(InnerAccount::getSid, sid);
		InnerAccount innerAccount = innerAccountService.getOne(queryWrapper);
		if(innerAccount != null) {
			DealUserAccounts accounts = dealUserAccountsService.getOne(new LambdaQueryWrapper<DealUserAccounts>()
				.eq(DealUserAccounts::getDealAccountId, innerAccount.getDealAccountId())
			);

			// Http 1.0 header
			response.setDateHeader("Expires", 0);
			response.addHeader("Pragma", "no-cache");
			// Http 1.1 header
			response.setHeader("Cache-Control", "no-cache");
			String encodedfileName = new String((innerAccount.getCompany()+"结算确认单").getBytes("GBK"), "ISO8859-1");
			response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedfileName + ".pdf\"");
			response.setContentType("application/vnd.ms-pdf");

			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			if(accounts != null && accounts.getDealUserid().equals("inn_rh_wo_assis")){
				createPdfWzl(innerAccount, baos);
			}else {
				createPdfNbjs(innerAccount, baos);
			}
			response.getOutputStream().write(baos.toByteArray());
			response.getOutputStream().flush();
		}
	}


	/**
	 * 内部结算类型PDF
	 * @param data
	 * @param baos
	 * @throws Exception
	 */
	private void createPdfNbjs(InnerAccount data, ByteArrayOutputStream baos) throws Exception {
		List<InnerDealDetail> list = null;
		if(data.getSid() != null){
			list = innerDealDetailService.list(new LambdaQueryWrapper<InnerDealDetail>()
				.eq(InnerDealDetail::getSid,data.getSid())
			);
		}

		Document document = new Document();
		PdfWriter.getInstance(document, baos);
		document.open();

		String theMonthStr = data.getThemonth().toString();
		String year = theMonthStr.substring(0, 4), month = theMonthStr.substring(4);

		// 使用语言包字体
		BaseFont abf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
		// 外部字体
		ClassPathResource cpr = new ClassPathResource("/fonts/simfang.ttf");
		BaseFont bf = BaseFont.createFont(cpr.getPath(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
		Font titleFont = new Font(bf, 12, Font.NORMAL);

		PdfPTable table = new PdfPTable(4);

		PdfPCell cell = new PdfPCell();
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setVerticalAlignment(Element.ALIGN_CENTER);
		cell.setColspan(4);
		cell.setPaddingBottom(10f);
		Paragraph paragraph = new Paragraph(String.format("《%s结算确认单》", data.getDealType()), new Font(abf, 13, Font.BOLD));
		paragraph.setAlignment(Paragraph.ALIGN_CENTER);
		cell.addElement(paragraph);
		table.addCell(cell);

		/*cell = new PdfPCell();
		cell.setColspan(4);
		cell.setPadding(10f);
		Paragraph para = new Paragraph(
			"1.甲方为推广其产品或服务，同意按照本协议的规定在乙方 独家代理的优酷APP收银台 渠道推广其产品或服务，按合作结算渠道推广费用。\n" +
				"2.本统计表自双方签署盖章之日起生效。\n" +
				"3.本统计表一式贰份，双方各执壹份。\n" +
				"5.请乙方收到此单据后 5个工作 日予以确认。", titleFont);
		para.setSpacingBefore(10f);
		cell.addElement(para);
		table.addCell(cell);*/

		cell = new PdfPCell(new Phrase("结算账期", titleFont));
		cell.setColspan(2);
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase(String.format("%s 年 %s 月", year, month), titleFont));
		cell.setColspan(4);
		cell.setPadding(10f);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase("甲方：", titleFont));
		cell.setColspan(2);
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("联通在线信息科技有限公司", titleFont));
		cell.setColspan(4);
		cell.setPadding(10f);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase("乙方：" , titleFont));
		cell.setColspan(2);
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase(data.getCompany(), titleFont));
		cell.setColspan(4);
		cell.setPadding(10f);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase("合同编号", titleFont));
		cell.setColspan(2);
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase(" ", titleFont));
		cell.setColspan(4);
		cell.setPadding(10f);
		table.addCell(cell);


		cell = new PdfPCell(new Phrase("业务名称", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("结算用户数", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("采购单价(含税)", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("小计(含税)", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);

		if(list != null && list.size() > 0){
			for (InnerDealDetail detail : list) {
				cell = new PdfPCell(new Phrase(detail.getSpname(), titleFont));
				cell.setPadding(10f);
				table.addCell(cell);
				cell = new PdfPCell(new Phrase(detail.getUsernum().toString(), titleFont));
				cell.setPadding(10f);
				table.addCell(cell);
				cell = new PdfPCell(new Phrase(detail.getDealPrice() + "", titleFont));
				cell.setPadding(10f);
				table.addCell(cell);
				cell = new PdfPCell(new Phrase(detail.getMoney() + "" ,titleFont));
				cell.setPadding(10f);
				table.addCell(cell);
			}
		}


		cell = new PdfPCell(new Phrase("", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase(24,
			"甲方：联通在线信息科技有限公司 \n" +
				"\n\n\n" +
				"盖章：\n\n\n\n" +
				"\n\n\n" +
				"日期：",
			titleFont));
		cell.setColspan(2);
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase(24,
			"乙方：" + data.getCompany() +" \n" +
				"\n\n\n" +
				"盖章：\n\n\n\n" +
				"\n\n\n" +
				"日期：",
			titleFont));
		cell.setColspan(4);
		cell.setPadding(10f);
		table.addCell(cell);
		document.add(table);
		document.close();
	}

	/**
	 * 沃助理单独处理
	 * @param data
	 * @param baos
	 * @throws Exception
	 */
	private void createPdfWzl(InnerAccount data, ByteArrayOutputStream baos) throws Exception {
		List<InnerDealDetail> list = null;
		if(data.getSid() != null){
			list = innerDealDetailService.list(new LambdaQueryWrapper<InnerDealDetail>()
				.eq(InnerDealDetail::getSid,data.getSid())
			);
		}

		Document document = new Document();
		PdfWriter.getInstance(document, baos);
		document.open();

		String theMonthStr = data.getThemonth().toString();
		String year = theMonthStr.substring(0, 4), month = theMonthStr.substring(4);

		// 使用语言包字体
		BaseFont abf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
		// 外部字体
		ClassPathResource cpr = new ClassPathResource("/fonts/simfang.ttf");
		BaseFont bf = BaseFont.createFont(cpr.getPath(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
		Font titleFont = new Font(bf, 12, Font.NORMAL);

		PdfPTable table = new PdfPTable(4);

		PdfPCell cell = new PdfPCell();
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setVerticalAlignment(Element.ALIGN_CENTER);
		cell.setColspan(4);
		cell.setPaddingBottom(10f);
		Paragraph paragraph = new Paragraph(String.format("《%s结算确认单》", data.getDealType()), new Font(abf, 13, Font.BOLD));
		paragraph.setAlignment(Paragraph.ALIGN_CENTER);
		cell.addElement(paragraph);
		table.addCell(cell);

		/*cell = new PdfPCell();
		cell.setColspan(4);
		cell.setPadding(10f);
		Paragraph para = new Paragraph(
			"1.甲方为推广其产品或服务，同意按照本协议的规定在乙方 独家代理的优酷APP收银台 渠道推广其产品或服务，按合作结算渠道推广费用。\n" +
				"2.本统计表自双方签署盖章之日起生效。\n" +
				"3.本统计表一式贰份，双方各执壹份。\n" +
				"5.请乙方收到此单据后 5个工作 日予以确认。", titleFont);
		para.setSpacingBefore(10f);
		cell.addElement(para);
		table.addCell(cell);*/

		cell = new PdfPCell(new Phrase("结算账期", titleFont));
		cell.setColspan(2);
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase(String.format("%s 年 %s 月", year, month), titleFont));
		cell.setColspan(4);
		cell.setPadding(10f);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase("甲方：", titleFont));
		cell.setColspan(2);
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("畅视事业部", titleFont));
		cell.setColspan(4);
		cell.setPadding(10f);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase("乙方：" , titleFont));
		cell.setColspan(2);
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase(data.getCompany(), titleFont));
		cell.setColspan(4);
		cell.setPadding(10f);
		table.addCell(cell);

		cell = new PdfPCell(new Phrase("合同编号", titleFont));
		cell.setColspan(2);
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase(" ", titleFont));
		cell.setColspan(4);
		cell.setPadding(10f);
		table.addCell(cell);


		cell = new PdfPCell(new Phrase("业务名称", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("结算用户数", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("采购单价(含税)", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("小计(含税)", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);

		if(list != null && list.size() > 0){
			for (InnerDealDetail detail : list) {
				cell = new PdfPCell(new Phrase(detail.getSpname(), titleFont));
				cell.setPadding(10f);
				table.addCell(cell);
				cell = new PdfPCell(new Phrase(detail.getUsernum().toString(), titleFont));
				cell.setPadding(10f);
				table.addCell(cell);
				cell = new PdfPCell(new Phrase(detail.getDealPrice() + "", titleFont));
				cell.setPadding(10f);
				table.addCell(cell);
				cell = new PdfPCell(new Phrase(detail.getMoney() + "" ,titleFont));
				cell.setPadding(10f);
				table.addCell(cell);
			}
		}


		cell = new PdfPCell(new Phrase("", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase("", titleFont));
		cell.setPadding(10f);
		table.addCell(cell);

		/*cell = new PdfPCell(new Phrase(24,
			"甲方：联通在线信息科技有限公司 \n" +
				"\n\n\n" +
				"盖章：\n\n\n\n" +
				"\n\n\n" +
				"日期：",
			titleFont));
		cell.setColspan(2);
		cell.setPadding(10f);
		table.addCell(cell);
		cell = new PdfPCell(new Phrase(24,
			"乙方：" + data.getCompany() +" \n" +
				"\n\n\n" +
				"盖章：\n\n\n\n" +
				"\n\n\n" +
				"日期：",
			titleFont));
		cell.setColspan(4);
		cell.setPadding(10f);
		table.addCell(cell);*/
		document.add(table);
		document.close();
	}

}
