package cn.superdesk.uniorder.controller.accounting.customer;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.mail.MailUtil;
import cn.superdesk.uniorder.common.enums.common.CommonAccountingStateEnum;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderIsSendEmailEnum;
import cn.superdesk.uniorder.common.exception.utils.ExceptionUtils;
import cn.superdesk.uniorder.common.numerical.AnBeanUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.rest.response.ResponseResultOuterUtils;
import cn.superdesk.uniorder.config.mail.MailAccountConfigFactory;
import cn.superdesk.uniorder.controller.accounting.utils.ExcelExportAccountingOrderDetailUtils;
import cn.superdesk.uniorder.controller.base.BaseController;
import cn.superdesk.uniorder.dao.entity.accounting.score.customer.AccountingScoreCustomer;
import cn.superdesk.uniorder.dto.param.accounting.common.StatementOfAccountUpdateFieldRamarkForm;
import cn.superdesk.uniorder.dto.param.accounting.score.customer.AccountingOrderScoreCustomerOpDetailQueryCriteria;
import cn.superdesk.uniorder.dto.param.accounting.score.customer.AccountingOrderScoreCustomerQueryCriteria;
import cn.superdesk.uniorder.dto.vo.accounting.score.customer.AccountingOrderScoreCustomerDetailVo;
import cn.superdesk.uniorder.dto.vo.accounting.score.customer.AccountingOrderScoreCustomerHeadVo;
import cn.superdesk.uniorder.dto.vo.accounting.score.customer.AccountingOrderScoreCustomerListItemVo;
import cn.superdesk.uniorder.dubbo.consumer.accounting.customer.AccountingScoreCustomerDubboConsumerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;

/**
 * @Description: Java类作用描述
 * @Author: linjinyu
 * @CreateDate: 2020/11/19 下午3:55
 * @UpdateUser: linjinyu
 * @UpdateDate: 2020/11/19 下午3:55
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Api(value = "积分结算2.0-对账单", tags = {"积分结算2.0-对账单"})
@Slf4j
@RestController
@RequestMapping("/accounting/score/customer/statement")
public class ScoreCustomerStatementController extends BaseController {

    @Autowired
    private AccountingScoreCustomerDubboConsumerService accountingScoreCustomerDubboConsumerService;


//	@Autowired
//	JavaMailSender javaMailSender;
//	@Autowired
//	private SysConfigDubboConsumerService sysConfigDubboConsumerService;


    @Autowired
    private MailAccountConfigFactory mailAccountConfigFactory;
    @Autowired
    private TemplateEngine           templateEngine;


    @Value("${me.email.dzpath}")
    private String accountingCreateFileTempPath;


    /**
     * TAPD_ID_1001175_进行中_积分流水_对账单 添加根据批次查询 batchs 已完成 @RequestBody
     *
     * @param queryCriteria
     * @return
     */
    @ApiOperation(value = "积分结算2.1-对账单-列表", notes = "积分结算2.1")
    @RequestMapping(value = "/getAccountingList", method = RequestMethod.POST)
    @ResponseBody
    public R<List<AccountingOrderScoreCustomerListItemVo>> pageQueryAccountingOrderList(@RequestBody AccountingOrderScoreCustomerQueryCriteria queryCriteria) {

        R<List<AccountingOrderScoreCustomerListItemVo>> result = new R<List<AccountingOrderScoreCustomerListItemVo>>();

        try {

            /****************************************** 筛选条件 start ******************************************/

            /****************************************** 筛选条件   end ******************************************/


            /****************************************** 处理到这里 已经把 table list 的数据填充了 start ******************************************/

            result = accountingScoreCustomerDubboConsumerService.pageQueryAccountingOrderList(queryCriteria, getToken());

            /****************************************** 处理到这里 已经把 table list 的数据填充了 start ******************************************/

            /****************************************** 页头 积分结算2.1 修改 20220218 start ******************************************/

            AccountingOrderScoreCustomerHeadVo accountingListHeadSum = accountingScoreCustomerDubboConsumerService.getAccountingOrderListHeadSum(getToken(), queryCriteria);
            result.setHeadData(AnBeanUtils.beanToMap(accountingListHeadSum));

            /****************************************** 页头 积分结算2.1 修改 20220218   end ******************************************/

        } catch (Exception e) {

            result.setCode(String.valueOf(e.hashCode()));
            result.setSuccess(false);
            result.setMessage(e.getMessage());

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
        }
        return result;

    }

    /**
     * /accounting/score/customer/statement/getAccountingList2Excel
     *
     * @param queryCriteria
     * @return
     */
    @ApiOperation(value = "积分结算2.0-对账单-列表-op导出报表(列表结果集) | opt勾选导出报表", notes = "积分结算2.0,伪表单计划整改")
    @RequestMapping(value = "/getAccountingList2Excel", method = RequestMethod.POST)
    public R<String> exportExcelAccountingOrderScoreCustomerList(@RequestBody AccountingOrderScoreCustomerQueryCriteria queryCriteria) {


        return new R<String>(accountingScoreCustomerDubboConsumerService.exportExcelAccountingOrderScoreCustomerList(queryCriteria, getToken()));
//		try {
//
//
//
//			String[] field = {"batchs", "creditName",
//					"accountingOrderSn", "enterpriseName", "purchaseUserName", "quantityOrder",
//					"accountingAmount",
//					"accountingStatusName", "sendEmailStatusName", "invoiceStatusName", "createTime"
//			};
//
//			String[] fieldZhCn = {"积分批次", "积分类型",
//					"结算单编号", "企业名称", "账单联系人", "订单数量",
//					"积分总数",
//					"结算单状态", "邮件状态", "发票状态", "对账时间"};
//
//			ExcelResponse.out(result, fieldZhCn, field, "对账单-概要", "客户结算_对账单", response);
//
//		} catch (Exception e) {
//
//			log.error(ExceptionUtils.getMessage(e));
//			e.printStackTrace();
//
//		}

    }


    /**
     * 查询详情
     * <p>
     * http://192.168.1.223:8089/web/dzmain/getDzMainDetail
     */
    @ApiOperation(value = "积分结算2.1-对账单-账单详情-op查看详情", notes = "积分结算2.1")
    @RequestMapping(value = "/getAccountingDetail", method = RequestMethod.POST)
    @ResponseBody
    public R<AccountingOrderScoreCustomerDetailVo> getStatementOfAccountDetailDimCredit(@RequestBody AccountingOrderScoreCustomerOpDetailQueryCriteria queryCriteria) {

        R<AccountingOrderScoreCustomerDetailVo> result = new R<>();

        if (ObjectUtil.isNull(queryCriteria.getAccountingOrderId())) {
            return ResponseResultOuterUtils.createErrorResult("500", "请选择查看记录。");
        }

        AccountingOrderScoreCustomerDetailVo accountingScoreCustomerDetailVo = accountingScoreCustomerDubboConsumerService.commonStatementOfAccountDetailDimCredit(queryCriteria, getToken());

        result.setSuccess(true);
        result.setData(accountingScoreCustomerDetailVo);

        return result;
    }

    // TODO  积分结算-结算单-详情 导出报表

//    积分结算 > 对账单 > 详情 > op导出账单
//    http://192.168.6.225:8089/web/accounting/score/customer/statement/exportExcelDetail
//    {"accountingOrderId":"1539","creditAccountingState":1}
//
//    积分结算 > 对账单 > 详情 > op导出账单（含微信支付）
//    http://192.168.6.225:8089/web/accounting/score/customer/statement/exportExcelDetail
//    {"accountingOrderId":"1539","creditAccountingState":0}

    /**
     * @throws IOException
     * @url http://192.168.6.225:8089/web/accounting/score/customer/statement/exportExcelDetail
     * 客户结算-对账单-账单详情-电子对账单
     * op导出账单 accountingOrderId
     * op导出账单(含微信支付) accountingOrderId
     * <p>
     */
    @ApiOperation(value = "积分结算2.1-对账单-账单详情-op查看详情-op导出账单|op导出账单(含微信支付)", notes = "积分结算2.1")
    @RequestMapping(value = "/exportExcelDetail", method = RequestMethod.POST)
    public R<String> exportExcelStatementOfAccountDetailDimCredit(@RequestBody AccountingOrderScoreCustomerOpDetailQueryCriteria queryCriteria) throws IOException {

        if (ObjectUtil.isNull(queryCriteria.getAccountingOrderId())) {
            return ResponseResultOuterUtils.createErrorResult("500", "请选择查看记录。");
        }

        return new R<String>(accountingScoreCustomerDubboConsumerService.exportExcelAccountingOrderScoreCustomerDetailDimCredit(queryCriteria, getToken()));
    }


    // TODO  积分结算-结算单-详情 导出报表-发邮件


    /**
     * 客户结算-对账单-对账单详情 opt 发送邮件
     * /accounting/score/customer/statement/sendEmailExcelDetail
     * <p>
     * 发送对账单邮件-更新二维码地址
     * <p>
     * TODO 正解?20200630 彩娇说目前是用这个
     *
     * @param id
     * @param toEmailAddress
     * @param WxQRCodeUrl
     * @param htmlContent
     * @return
     */
    @ApiOperation(value = "积分结算2.0-对账单-详情-op导出报表-发邮件", notes = "积分结算2.0,伪表单计划整改")
    @SuppressWarnings("restriction")
    @RequestMapping(value = "/sendEmailExcelDetail", method = RequestMethod.POST)
    @ResponseBody
    public R<AccountingOrderScoreCustomerDetailVo> sendEmailExcelAccountingDetail(Long accountingOrderId,
                                                                                  String toEmailAddress,
                                                                                  String WxQRCodeUrl,
                                                                                  int sendWxQRCode,
                                                                                  String htmlContent
    ) {


        log.info("客户结算-对账单-对账单详情 opt 发送邮件 params-id            : {}", accountingOrderId);
        log.info("客户结算-对账单-对账单详情 opt 发送邮件 params-toEmailAddress: {}", toEmailAddress);
        log.info("客户结算-对账单-对账单详情 opt 发送邮件 params-WxQRCodeUrl   : {}", WxQRCodeUrl);
        log.info("客户结算-对账单-对账单详情 opt 发送邮件 params-sendWxQRCode  : {}", sendWxQRCode);
        log.info("客户结算-对账单-对账单详情 opt 发送邮件 params-htmlContent   : {}", htmlContent);


        R<AccountingOrderScoreCustomerDetailVo> result = new R<>();

        try {

//			if (StringUtils.isNotEmpty(WxQRCodeUrl)) {
//				AccountingScoreCustomer statementOfAccount4Update = new AccountingScoreCustomer();
//				statementOfAccount4Update.setId(accountingOrderId);
//				statementOfAccount4Update.setWxQrcodeImgurl(WxQRCodeUrl);
//				accountingScoreCustomerDubboConsumerService.updateObj(statementOfAccount4Update);
//			}

//			ViewDzMain dzMainDetail = accountingScoreCustomerDubboConsumerService.getDzMainDetail(accountingOrderId);
//
//			if (dzMainDetail == null) {
//				result.setSuccess(false);
//				result.setMessage("对账单信息为空,请先选择对账单！");
//				return result;
//			}

            // 对账单详情 复合 主体
            AccountingOrderScoreCustomerDetailVo accountingScoreCustomerDetailVo = accountingScoreCustomerDubboConsumerService.commonStatementOfAccountDetailDimCredit(
                    AccountingOrderScoreCustomerOpDetailQueryCriteria.builder()
                            .accountingOrderId(accountingOrderId)
                            .creditAccountingState(CommonAccountingStateEnum.已对账.getKey())
                            .build()
                    , getToken());

            // 对账单 View Object 填充到 Excel中
            AccountingOrderScoreCustomerListItemVo accountingScoreCustomerVo = accountingScoreCustomerDetailVo.getAccounting();


            /****************************************** 邮件正文 start ******************************************/

            // 利用 Thymeleaf 模板构建 html 文本
            Context templateEngineContext = new Context();
            // 给模板的参数的上下文
            templateEngineContext.setVariable("emailParam", accountingScoreCustomerVo);
            // 执行模板引擎,执行模板引擎需要传入模板名、上下文对象
            // Thymeleaf的默认配置期望所有HTML文件都放在 **resources/templates ** 目录下,以.html扩展名结尾。
            // String emailText = templateEngine.process("email/templates", ctx);
            htmlContent = templateEngine.process("mail_qch", templateEngineContext);

            /****************************************** 邮件正文   end ******************************************/

            /****************************************** 邮件附件 start ******************************************/

            // TODO 20200709 清理过
            HSSFWorkbook workbook = ExcelExportAccountingOrderDetailUtils.score(accountingScoreCustomerDetailVo);
//			SysConfig emailConfig = sysConfigDubboConsumerService.findById("EMAIL");

            String fullpath = accountingCreateFileTempPath + accountingScoreCustomerVo.getAccountingOrderSn() + ".xls";

            FileOutputStream fos = new FileOutputStream(new File(fullpath));
            workbook.write(fos);
            workbook.close();
            fos.close();

            /****************************************** 邮件附件   end ******************************************/

            /****************************************** 邮件标题 start ******************************************/

            SimpleDateFormat sdfm = new SimpleDateFormat("yyyy年MM月");
            SimpleDateFormat sdfd = new SimpleDateFormat("yyyy年MM月dd日");

            String subject = "侨城汇-" + accountingScoreCustomerVo.getAccountingOrderSn() + "-" + (accountingScoreCustomerVo.getEnterpriseName()) + "." + sdfd.format(accountingScoreCustomerVo.getStartTime()) + "-" + sdfd.format(accountingScoreCustomerVo.getEndTime()) + "-对账单";

            /****************************************** 邮件标题   end ******************************************/

            /****************************************** 邮件发送 start ******************************************/

            MailUtil.send(
                    mailAccountConfigFactory.newInstance(),
                    CollUtil.newArrayList(toEmailAddress.split(",")[0]),
//					CollUtil.newArrayList("linjinyu@superdesk.cn"),
                    subject,
                    htmlContent, true,
                    new File(fullpath)
            );

            AccountingScoreCustomer entity = accountingScoreCustomerDubboConsumerService.findById(accountingOrderId);

            entity.setIsSendEmail(AccountingOrderIsSendEmailEnum.已发送.getKey());
            entity.setSendEmailTime(DateUtil.date());

            int ret = accountingScoreCustomerDubboConsumerService.opUpdateByPrimaryKeySelective(entity, getToken());

            /****************************************** 邮件发送   end ******************************************/

            if (ret > 0) {
                return ResponseResultOuterUtils.createSuccesResult();
            } else {
                return ResponseResultOuterUtils.createErrorResult("500", "操作失败");
            }


        } catch (cn.hutool.extra.mail.MailException e) {

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();

            return ResponseResultOuterUtils.createErrorResult("500", "发送邮件失败, 请检查邮箱地址: " + e.getMessage());

        } catch (Exception e) {

            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();

            return ResponseResultOuterUtils.createErrorResult("500", "发送邮件失败,请联系管理员" + e.getMessage());
        }
    }

    @ApiOperation(value = "积分结算2.0-对账单-列表-op设置备注-侨城汇", notes = "积分结算2.0")
    @RequestMapping(value = "/setRemark", method = RequestMethod.POST)
    @ResponseBody
    public R<String> setRemark(@RequestBody StatementOfAccountUpdateFieldRamarkForm form) {

        AccountingScoreCustomer statementOfAccount4Update = new AccountingScoreCustomer();
        statementOfAccount4Update.setId(form.getId());
        statementOfAccount4Update.setRemark(form.getRemark());

        int ret = accountingScoreCustomerDubboConsumerService.opUpdateFieldRemark(statementOfAccount4Update, getToken());

        if (ret > 0) {
            return ResponseResultOuterUtils.createSuccesResult();
        } else {
            return ResponseResultOuterUtils.createErrorResult("500", "操作失败");
        }
    }

}


