package cn.superdesk.uniorder.controller._common;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.superdesk.libs.common.json.JsonUtils;
import cn.superdesk.uniorder.common.bizScene.invoice.common.InvoiceTypeScene;
import cn.superdesk.uniorder.common.enums.common.CommonEnabledEnum;
import cn.superdesk.uniorder.common.enums.invoice.common.InvoiceTypeEnum;
import cn.superdesk.uniorder.common.enums.invoice.customer.*;
import cn.superdesk.uniorder.common.enums.invoice.supplier.*;
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.InvoiceType;
import cn.superdesk.uniorder.dao.utils.AnEntitySortedListUtils;
import cn.superdesk.uniorder.dto.param.invoice.common.InvoiceTypeQueryCriteria;
import cn.superdesk.uniorder.dto.utils.AnDtoSortedListUtils;
import cn.superdesk.uniorder.dto.vo._common.EnumSelectIntegerStringVo;
import cn.superdesk.uniorder.dto.vo.invoice.common.InvoiceTypeSelectVo;
import cn.superdesk.uniorder.dubbo.consumer.invoice.common.InvoiceTypeDubboConsumerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Description: Java类作用描述
 * @Author: linjinyu
 * @CreateDate: 2022/5/13 3:40 下午
 * @UpdateUser: linjinyu
 * @UpdateDate: 2022/5/13 3:40 下午
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Api(value = "公共接口-下拉列表-发票申请(发票单)", tags = {"公共接口-下拉列表-发票申请(发票单)"})
@Slf4j
@RestController
@RequestMapping("/common/select/invoice")
public class CommonSelectInvoiceController extends BaseController {


    @Autowired
    private InvoiceTypeDubboConsumerService invoiceTypeDubboConsumerService;


    /**
     * /common/select/invoice/type/select/by/module
     *
     * @param queryCriteria
     * @return
     */
    @ApiOperation(value = "发票种类-下拉不分页-区分模块(包含 客户结算(customerGoods)|积分结算(customerCredit)|供应商结算(supplierGoods))--前端处理-selectBy{customerGoods|customerCredit|supplierGoods}", notes = "积分结算2.1")
    @RequestMapping(value = "type/select/by/module", method = RequestMethod.POST)
    @ResponseBody
    public R<List<InvoiceTypeSelectVo>> selectQueryByModule(@RequestBody InvoiceTypeQueryCriteria queryCriteria) {


        //		customer_goods(客户结算),customer_credit(积分结算),supplier_goods(供应商结算)

        if (ObjectUtil.isEmpty(queryCriteria.getSelectByModule())) {
            return ResponseResultOuterUtils.createErrorResult("500", "参数未指定");
        } else {

            if (!ArrayUtil.contains(
                    InvoiceTypeScene.modulesV2_1_Array_SceneParamCheck(),
                    queryCriteria.getSelectByModule())
            ) {
                return ResponseResultOuterUtils.createErrorResult("500", "非法参数");
            }
        }

//        【【结算中心-测试环境】【前端&后端处理】积分结算-金税盘发票，筛选条件的“发票种类”显示不需要与“数据管理-发票种类”的启用/停用联动。】https://www.tapd.cn/33003868/bugtrace/bugs/view?bug_id=1133003868001004865
//        创建时间
//        2022-03-31 12:50:36
//        创建人  李立权
        // 是否强行突破是否启用限制:0-不;1-强行突破
        queryCriteria.setBreakthroughEnabled(CommonEnabledEnum.禁用.getKey());

        log.info("selectQuery:\n{}", JsonUtils.toJson(queryCriteria));

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

        // TODO 参数合法性判定

        List<InvoiceTypeSelectVo> targetList = invoiceTypeDubboConsumerService.selectQuery(queryCriteria, getToken());
        List<Long> orderList = Arrays.asList(
                InvoiceTypeEnum.电子普通发票.getKey(),
                InvoiceTypeEnum.电子专用发票.getKey(),
                InvoiceTypeEnum.纸质普通发票.getKey(),
                InvoiceTypeEnum.纸质专用发票.getKey()
        );
        AnDtoSortedListUtils.sortInvoiceTypeSelectVoTargetList1(orderList, targetList);

        result.setData(targetList);

        return result;
    }

    /**
     * /common/select/invoice/type/select/by/module/breakthroughEnabled
     *
     * @param queryCriteria
     * @return
     */
    @ApiOperation(value = "发票种类-下拉不分页-区分模块-强行突破(包含 客户结算(customerGoods)|积分结算(customerCredit)|供应商结算(supplierGoods))--前端处理-selectBy{customerGoods|customerCredit|supplierGoods}", notes = "积分结算2.1")
    @RequestMapping(value = "type/select/by/module/breakthroughEnabled", method = RequestMethod.POST)
    @ResponseBody
    public R<List<InvoiceTypeSelectVo>> selectQueryByModuleBreakthroughEnabled(@RequestBody InvoiceTypeQueryCriteria queryCriteria) {


        //		customer_goods(客户结算),customer_credit(积分结算),supplier_goods(供应商结算)

        if (ObjectUtil.isEmpty(queryCriteria.getSelectByModule())) {
            return ResponseResultOuterUtils.createErrorResult("500", "参数未指定");
        } else {
            if (!ArrayUtil.contains(
                    InvoiceTypeScene.modulesV2_1_Array_SceneParamCheck(),
                    queryCriteria.getSelectByModule())
            ) {
                return ResponseResultOuterUtils.createErrorResult("500", "非法参数");
            }
        }

//        【【结算中心-测试环境】【前端&后端处理】积分结算-金税盘发票，筛选条件的“发票种类”显示不需要与“数据管理-发票种类”的启用/停用联动。】https://www.tapd.cn/33003868/bugtrace/bugs/view?bug_id=1133003868001004865
//        创建时间
//        2022-03-31 12:50:36
//        创建人  李立权
        // 是否强行突破是否启用限制:0-不;1-强行突破
        queryCriteria.setBreakthroughEnabled(CommonEnabledEnum.启用.getKey());

        log.info("selectQuery:\n{}", JsonUtils.toJson(queryCriteria));

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

        // TODO 参数合法性判定


        List<InvoiceTypeSelectVo> targetList = invoiceTypeDubboConsumerService.selectQuery(queryCriteria, getToken());

        List<Long> orderList = Arrays.asList(
                InvoiceTypeEnum.电子普通发票.getKey(),
                InvoiceTypeEnum.电子专用发票.getKey(),
                InvoiceTypeEnum.纸质普通发票.getKey(),
                InvoiceTypeEnum.纸质专用发票.getKey()
        );
        AnDtoSortedListUtils.sortInvoiceTypeSelectVoTargetList1(orderList, targetList);

        result.setData(targetList);

        return result;
    }


    /**
     * /common/select/invoice/type
     *
     * @param queryCriteria
     * @return
     */
    @ApiOperation(value = "发票种类-可扩展以人为基础的使用习惯返回排序", notes = "积分结算2.0")
    @RequestMapping(value = "type", method = RequestMethod.POST)
    @ResponseBody
    public R<List<InvoiceType>> selectQueryByInvoiceTypes(@RequestBody InvoiceTypeQueryCriteria queryCriteria) {


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

        // TODO 参数合法性判定

        result = invoiceTypeDubboConsumerService.pageQuery(queryCriteria, getToken());

        List<InvoiceType> targetList = result.getData();

        List<Long> orderList = Arrays.asList(
                InvoiceTypeEnum.电子普通发票.getKey(),
                InvoiceTypeEnum.电子专用发票.getKey(),
                InvoiceTypeEnum.纸质普通发票.getKey(),
                InvoiceTypeEnum.纸质专用发票.getKey()
        );
        AnEntitySortedListUtils.sortInvoiceTypeTargetList1(orderList, targetList);

        return result;
    }

    /**************************************** 积分结算 客户结算 start ****************************************/

    @ApiOperation(value = "回款状态-发票申请(发票单)-积分结算", notes = "积分结算2.1")
    @RequestMapping(value = "/customer/backAccountStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplyCustomerBackAccountStatusEnum() {

        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplyCustomerBackAccountStatusEnum value : InvoiceApplyCustomerBackAccountStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }


        List<Integer> orderList = Arrays.asList(
                InvoiceApplyCustomerBackAccountStatusEnum.未回款.getKey(),
//                InvoiceApplyCustomerBackAccountStatusEnum.回款中.getKey(),
//                InvoiceApplyCustomerBackAccountStatusEnum.部分回款.getKey(),
                InvoiceApplyCustomerBackAccountStatusEnum.已回款.getKey(),
//                InvoiceApplyCustomerBackAccountStatusEnum.发票蓝冲.getKey(),
                InvoiceApplyCustomerBackAccountStatusEnum.发票红冲.getKey(),
                InvoiceApplyCustomerBackAccountStatusEnum.发票作废.getKey()

        );
        AnDtoSortedListUtils.sortEnumSelectIntegerStringVo(orderList, selectVos);

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }

    @ApiOperation(value = "申请状态-发票申请(发票单)-积分结算", notes = "积分结算2.1")
    @RequestMapping(value = "/customer/invoiceProgressingStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplyCustomerInvoiceProgressingStatusEnum() {

        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplyCustomerInvoiceProgressingStatusEnum value : InvoiceApplyCustomerInvoiceProgressingStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }

//        【2. 积分结算-2.2 发票申请管理-2.2.1 数据【新增“已作废”】-已整理-20220406】
//        https://www.tapd.cn/33003868/prong/stories/view/1133003868001004182
//        待开票/待领票/待寄票/待回款/已完成/已红冲/已作废
        List<Integer> orderList = Arrays.asList(
                InvoiceApplyCustomerInvoiceProgressingStatusEnum.待开票.getKey(),
                InvoiceApplyCustomerInvoiceProgressingStatusEnum.待领票.getKey(),
                InvoiceApplyCustomerInvoiceProgressingStatusEnum.待寄票.getKey(),
                InvoiceApplyCustomerInvoiceProgressingStatusEnum.待回款.getKey(),
                InvoiceApplyCustomerInvoiceProgressingStatusEnum.已完成.getKey(),
                InvoiceApplyCustomerInvoiceProgressingStatusEnum.已红冲.getKey(),
                InvoiceApplyCustomerInvoiceProgressingStatusEnum.已作废.getKey()
        );
        AnDtoSortedListUtils.sortEnumSelectIntegerStringVo(orderList, selectVos);

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }

    @ApiOperation(value = "子项-回款状态-发票申请(发票单)-积分结算", notes = "积分结算2.1")
    @RequestMapping(value = "/customer/itemBackStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplyCustomerItemBackStatusEnum() {

        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplyCustomerBackAccountStatusEnum value : InvoiceApplyCustomerBackAccountStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }

    @ApiOperation(value = "寄票状态-发票申请(发票单)-积分结算", notes = "积分结算2.1")
    @RequestMapping(value = "/customer/mailTickStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplyCustomerMailTickStatusEnum() {
        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplyCustomerMailTickStatusEnum value : InvoiceApplyCustomerMailTickStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }

    @ApiOperation(value = "开票状态-发票申请(发票单)-积分结算", notes = "积分结算2.1")
    @RequestMapping(value = "/customer/makeInvoiceStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplyCustomerMakeInvoiceStatusEnum() {
        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplyCustomerMakeInvoiceStatusEnum value : InvoiceApplyCustomerMakeInvoiceStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }

    @ApiOperation(value = "领票状态-发票申请(发票单)-积分结算", notes = "积分结算2.1")
    @RequestMapping(value = "/customer/receiveInvoiceStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplyCustomerReceiveInvoiceStatusEnum() {

        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplyCustomerReceiveInvoiceStatusEnum value : InvoiceApplyCustomerReceiveInvoiceStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }

    /**************************************** 积分结算 客户结算   end ****************************************/

    /**************************************** 供应商结算 start ****************************************/

    @ApiOperation(value = "申请状态(流程节点)-供应商结算")
    @RequestMapping(value = "/supplier/invoiceProgressingStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplySupplierInvoiceProgressingStatusEnum() {

        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplySupplierInvoiceProgressingStatusEnum value : InvoiceApplySupplierInvoiceProgressingStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }

        List<Integer> orderList = Arrays.asList(
                InvoiceApplySupplierInvoiceProgressingStatusEnum.未申请.getKey(),
                InvoiceApplySupplierInvoiceProgressingStatusEnum.待开票.getKey(),
                InvoiceApplySupplierInvoiceProgressingStatusEnum.待寄票.getKey(),
                InvoiceApplySupplierInvoiceProgressingStatusEnum.待收票.getKey(),
                InvoiceApplySupplierInvoiceProgressingStatusEnum.待付款.getKey(),
                InvoiceApplySupplierInvoiceProgressingStatusEnum.已完成.getKey(),
                InvoiceApplySupplierInvoiceProgressingStatusEnum.已作废.getKey()
        );

        AnDtoSortedListUtils.sortEnumSelectIntegerStringVo(orderList, selectVos);

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }

    @ApiOperation(value = "是否已付款(特指细项)-供应商结算")
    @RequestMapping(value = "/supplier/itemPayOffStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplySupplierItemPayOffStatusEnum() {

        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplySupplierItemPayOffStatusEnum value : InvoiceApplySupplierItemPayOffStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }

        List<Integer> orderList = Arrays.asList(
                InvoiceApplySupplierItemPayOffStatusEnum.待付款.getKey(),
                InvoiceApplySupplierItemPayOffStatusEnum.已付款.getKey()

        );
        AnDtoSortedListUtils.sortEnumSelectIntegerStringVo(orderList, selectVos);

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }

    @ApiOperation(value = "寄票状态-供应商结算")
    @RequestMapping(value = "/supplier/mailTickStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplySupplierMailTickStatusEnum() {

        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplySupplierMailTickStatusEnum value : InvoiceApplySupplierMailTickStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }

        List<Integer> orderList = Arrays.asList(
                InvoiceApplySupplierMailTickStatusEnum.未邮寄.getKey(),
                InvoiceApplySupplierMailTickStatusEnum.已邮寄.getKey()
        );
        AnDtoSortedListUtils.sortEnumSelectIntegerStringVo(orderList, selectVos);

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }

    @ApiOperation(value = "开票状态-供应商结算")
    @RequestMapping(value = "/supplier/makeInvoiceStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplySupplierMakeInvoiceStatusEnum() {

        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplySupplierMakeInvoiceStatusEnum value : InvoiceApplySupplierMakeInvoiceStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }

        List<Integer> orderList = Arrays.asList(
                InvoiceApplySupplierMakeInvoiceStatusEnum.未开票.getKey(),
                InvoiceApplySupplierMakeInvoiceStatusEnum.已开票.getKey(),
                InvoiceApplySupplierMakeInvoiceStatusEnum.已撤消.getKey()
        );
        AnDtoSortedListUtils.sortEnumSelectIntegerStringVo(orderList, selectVos);

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }

    @ApiOperation(value = "是否付款_付款状态-供应商结算")
    @RequestMapping(value = "/supplier/payOffAccountStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplySupplierPayOffAccountStatusEnum() {

        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplySupplierPayOffAccountStatusEnum value : InvoiceApplySupplierPayOffAccountStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }

        List<Integer> orderList = Arrays.asList(
                InvoiceApplySupplierPayOffAccountStatusEnum.待付款.getKey(),
                InvoiceApplySupplierPayOffAccountStatusEnum.付款中.getKey(),
                InvoiceApplySupplierPayOffAccountStatusEnum.已付款.getKey()
        );
        AnDtoSortedListUtils.sortEnumSelectIntegerStringVo(orderList, selectVos);

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }

    @ApiOperation(value = "收票状态-供应商结算")
    @RequestMapping(value = "/supplier/receiveInvoiceStatus", method = RequestMethod.POST)
    @ResponseBody
    public R<List<EnumSelectIntegerStringVo>> selectInvoiceApplySupplierReceiveInvoiceStatusEnum() {

        List<EnumSelectIntegerStringVo> selectVos = new ArrayList<>();

        for (InvoiceApplySupplierReceiveInvoiceStatusEnum value : InvoiceApplySupplierReceiveInvoiceStatusEnum.values()) {
            selectVos.add(EnumSelectIntegerStringVo
                    .builder()
                    .key(value.getKey())
                    .desc(value.getDesc())
                    .build()
            );
        }

        List<Integer> orderList = Arrays.asList(
                InvoiceApplySupplierReceiveInvoiceStatusEnum.未收票.getKey(),
                InvoiceApplySupplierReceiveInvoiceStatusEnum.已收票.getKey()
        );
        AnDtoSortedListUtils.sortEnumSelectIntegerStringVo(orderList, selectVos);

        return ResponseResultOuterUtils.createSuccesResult("SUCCESS", selectVos);
    }


    /**************************************** 供应商结算   end ****************************************/


}
