package cn.superdesk.uniorder.controller.invoice.common;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.common.exception.utils.ExceptionUtils;
import cn.superdesk.uniorder.common.numerical.AnStringUtils;
import cn.superdesk.uniorder.common.pagination.PageQueryParam;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.rest.response.ResponseResultOuterUtils;
import cn.superdesk.uniorder.controller.base.BaseController;
import cn.superdesk.uniorder.dao.entity.invoice.common.InvoiceBankInfo;
import cn.superdesk.uniorder.dto.param.invoice.common.InvoiceBankInfoParam;
import cn.superdesk.uniorder.dto.param.invoice.common.InvoiceBankInfoQueryCriteria;
import cn.superdesk.uniorder.dubbo.consumer.invoice.common.InvoiceBankInfoDubboConsumerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

@Api(value = "系统设置-收款方发票信息(银行信息)", tags = {"系统设置-收款方发票信息(银行信息)"})
@Slf4j
@RestController
@RequestMapping("/setting/unifiedBankInfo")
public class InvoiceBankInfoController extends BaseController {


    @Autowired
    private InvoiceBankInfoDubboConsumerService invoiceBankInfoDubboConsumerService;

    @ApiOperation(value = "列表分页-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)", notes = "积分结算2.1,伪表单整改")
    @PostMapping("/pageQuery")
    @ResponseBody
    public R<List<InvoiceBankInfoParam>> pageQuery(@RequestBody InvoiceBankInfoQueryCriteria queryCriteria) {

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

        try {
            result = invoiceBankInfoDubboConsumerService.pageQuery(queryCriteria, getToken());
            return result;
        } catch (Exception e) {
            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
            return ResponseResultOuterUtils.createErrorResult("500", StrUtil.format("{}:{}", e.hashCode(), e.getMessage()));
        }

    }

    @ApiOperation(value = "下拉-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)", notes = "积分结算2.1,伪表单整改")
    @PostMapping("/query")
    @ResponseBody
    public R<List<InvoiceBankInfo>> query(@RequestBody InvoiceBankInfoQueryCriteria queryCriteria) {

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

        try {
            List<InvoiceBankInfo> resultList = invoiceBankInfoDubboConsumerService.query(queryCriteria, getToken());
            result.setData(resultList);

        } catch (Exception e) {
            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
            return ResponseResultOuterUtils.createErrorResult("500", StrUtil.format("{}:{}", e.hashCode(), e.getMessage()));
        }

        return result;
    }

    @ApiOperation(value = "新增-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)", notes = "积分结算2.1,伪表单整改")
    @PostMapping("/add")
    @ResponseBody
    public R<String> add(@RequestBody InvoiceBankInfo invoiceBankInfo) {

        try {


            if (StrUtil.isBlank(invoiceBankInfo.getCompanyName().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入收款方名称");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getBankName().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入开户行名称");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getBankAccount().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入开户行账号");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getSupplyName().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入供货单位");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getAddress().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入地址");
            }

            /**************************************** 开票人 复核人 收款人 start ****************************************/


            if (StrUtil.isBlank(invoiceBankInfo.getPersonNameInvoice().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入开票人");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getPersonNameReview().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入复核人");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getPersonNameCashier().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入收款人");
            }

            /**************************************** 开票人 复核人 收款人   end ****************************************/


            /**************************************** 单张票面最大限额(不含税) start ****************************************/


            if (ObjectUtil.isEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount1())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入单张票面最大限额（电子普通发票）");
            }

            if (ObjectUtil.isNotEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount1())
                    && (invoiceBankInfo.getSingleInvoiceMaxAmount1().compareTo(new BigDecimal(10000L)) < 0
                    || invoiceBankInfo.getSingleInvoiceMaxAmount1().compareTo(new BigDecimal(10000000L)) > 0)) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入正确的单张票面最大限额[10000-10000000]以内");
            }

            if (ObjectUtil.isEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount2())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入单张票面最大限额（专用发票）");
            }

            if (ObjectUtil.isNotEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount2())
                    && (invoiceBankInfo.getSingleInvoiceMaxAmount2().compareTo(new BigDecimal(10000L)) < 0
                    || invoiceBankInfo.getSingleInvoiceMaxAmount2().compareTo(new BigDecimal(10000000L)) > 0)) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入正确的单张票面最大限额[10000-10000000]以内");
            }

            if (ObjectUtil.isEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount3())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入单张票面最大限额（普通发票）");
            }

            if (ObjectUtil.isNotEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount3())
                    && (invoiceBankInfo.getSingleInvoiceMaxAmount3().compareTo(new BigDecimal(10000L)) < 0
                    || invoiceBankInfo.getSingleInvoiceMaxAmount3().compareTo(new BigDecimal(10000000L)) > 0)) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入正确的单张票面最大限额[10000-10000000]以内");
            }

            if (ObjectUtil.isEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount4())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入单张票面最大限额（电子专用发票）");
            }

            if (ObjectUtil.isNotEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount4())
                    && (invoiceBankInfo.getSingleInvoiceMaxAmount4().compareTo(new BigDecimal(10000L)) < 0
                    || invoiceBankInfo.getSingleInvoiceMaxAmount4().compareTo(new BigDecimal(10000000L)) > 0)) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入正确的单张票面最大限额[10000-10000000]以内");
            }

            /**************************************** 单张票面最大限额(不含税)   end ****************************************/

            List<InvoiceBankInfo> checkExist = invoiceBankInfoDubboConsumerService.query(InvoiceBankInfoQueryCriteria
                    .builder()
                    .companyNameEq(invoiceBankInfo.getCompanyName())
                    .build(), getToken());

            if (CollUtil.isNotEmpty(checkExist)) {
                return ResponseResultOuterUtils.createErrorResult("500", "收款方名称已存在，请重新输入");
            }

            int ret = invoiceBankInfoDubboConsumerService.addInvoiceBankInfo(invoiceBankInfo, getToken());

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

        } catch (Exception e) {
            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
            return ResponseResultOuterUtils.createErrorResult("500", StrUtil.format("{}:{}", e.hashCode(), e.getMessage()));
        }
    }

    @ApiOperation(value = "编辑-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)", notes = "积分结算2.1,伪表单整改")
    @PostMapping("/update")
    @ResponseBody
    public R<String> update(@RequestBody InvoiceBankInfo invoiceBankInfo) {

        log.info("收款方 编辑保存 \n{}", JSONUtil.toJsonPrettyStr(invoiceBankInfo));

        try {

            if (StrUtil.isBlank(invoiceBankInfo.getCompanyName().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入收款方名称");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getBankName().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入开户行名称");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getBankAccount().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入开户行账号");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getSupplyName().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入供货单位");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getAddress().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入地址");
            }

            /**************************************** 开票人 复核人 收款人 start ****************************************/


            if (StrUtil.isBlank(invoiceBankInfo.getPersonNameInvoice().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入开票人");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getPersonNameReview().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入复核人");
            }

            if (StrUtil.isBlank(invoiceBankInfo.getPersonNameCashier().trim())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入收款人");
            }

            /**************************************** 开票人 复核人 收款人   end ****************************************/


            /**************************************** 单张票面最大限额(不含税) start ****************************************/


            if (ObjectUtil.isEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount1())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入单张票面最大限额（电子普通发票）");
            }

            if (ObjectUtil.isNotEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount1())
                    && (invoiceBankInfo.getSingleInvoiceMaxAmount1().compareTo(new BigDecimal(10000L)) < 0
                    || invoiceBankInfo.getSingleInvoiceMaxAmount1().compareTo(new BigDecimal(10000000L)) > 0)) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入正确的单张票面最大限额[10000-10000000]以内");
            }

            if (ObjectUtil.isEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount2())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入单张票面最大限额（专用发票）");
            }

            if (ObjectUtil.isNotEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount2())
                    && (invoiceBankInfo.getSingleInvoiceMaxAmount2().compareTo(new BigDecimal(10000L)) < 0
                    || invoiceBankInfo.getSingleInvoiceMaxAmount2().compareTo(new BigDecimal(10000000L)) > 0)) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入正确的单张票面最大限额[10000-10000000]以内");
            }

            if (ObjectUtil.isEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount3())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入单张票面最大限额（普通发票）");
            }

            if (ObjectUtil.isNotEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount3())
                    && (invoiceBankInfo.getSingleInvoiceMaxAmount3().compareTo(new BigDecimal(10000L)) < 0
                    || invoiceBankInfo.getSingleInvoiceMaxAmount3().compareTo(new BigDecimal(10000000L)) > 0)) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入正确的单张票面最大限额[10000-10000000]以内");
            }

            if (ObjectUtil.isEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount4())) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入单张票面最大限额（电子专用发票）");
            }

            if (ObjectUtil.isNotEmpty(invoiceBankInfo.getSingleInvoiceMaxAmount4())
                    && (invoiceBankInfo.getSingleInvoiceMaxAmount4().compareTo(new BigDecimal(10000L)) < 0
                    || invoiceBankInfo.getSingleInvoiceMaxAmount4().compareTo(new BigDecimal(10000000L)) > 0)) {
                return ResponseResultOuterUtils.createErrorResult("500", "请输入正确的单张票面最大限额[10000-10000000]以内");
            }

            /**************************************** 单张票面最大限额(不含税)   end ****************************************/


            List<InvoiceBankInfo> checkExist = invoiceBankInfoDubboConsumerService.query(InvoiceBankInfoQueryCriteria
                    .builder()
                    .companyNameEq(invoiceBankInfo.getCompanyName())
                    .invoiceBankInfoIdNotIn(Arrays.asList(invoiceBankInfo.getId()))
                    .build(), getToken());

            if (CollUtil.isNotEmpty(checkExist)) {
                return ResponseResultOuterUtils.createErrorResult("500", "收款方名称已存在，请重新输入");
            }

            int ret = invoiceBankInfoDubboConsumerService.updateInvoiceBankInfo(invoiceBankInfo, getToken());

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

        } catch (Exception e) {
            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
            return ResponseResultOuterUtils.createErrorResult("500", StrUtil.format("{}:{}", e.hashCode(), e.getMessage()));
        }
    }

    @ApiOperation(value = "设置默认-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)", notes = "积分结算2.1,伪表单整改")
    @PostMapping("/opSetDefault/{invoiceBankInfoId}")
    @ResponseBody
    public R<String> opSetDefault(@PathVariable Long invoiceBankInfoId) {

        try {

            int ret = invoiceBankInfoDubboConsumerService.opSetDefault(invoiceBankInfoId, getToken());
            if (ret > 0) {
                return ResponseResultOuterUtils.createSuccesResult();
            } else {
                return ResponseResultOuterUtils.createErrorResult("500", "操作失败");
            }

        } catch (Exception e) {
            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
            return ResponseResultOuterUtils.createErrorResult("500", StrUtil.format("{}:{}", e.hashCode(), e.getMessage()));
        }
    }

    @ApiOperation(value = "取消默认-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)", notes = "积分结算2.1,伪表单整改")
    @PostMapping("/opSetNormal/{invoiceBankInfoId}")
    @ResponseBody
    public R<String> opSetNormal(@PathVariable Long invoiceBankInfoId) {

        try {

            int ret = invoiceBankInfoDubboConsumerService.opSetNormal(invoiceBankInfoId, getToken());
            if (ret > 0) {
                return ResponseResultOuterUtils.createSuccesResult();
            } else {
                return ResponseResultOuterUtils.createErrorResult("500", "操作失败");
            }

        } catch (Exception e) {
            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
            return ResponseResultOuterUtils.createErrorResult("500", StrUtil.format("{}:{}", e.hashCode(), e.getMessage()));
        }
    }

    @ApiOperation(value = "物理删除-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)", notes = "积分结算2.1")
    @PostMapping("/opPhysicsDelete/{invoiceBankInfoId}")
    @ResponseBody
    public R<String> opPhysicsDelete(@PathVariable Long invoiceBankInfoId) {

        try {
            int ret = invoiceBankInfoDubboConsumerService.opPhysicsDelete(invoiceBankInfoId, getToken());
            if (ret > 0) {
                return ResponseResultOuterUtils.createSuccesResult();
            } else {
                return ResponseResultOuterUtils.createErrorResult("500", "操作失败");
            }

        } catch (Exception e) {
            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
            return ResponseResultOuterUtils.createErrorResult("500", StrUtil.format("{}:{}", e.hashCode(), e.getMessage()));
        }
    }

    @ApiOperation(value = "逻辑删除-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)", notes = "积分结算2.1")
    @PostMapping("/opLogicalDelete/{invoiceBankInfoId}")
    @ResponseBody
    public R<String> opLogicalDelete(@PathVariable Long invoiceBankInfoId) {

        try {

            int ret = invoiceBankInfoDubboConsumerService.opLogicalDelete(invoiceBankInfoId, getToken());
            if (ret > 0) {
                return ResponseResultOuterUtils.createSuccesResult();
            } else {
                return ResponseResultOuterUtils.createErrorResult("500", "操作失败");
            }

        } catch (Exception e) {
            log.error(ExceptionUtils.getMessage(e));
            e.printStackTrace();
            return ResponseResultOuterUtils.createErrorResult("500", StrUtil.format("{}:{}", e.hashCode(), e.getMessage()));
        }

    }


    /****************************************** 缓存 start ******************************************/

    /**
     * http://192.168.6.223:8089/web/setting/unifiedBankInfo/cacheInit
     *
     * @return
     */
    @ApiOperation(value = "缓存-cacheInit-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)")
    @RequestMapping(value = "cacheInit", method = RequestMethod.POST)
    @ResponseBody
    public R<String> cacheInit() {

        invoiceBankInfoDubboConsumerService.cacheInit();
        return new R<>("200", "操作成功", true);

    }

    @ApiOperation(value = "缓存-cacheRefresh-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)")
    @RequestMapping(value = "cacheRefresh", method = RequestMethod.POST)
    @ResponseBody
    public R<String> cacheRefresh() {

        invoiceBankInfoDubboConsumerService.cacheRefresh();
        return new R<>("200", "操作成功", true);

    }

    @ApiOperation(value = "缓存-cacheRemove-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)")
    @RequestMapping(value = "cacheRemove", method = RequestMethod.POST)
    @ResponseBody
    public R<String> cacheRemove() {

        invoiceBankInfoDubboConsumerService.cacheRemove();
        return new R<>("200", "操作成功", true);

    }


    /**
     * hashtable relation:sys_enterprise_ext_invoice:company_name field 中航物业管理有限公司济南分公司
     * <p>
     * {
     * "conditions": {
     * "hashTable": "relation:sys_enterprise_ext_invoice:company_name",
     * "keyField": "中航物业管理有限公司长沙分公司"
     * }
     * }
     *
     * @return
     */
    @ApiOperation(value = "缓存-cacheGet-系统设置-收款方(平台给企业开票,企业给平台付款)付款方(供应商|商户给平台开票,平台给供应商|商户付款)发票信息(银行信息)")
    @RequestMapping(value = "cacheGet", method = RequestMethod.POST)
    @ResponseBody
    public R<String> cacheGet(@RequestBody PageQueryParam param) {

//		String hashTable = "relation:sys_enterprise_ext_invoice:company_name";
//		String keyField = "中航物业管理有限公司";

        String hashTable = AnStringUtils.getString(param.getConditions().get("hashTable"));
        String keyField = AnStringUtils.getString(param.getConditions().get("keyField"));

        log.info("{}{}", hashTable, keyField);

        String responseData = invoiceBankInfoDubboConsumerService.cacheGet(hashTable, keyField);
        return new R<>("200", "操作成功", responseData);

    }
}
