package com.crm.ucard.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.dto.wasabi.WasabiAuthTransactionDto;
import com.crm.rely.backend.core.dto.wasabi.WasabiMerchantDataDto;
import com.crm.rely.backend.core.entity.wasabi.WasabiAuthTransactionEntity;
import com.crm.rely.backend.core.enums.CardStatusTypeEnum;
import com.crm.rely.backend.core.pojo.table.ucard.CardTransacOrderTable;
import com.crm.rely.backend.core.pojo.table.ucard.UcardCardTable;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.service.MqSendService;
import com.crm.ucard.config.WasabiConfig;
import com.crm.ucard.dao.repository.CardTransacOrderRepository;
import com.crm.ucard.dao.repository.UcardCardRepository;
import com.crm.ucard.model.ResultData;
import com.crm.ucard.model.TwoTuple;
import com.crm.ucard.service.GlobalService;
import com.crm.ucard.service.UcardTaskService;
import com.crm.ucard.service.WasabiDocumentApiService;
import com.crm.ucard.util.WasabiCommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UcardTaskServiceImpl implements UcardTaskService {

    @Autowired
    private UcardCardRepository cardRepository;
    @Autowired
    private CardTransacOrderRepository cardTransacOrderRepository;
    @Autowired
    private MqSendService mqSendService;
    @Autowired
    private WasabiDocumentApiService wasabiDocumentApiService;
    @Autowired
    private GlobalService globalService;


    /**
     * 同步卡授权交易记录任务
     */
    @Override
    public void queryOrderInfo() throws Exception {
        WasabiConfig config = wasabiDocumentApiService.getWasabiConfig();

        try {
            WasabiAuthTransactionEntity entity = new WasabiAuthTransactionEntity();
            // 查询时间为前一天
            LocalDate yesterday = LocalDate.now().minusDays(1);
            LocalDateTime yesterdayStart = yesterday.atStartOfDay();
            LocalDateTime yesterdayEnd = yesterday.atTime(LocalTime.MAX);

            entity.setStartTime(yesterdayStart.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
            entity.setEndTime(yesterdayEnd.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());

            // 获取到银行卡信息
            List<UcardCardTable> cardlist = cardRepository.findAll();
            if (cardlist.isEmpty()) {
                return;
            }

            // 批量查询本地已存在的交易记录
            List<String> allCardNos = cardlist.stream().map(UcardCardTable::getCardNo).collect(Collectors.toList());
            List<CardTransacOrderTable> localOrders = cardTransacOrderRepository.findByCardNoIn(allCardNos);
            Set<String> localTradeNos = localOrders.stream()
                    .map(CardTransacOrderTable::getTradeNo)
                    .collect(Collectors.toSet());

            List<CardTransacOrderTable> tablesToSave = new ArrayList<>();
            for (UcardCardTable table : cardlist) {
                String cardNo = table.getCardNo();

                int page = 1;
                while (true) {
                    entity.setCardNo(cardNo);
                    entity.setPageNum((long) page);
                    entity.setPageSize(30L);
                    TwoTuple<String, String> result =
                            WasabiCommonUtil.post(config.getApiUrl() + config.getCardAuthTransactionUrl(),
                                    JSON.toJSONString(entity), config);
                    wasabiDocumentApiService.verifySignature(result, config.getWsbPublicKey());
                    ResultData resultData = JSON.parseObject(result.getSecond(), ResultData.class);
                    if (!resultData.isSuccess()) {
                        log.error("同步卡授权交易记录任务异常：cardNo:{},message:{}", cardNo, resultData.getMsg());
                        break;
                    }
                    JSONObject data = JSON.parseObject(resultData.getData().toString());
                    Integer total = data.getInteger("total");

                    if (total == null || total <= 0) {
                        break;
                    }
                    JSONArray records = data.getJSONArray("records");
                    List<WasabiAuthTransactionDto> dtos = records.toJavaList(WasabiAuthTransactionDto.class);

                    //比对数据
                    for (WasabiAuthTransactionDto dto : dtos) {
                        if (!localTradeNos.contains(dto.getTradeNo())) {
                            CardTransacOrderTable saveTable = new CardTransacOrderTable();
                            BeanUtils.copyProperties(dto, saveTable);
                            WasabiMerchantDataDto merchantDataDto = dto.getMerchantData();
                            BeanUtils.copyProperties(merchantDataDto, saveTable);
                            saveTable.setAddTime(new Date());
                            tablesToSave.add(saveTable);
                        }
                    }

                    if (dtos.size() < 30) {
                        break;
                    }
                    page++;
                }
            }

            if (!tablesToSave.isEmpty()) {
                cardTransacOrderRepository.save(tablesToSave);
                log.info("本次同步新增 {} 条交易记录", tablesToSave.size());
            } else {
                log.info("本次同步无新增交易记录");
            }
        } catch (Exception e) {
            log.error("银行卡授权交易信息数据定时同步异常", e);
            throw new ServiceException("银行卡授权交易信息数据定时同步失败，请稍后重试");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void queryCardInfo() throws Exception {
        // 查询卡激活处理中数据
        List<UcardCardTable> cardTables = cardRepository.findAllByStatus("processing");
        if (CollectionUtils.isEmpty(cardTables)) {
            return;
        }
        for (UcardCardTable table : cardTables) {
            log.info("激活中数据同步定时任务,开始处理-cardNumber:{}", table.getCardNumber());
            mqSendService.send(Constants.WASABICARD_CARD_INFO_REFRESH, JSONObject.toJSONString(table));
//            wasabiCardCardService.activateCallback(JSON.toJSONString(table));
        }
    }

    /**
     * 卡邮寄状态同步
     */
    @Override
    public void queryCardLogisticsStatus() throws Exception {
        // 查询待激活并且物流状态不为终态的数据
        List<UcardCardTable> tables =
                cardRepository.findAllByStatusAndLogisticsStatusNot(CardStatusTypeEnum.UN_ACTIVATE.getCode(), "4");
        if (CollectionUtils.isNotEmpty(tables)) {
            for (UcardCardTable table : tables) {
                mqSendService.send(Constants.CARD_LOGISTICS_STATUS_UPDATE, JSONObject.toJSONString(table));
            }
        }
    }

    /**
     * 定时同步币种信息
     */
    @Override
    public void queryCurrencyInfo() throws Exception {
        globalService.saveCurrencies();
    }

}
