package com.jwipc.sys.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jwipc.api.OaCallBackLogic;
import com.jwipc.constant.DictCode;
import com.jwipc.constant.OaProcessType;
import com.jwipc.api.constant.OaStatus;
import com.jwipc.api.constant.RestCode;
import com.jwipc.api.dto.ApiResult;
import com.jwipc.api.dto.OaCallBackDTO;
import com.jwipc.log.annotation.ApiOperateLog;
import com.jwipc.log.constant.ApiDirection;
import com.jwipc.log.constant.ThirdSysType;
import com.jwipc.supplier.constant.VersionChangeType;
import com.jwipc.supplier.convert.SupplierBankConvert;
import com.jwipc.supplier.entity.*;
import com.jwipc.supplier.service.*;
import com.jwipc.sys.client.DictClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

import static com.jwipc.constant.DictCode.CURRENCY;
import static com.jwipc.constant.DictCode.DELIVERY_TYPE;

/**
 * <p> </p>
 *
 * @author ZhangJie
 * @version 1.0
 * @since JDK 1.8
 */
@RestController
@RequestMapping("/oa/api")
@RequiredArgsConstructor
@Slf4j
public class OaCallBackController {

    @Autowired
    private List<OaCallBackLogic> oaCallBackLogicList;

    private final ISupplierBankService supplierBankService;

    private final ISupplierBankInfoService supplierBankInfoService;

    private final SupplierBankConvert supplierBankConvert;

    private final ISupplierPurchaseCategoryService supplierPurchaseCategoryService;

    private final ISupplierService supplierService;

    private final DictClient dictClient;

    private final ISupplierChangeVersionService supplierChangeVersionService;

    private final ISupplierBankVersionService supplierBankVersionService;

    private final ISupplierPurchaseCategoryVersionService supplierPurchaseCategoryVersionService;

    private final ISupplierExtensionVersionService supplierExtensionVersionService;






    @PostMapping("callback")
    @ApiOperateLog(code = "callBack", name = "OA回调SRM", direction = ApiDirection.OTHER_TO_SRM,
            thirdSysType = ThirdSysType.OA)
    public ApiResult callBack(@RequestBody OaCallBackDTO callBackDTO) {
        log.info("{}", callBackDTO);
        for (OaCallBackLogic service : oaCallBackLogicList) {
            final OaProcessType processType = service.getProcessType();
            if (callBackDTO.getIT_DATA().type == processType.getType()) {
                return service.processor(callBackDTO.getIT_DATA().workflowId,
                        OaStatus.forVal(callBackDTO.getIT_DATA().auditState),
                        callBackDTO.getIT_DATA().auditMessage, callBackDTO.getIT_DATA().processCode,
                        callBackDTO.getIT_DATA().code,
                        callBackDTO.getIT_DATA().list);
            }
            if (callBackDTO.getIT_DATA().type == processType.SUPPLIER_ACCESS.getType()
                    ||callBackDTO.getIT_DATA().type == processType.SUPPLIER_IMPORT_ACCESS.getType()
                    ||callBackDTO.getIT_DATA().type == processType.SUPPLIER_CHANGE.getType()) {
                Long   supplierId=null;
                if(callBackDTO.getIT_DATA().type == processType.SUPPLIER_CHANGE.getType()){
                    final List<SupplierChangeVersion> list = supplierChangeVersionService.list(
                            new LambdaQueryWrapper<SupplierChangeVersion>()
                                    .eq(SupplierChangeVersion::getBpmCode, callBackDTO.getIT_DATA().workflowId));
                    List<SupplierBankInfo> supplierBankInfos = new ArrayList<>();
                    supplierId=list.get(0).getSupplierId();
                    final Supplier supplier = supplierService.getById(supplierId);

                    final List<SupplierExtensionVersion> supplierExtensionVersions = supplierExtensionVersionService.list(
                            new LambdaQueryWrapper<SupplierExtensionVersion>()
                                    .eq(SupplierExtensionVersion::getChangeVersionId, list.get(0).getId())
                                    .eq(SupplierExtensionVersion::getExtensionKey, "colBeiyOne"));
                     //查询之前供应商银行信息
                    List<SupplierBank> supplierBanks = supplierBankService.list(
                            new LambdaQueryWrapper<SupplierBank>().eq(SupplierBank::getSupplierId, supplierId));
                     //对新增修改删除的数据进行整合
                    final List<SupplierBankVersion> supplierBankVersionList = supplierBankVersionService.list(
                            new LambdaQueryWrapper<SupplierBankVersion>().eq(SupplierBankVersion::getChangeVersionId, list.get(0).getId()));
                    if (CollUtil.isNotEmpty(supplierBankVersionList)) {
                        supplierBankVersionList.forEach(e -> {
                            if (Objects.nonNull(e.getType())) {
                                final VersionChangeType versionChangeType = VersionChangeType.forEach(e.getType());
                                switch (versionChangeType) {
                                    case CREATE:
                                        final SupplierBank insert = new SupplierBank();
                                        insert.setId(UUID.randomUUID().getMostSignificantBits());
                                        insert.setSupplierId(list.get(0).getSupplierId());
                                        insert.setOpeningBankName(e.getOpeningBankName());
                                        insert.setCardholderName(e.getCardholderName());
                                        insert.setBankAccount(e.getBankAccount());
                                        insert.setBankCode(e.getBankCode());
                                        insert.setBankAddress(e.getBankAddress());
                                        insert.setCompanyCode(e.getCompanyCode());
                                        insert.setCompanyName(e.getCompanyName());
                                        insert.setBankInterCode(e.getBankInterCode());
                                        e.setMasterId(insert.getId());
                                        supplierBanks.add(insert);
                                        break;
                                    case EDIT:
                                        final SupplierBank update = new SupplierBank();
                                        List<SupplierBank> s1= supplierBanks.stream().filter(s -> s.getId().equals(e.getMasterId())).collect(Collectors.toList());
                                        supplierBanks.remove(s1.get(0));
                                        update.setId(e.getMasterId());
                                        update.setSupplierId(list.get(0).getSupplierId());
                                        update.setOpeningBankName(e.getOpeningBankName());
                                        update.setCardholderName(e.getCardholderName());
                                        update.setBankAccount(e.getBankAccount());
                                        update.setBankCode(e.getBankCode());
                                        update.setBankAddress(e.getBankAddress());
                                        update.setBankInterCode(e.getBankInterCode());
                                        update.setCompanyCode(e.getCompanyCode());
                                        update.setCompanyName(e.getCompanyName());
                                        supplierBanks.add(update);
                                        break;
                                    case DEL:
                                        List<SupplierBank> s2= supplierBanks.stream().filter(s -> s.getId().equals(e.getMasterId())).collect(Collectors.toList());
                                        supplierBanks.remove(s2.get(0));                                    break;
                                }
                            }
                        });
                    }

                    supplierBankInfos = supplierBankConvert.bank2SupplierBank(supplierBanks);
                    String currencyCode=null;
                    final List<SupplierPurchaseCategoryVersion> supplierProductTypeVersionList =
                            supplierPurchaseCategoryVersionService.list(
                                    new LambdaQueryWrapper<SupplierPurchaseCategoryVersion>().eq(
                                            SupplierPurchaseCategoryVersion::getChangeVersionId, list.get(0).getId()));
                    if(CollectionUtil.isNotEmpty(supplierProductTypeVersionList)){
                         currencyCode = supplierProductTypeVersionList.get(0).getCurrencyCode();
                    }else{
                        final List<SupplierPurchaseCategory> supplierPurchaseCategories = supplierPurchaseCategoryService.list(
                                new LambdaQueryWrapper<SupplierPurchaseCategory>()
                                        .eq(SupplierPurchaseCategory::getSupplierId, supplierId));
                         currencyCode = supplierPurchaseCategories.get(0).getCurrencyCode();

                    }
                    //推送供应商银行信息到中间库
                    final Map<String, String> dictCache = dictClient.getDicMapByType(CURRENCY.getCode());
                    String currencyName = dictCache.get(currencyCode);
                    String finalCurrencyCode = currencyCode;
                    supplierBankInfos.stream().forEach(supplierBankInfo ->{
                        supplierBankInfo.setSupplierCode(callBackDTO.getIT_DATA().code);
                        supplierBankInfo.setSupplierName(supplier.getSupplierName());
                        supplierBankInfo.setCurrencyCode(finalCurrencyCode);
                        supplierBankInfo.setCurrencyName(currencyName);
                        if(CollectionUtil.isNotEmpty(supplierExtensionVersions)){
                            supplierBankInfo.setSupplierRegister(supplierExtensionVersions.get(0).getExtensionValue());
                        }
                    });
                    //若中间表有此供应商银行信息，先清除数据再保存
                    List<Long> ids=  new ArrayList<>();
                    ids.add(supplier.getId());
                    supplierBankInfoService.deleteBySupplieId(ids);
                    supplierBankInfoService.saveSupplierBankInfos(supplierBankInfos);
                }else{
                    final List<SupplierPurchaseCategory> list = supplierPurchaseCategoryService.list(
                            new LambdaQueryWrapper<SupplierPurchaseCategory>()
                                    .eq(SupplierPurchaseCategory::getOaId, callBackDTO.getIT_DATA().workflowId));
                    supplierId=list.get(0).getSupplierId();

                    final Supplier supplier = supplierService.getById(supplierId);
                    //推送供应商银行信息到中间库
                    final List<SupplierBank> supplierBanks = supplierBankService.list(
                            new LambdaQueryWrapper<SupplierBank>().eq(SupplierBank::getSupplierId, supplier.getId()));
                    List<SupplierBankInfo> supplierBankInfos = supplierBankConvert.bank2SupplierBank(supplierBanks);
                    final Map<String, String> dictCache = dictClient.getDicMapByType(CURRENCY.getCode());
                    final List<SupplierPurchaseCategory> supplierPurchaseCategories = supplierPurchaseCategoryService.list(
                            new LambdaQueryWrapper<SupplierPurchaseCategory>()
                                    .eq(SupplierPurchaseCategory::getSupplierId, supplierId));
                    String currencyName = dictCache.get(list.get(0).getCurrencyCode());
                    supplierBankInfos.stream().forEach(supplierBankInfo ->{
                        supplierBankInfo.setSupplierCode(callBackDTO.getIT_DATA().code);
                        if(CollectionUtil.isNotEmpty(supplierPurchaseCategories)){
                            supplierBankInfo.setCurrencyCode(supplierPurchaseCategories.get(0).getCurrencyCode());
                        }
                        supplierBankInfo.setCurrencyName(currencyName);
                        supplierBankInfo.setSupplierRegister(supplier.getColBeiyOne());
                    });
                    //若中间表有此供应商银行信息，先清除数据再保存
                    List<Long> ids=  new ArrayList<>();
                    ids.add(supplierId);
                    supplierBankInfoService.deleteBySupplieId(ids);
                    supplierBankInfoService.saveSupplierBankInfos(supplierBankInfos);
                }



            }
        }
        return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message("未找到业务处理逻辑").build();
    }
}
