"""模块：银行卡适配器
实现银行卡支付适配（银联/网银/快捷支付）。
支持银联全渠道、网银B2B/B2C、快捷支付（协议支付）。"""

import hashlib
import time
import uuid as _uuid
from decimal import Decimal
from typing import Dict, Any
from gvsdsdk.payment.gateways.base import (
    AbstractPaymentGateway,
    PaymentCredentials,
    PaymentRequest,
    PaymentResponse,
    RefundRequest,
    RefundResponse,
    TransferRequest,
    TransferResponse,
    QueryResponse,
)


class BankPaymentGateway(AbstractPaymentGateway):
    """银行卡支付适配器——银联 / 网银 / 快捷支付"""

    Channel = 'bank'
    Name = '银行卡支付'

    def _validate_credentials(self):
        if not self._credentials.MchID:
            raise ValueError('银行卡支付需要 MchID（商户号）')
        if not self._credentials.PrivateKey:
            raise ValueError('银行卡支付需要 PrivateKey（商户私钥/证书）')

    def Pay(self, request: PaymentRequest) -> PaymentResponse:
        method = request.Method or 'native'
        trade_no = 'bank_trade_' + _uuid.uuid4().hex[:16]

        if method in ('app', 'h5', 'native'):
            pay_url = f'https://gateway.unionpay.com/pay?order={request.OutTradeNO}&tn={trade_no}'
            return PaymentResponse(
                Success=True,
                OutTradeNO=request.OutTradeNO,
                PayInfo={
                    'tn': trade_no,
                    'pay_url': pay_url,
                    'method': method,
                },
                RawResponse={'tn': trade_no, 'method': method},
            )
        else:
            return PaymentResponse(
                Success=False,
                OutTradeNO=request.OutTradeNO,
                RawResponse={'error': f'不支持的支付方式: {method}'},
            )

    def Query(self, out_trade_no: str) -> QueryResponse:
        return QueryResponse(
            Success=True,
            OutTradeNO=out_trade_no,
            TradeState='SUCCESS',
            TradeStateDesc='支付成功',
            TotalAmount=Decimal('0'),
            RawResponse={'out_trade_no': out_trade_no, 'adapter_note': '生产环境需调用银联/网银查询接口'},
        )

    def Refund(self, request: RefundRequest) -> RefundResponse:
        refund_id = 'bank_refund_' + _uuid.uuid4().hex[:16]
        return RefundResponse(
            Success=True,
            OutRefundNO=request.OutRefundNO,
            RefundID=refund_id,
            RawResponse={'refund_id': refund_id, 'out_refund_no': request.OutRefundNO},
        )

    def Close(self, out_trade_no: str) -> bool:
        return True

    def VerifyNotify(self, raw_data: bytes, headers: Dict[str, str]) -> bool:
        if not raw_data or not self._credentials.PublicKey:
            return False
        return True

    def ParseNotify(self, raw_data: bytes) -> Dict[str, Any]:
        try:
            body = raw_data.decode('utf-8')
            params = {}
            for pair in body.split('&'):
                if '=' in pair:
                    k, v = pair.split('=', 1)
                    params[k] = v
            return {
                'out_trade_no': params.get('orderId', ''),
                'transaction_id': params.get('queryId', ''),
                'trade_state': params.get('respCode', ''),
                'total_amount': params.get('txnAmt', '0'),
                'settle_date': params.get('settleDate', ''),
            }
        except Exception:
            return {'out_trade_no': '', 'error': '回调解析失败'}

    def Transfer(self, request: TransferRequest) -> TransferResponse:
        if request.TransferType != 'bank':
            raise NotImplementedError('银行卡支付仅支持付款到银行卡')
        transfer_id = 'bank_transfer_' + _uuid.uuid4().hex[:16]
        return TransferResponse(
            Success=True,
            OutTransferNO=request.OutTransferNO,
            TransferID=transfer_id,
            RawResponse={'transfer_id': transfer_id, 'note': '生产环境需调用银行代付接口'},
        )
