package com.crm.pay.service.impl.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.crm.pay.entity.brightcart.BrightcartBillingAddressEntity;
import com.crm.pay.entity.brightcart.BrightcartCustomerEntity;
import com.crm.pay.entity.brightcart.BrightcartOrderEntity;
import com.crm.pay.entity.brightcart.BrightcartSessionEntity;
import com.crm.pay.entity.callback.brightcart.BrightcartCallbackEntity;
import com.crm.pay.entity.property.BrightcartPropertyEntity;
import com.crm.pay.service.BrightcartService;
import com.crm.pay.service.CustomInfoService;
import com.crm.pay.service.FinanceDepositService;
import com.crm.pay.service.impl.base.BasePayServiceImpl;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.model.constant.PayConstants;
import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositAddEntity;
import com.crm.pay.entity.FinanceDepositCallbackUpdateEntity;
import com.crm.rely.backend.model.pojo.table.CustomInfoTable;
import com.crm.rely.backend.model.pojo.table.FinanceDepositTable;
import com.crm.rely.backend.model.pojo.table.SysRemittanceChannelTable;
import com.crm.rely.backend.core.exception.PayValidatedException;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.util.AESUtil;
import com.crm.rely.backend.util.HttpUtil;
import com.crm.rely.backend.util.MD5Util;
import com.crm.rely.backend.util.ShaUtil;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Connection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: cwg-my-base
 * @description:
 * @author: houn
 * @create: 2023-10-12 11:45
 */
@Slf4j
@Service
public class BrightcartServiceImpl extends BasePayServiceImpl implements BrightcartService {

    @Autowired
    private FinanceDepositService financeDepositService;

    @Autowired
    private CustomInfoService customInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String pay(FinanceDepositAddEntity balanceSaveEntity) throws Exception {

        //通道配置
        SysRemittanceChannelTable channel = getPayChannel(PayConstants.BRIGHTCART_PAY_KEY);
        //通道配置实体
        BrightcartPropertyEntity payProperty = getPayProperty(channel, BrightcartPropertyEntity.class);

        balanceSaveEntity.setCurrency(channel.getCurrency());
        balanceSaveEntity.setTransformCurrency(channel.getTransformCurrency());

        FinanceDepositTable balanceTable = financeDepositService.save(balanceSaveEntity, channel);

        String url = getUrl(payProperty, balanceTable, balanceSaveEntity);
        balanceTable.setFormUrl(url);
        
        return url;
    }

    /**
     * 回调处理数据
     *
     * @param callbackEntity
     * @throws ServiceException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void callback(BrightcartCallbackEntity callbackEntity) throws Exception {

        log.info(String.format("callback ticket:%s,callback data:%s", callbackEntity.getOrder_number(),
                JSON.toJSONString(callbackEntity)));

        //获取配置
        BrightcartPropertyEntity payProperty = getPayProperty(PayConstants.BRIGHTCART_PAY_KEY, false,
                BrightcartPropertyEntity.class);

        boolean flag = validate(callbackEntity, payProperty);

        if (!flag) {
            throw new ServiceException(Constants.FAIL);
        }

        FinanceDepositCallbackUpdateEntity balanceCallbackUpdateEntity =
                getFinanceDepositCallbackUpdateEntity(PayConstants.BRIGHTCART_SUCCESS_STATUS,
                        callbackEntity.getOrder_number(),
                        callbackEntity.getId(),
                        callbackEntity.getStatus(), callbackEntity);

        balanceCallbackUpdateEntity.setTransformAmount(new BigDecimal(callbackEntity.getOrder_amount()));
        balanceCallbackUpdateEntity.setNote(callbackEntity.getReason());
        /**
         * 更新数据
         */
        financeDepositService.updateCallback(balanceCallbackUpdateEntity);
    }


    private void validateAndUpdateCallback(BrightcartPropertyEntity payProperty, FinanceDepositTable table) throws ServiceException, IOException, PayValidatedException {
//        KorapayRequestReferenceDto korapayRequestReferenceDto = getTicketData(payProperty,
//                table.getSerial() + "_" + table.getLogin());
//        int status;
//        switch (korapayRequestReferenceDto.getData().getStatus()) {
//            case PayConstants.KORAPAY_SUCCESS_STATUS:
//                status = PayConstants.CALLBACE_SUCCESS_STATUS;
//                break;
//            case PayConstants.KORAPAY_FAILED_STATUS:
//                status = PayConstants.CALLBACE_FAIL_STATUS;
//                break;
//            default:
//                status = 0;
//                break;
//        }
//
//        FinanceDepositCallbackUpdateEntity balanceCallbackUpdateEntity = new FinanceDepositCallbackUpdateEntity();
//        balanceCallbackUpdateEntity.setChannelSerial(table.getChannelSerial());
//        balanceCallbackUpdateEntity.setTicket(table.getChannelSerial());
//        balanceCallbackUpdateEntity.setCallbackStatus(status);
//        balanceCallbackUpdateEntity.setCallbackTime(new Date());
//        balanceCallbackUpdateEntity.setCallbackData(JSON.toJSONString(korapayRequestReferenceDto));
//
//        balanceCallbackUpdateEntity.setTransformAmount(new BigDecimal(korapayRequestReferenceDto.getData()
//        .getAmount()));
//
//        /**
//         * 更新数据
//         */
//        financeDepositService.updateCallback(balanceCallbackUpdateEntity);
    }

    private boolean validate(BrightcartCallbackEntity callbackEntity, BrightcartPropertyEntity payProperty) throws Exception {
//payment_public_id + order.number + order.amount + order.currency + order.description + merchant.pass
        String signString = String.format("%s%s%s%s%s%s", callbackEntity.getId(), callbackEntity.getOrder_number(),
                callbackEntity.getOrder_amount(), callbackEntity.getOrder_currency(),
                callbackEntity.getOrder_description(), payProperty.getPassword()).toUpperCase();

        String sign = ShaUtil.sha("SHA-1", MD5Util.getMD5(signString));
        log.info(String.format("validate sign ma5 sha-1--orderNo:%s,sign string:%s,sign return:%s",
                callbackEntity.getOrder_number(),
                signString,
                sign));

        return sign.equals(callbackEntity.getHash());

    }

    /**
     * 获取支付url
     *
     * @param balanceTable
     * @return
     * @throws ServiceException
     */
    private String getUrl(BrightcartPropertyEntity propertyEntity,
                          FinanceDepositTable balanceTable,
                          FinanceDepositAddEntity balanceSaveEntity) throws Exception {

        BrightcartSessionEntity sessionEntity = new BrightcartSessionEntity();
        sessionEntity.setCancel_url(propertyEntity.getCancelUrl());

        sessionEntity.setMerchant_key(propertyEntity.getMerchantKey());
        sessionEntity.setMethods(propertyEntity.getMethods());
        sessionEntity.setSuccess_url(propertyEntity.getCallbackUrl());
        sessionEntity.setOperation(propertyEntity.getOperation());
        sessionEntity.setRecurring_init(propertyEntity.getRecurringInit());

        BrightcartOrderEntity orderEntity = new BrightcartOrderEntity();
        orderEntity.setAmount(String.format("%.2f", balanceTable.getTransformAmount().doubleValue()));
        orderEntity.setDescription(String.valueOf(balanceTable.getLogin()));
        orderEntity.setCurrency(balanceTable.getTransformCurrency());
        orderEntity.setNumber(balanceTable.getSerial() + "_" + balanceTable.getLogin());
        sessionEntity.setOrder(orderEntity);

        CustomInfoTable customInfoTable = customInfoService.getById(balanceTable.getCustomId());
        BrightcartCustomerEntity customerEntity = new BrightcartCustomerEntity();
        customerEntity.setEmail(customInfoTable.getEmail());
        customerEntity.setName(balanceTable.getName());
        sessionEntity.setCustomer(customerEntity);

        BrightcartBillingAddressEntity brightcartBillingAddressEntity = new BrightcartBillingAddressEntity();
        brightcartBillingAddressEntity.setAddress(customInfoTable.getAddressLine());
        brightcartBillingAddressEntity.setCity(customInfoTable.getCity());
        brightcartBillingAddressEntity.setCountry(customInfoTable.getCountry());
        brightcartBillingAddressEntity.setPhone(customInfoTable.getPhone());
        brightcartBillingAddressEntity.setState(customInfoTable.getState());
        brightcartBillingAddressEntity.setZip(customInfoTable.getZipCode());
        sessionEntity.setBilling_address(brightcartBillingAddressEntity);

        String hash = getSign(propertyEntity, sessionEntity);

        sessionEntity.setHash(hash);

        Map<String, String> headers = new HashMap<>(1);
        headers.put("Content-Type", "application/json");

        Connection.Response response = HttpUtil.post(
                propertyEntity.getBaseUrl() + propertyEntity.getSessionUrl(), headers, sessionEntity);

        log.info(String.format("url:%s,json:%s,body:%s", propertyEntity.getBaseUrl() + propertyEntity.getSessionUrl(),
                JSON.toJSON(sessionEntity), response.body()));
        JSONObject requestEntity = JSON.parseObject(response.body());

        if (requestEntity == null
                || (requestEntity.get("error_code") != null && requestEntity.get("error_code").toString().equals("0"))
        ) {
//            throw new PayValidatedException(requestEntity.get("error_message").toString());
//            if (requestEntity.get("errors").toString() == "[]") {
//                throw new PayValidatedException(requestEntity.get("error_message").toString());
//            } else {
//                throw new PayValidatedException(requestEntity.get(
//                        "errors"
//                ).toString());
//            }
            throw new PayValidatedException(requestEntity.get("error_message").toString() + ":" + requestEntity.get(
                    "errors"
            ).toString());
        }

        String url = String.valueOf(requestEntity.get("redirect_url"));
        log.info(String.format("pay to brightcart,orderNo:%s,return url:%s", orderEntity.getNumber(), url));
        return url;
    }

    private String getSign(BrightcartPropertyEntity payProperty, BrightcartSessionEntity entity) throws Exception {
        String signString = String.format("%s%s%s%s%s", entity.getOrder().getNumber(), entity.getOrder().getAmount(),
                entity.getOrder().getCurrency(), entity.getOrder().getDescription(), payProperty.getPassword()).toUpperCase();

        String sign = ShaUtil.sha("SHA-1", MD5Util.getMD5(signString));
        log.info(String.format("sign ma5 sha-1--orderNo:%s,sign string:%s,sign return:%s",
                entity.getOrder().getNumber(),
                signString,
                sign));

        return sign;
    }

    public static void main(String[] args) throws Exception {
        System.out.println(AESUtil.encrypt("", "bfa5559109f94c78af615bcf00d52060"));

        System.out.println(AESUtil.decrypt("", "bfa5559109f94c78af615bcf00d52060"));

    }
}
