package com.crm.ucard.controller;

import com.alibaba.fastjson.JSON;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.dto.wasabi.*;
import com.crm.rely.backend.core.pojo.table.ucard.SysUcardConfigTable;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.ucard.config.WasabiConfig;
import com.crm.ucard.service.SysUcardConfigService;
import com.crm.ucard.service.UcardNotifyService;
import com.crm.ucard.util.RsaUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequestMapping("/wasabi")
public class WasabiCardNotifyController {

    @Autowired
    private SysUcardConfigService sysUcardConfigService;
    @Autowired
    private UcardNotifyService ucardNotifyService;

    @PostMapping("/callback")
    public WasabiNotifyResultDto notify(@RequestHeader("x-wsb-category") String category,
                                @RequestHeader("x-wsb-signature") String signature,
                                @RequestHeader("x-wsb-request-id") String requestId,
                                @RequestBody String request) throws Exception {
        try {
            log.info("wasabi回调通知开始：" + category + ":" + JSON.toJSONString(request));
            WasabiConfig config = getWasabiConfig();
            // 验证签名
            if (!RsaUtils.verify(request, config.getWsbPublicKey(), signature)) {
                return WasabiNotifyResultDto.error();
            }
            switch (category) {
                case "card_transaction":
                    WasabiTransactionDto transactionNotifyDto = JSON.parseObject(request, WasabiTransactionDto.class);
                    ucardNotifyService.cardTransactionNotify(transactionNotifyDto);
                    break;
                case "card_auth_transaction":
                    WasabiAuthTransactionDto authTransactionNotifyDto = JSON.parseObject(request, WasabiAuthTransactionDto.class);
                    ucardNotifyService.cardAuthTransactionNotify(authTransactionNotifyDto);
                    break;
                case "card_fee_patch":
                    WasabiFeePatchNotifyDto feePatchNotifyDto = JSON.parseObject(request, WasabiFeePatchNotifyDto.class);
                    ucardNotifyService.cardFeePatchNotify(feePatchNotifyDto);
                    break;
                case "card_3ds":
                    WasabiThird3dsTransactionDto card3dsNotifyDto = JSON.parseObject(request, WasabiThird3dsTransactionDto.class);
                    ucardNotifyService.card3dsNotify(card3dsNotifyDto);
                    break;
                case "card_holder":
                    WasabiHolderQueryDto holderNotifyDto = JSON.parseObject(request, WasabiHolderQueryDto.class);
                    ucardNotifyService.cardHolderNotify(holderNotifyDto);
                    break;
                case "physical_card":
                    WasabiPhysicalCardNotifyDto physicalCardNotifyDto = JSON.parseObject(request, WasabiPhysicalCardNotifyDto.class);
                    ucardNotifyService.physicalCardNotify(physicalCardNotifyDto);
                    break;
                case "work":
                    break;
                case "gt_transaction":
                    WasabiTransactionTransferDto transferDto = JSON.parseObject(request, WasabiTransactionTransferDto.class);
                    ucardNotifyService.expressRemittanceTransactionNotify(transferDto);
                    break;
                default:
                    return WasabiNotifyResultDto.error();
            }
            log.info("wasabi回调通知结束");
            return WasabiNotifyResultDto.success();
        } catch (Exception e) {
            log.error("wasabi回调通知处理失败",e);
            return WasabiNotifyResultDto.error();
        }
    }

    public WasabiConfig getWasabiConfig() throws Exception {
        SysUcardConfigTable sysUcardConfigTable = sysUcardConfigService.getByCode(Constants.WASABI_CARD);
        if (sysUcardConfigTable == null) {
            throw ServiceException.exception(Constants.SYSTEM_ERROR);
        }
        WasabiConfig wasabiConfig = JSON.parseObject(sysUcardConfigTable.getValue(), WasabiConfig.class);
        return wasabiConfig;
    }

}
