package com.fshark.overseas.advert.processor;

import com.fshark.overseas.advert.entity.GameAccount;
import com.fshark.overseas.advert.entity.ServerRoleAccount;
import com.fshark.overseas.advert.entity.dao.GameAccountDao;
import com.fshark.overseas.advert.entity.dao.ServerRoleDao;
import com.fshark.overseas.advert.modle.AppsFlyerEvent;
import com.fshark.overseas.advert.modle.AppsflyerPurchase;
import com.fshark.overseas.advert.modle.OrderData;
import com.fshark.overseas.advert.modle.SinkMetricEvent;
import com.fshark.overseas.advert.util.*;
import com.google.gson.Gson;
import org.apache.flink.api.common.functions.RichFlatMapFunction;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.util.Collector;

import java.util.Optional;

public class PurchaseToOrderDataProcessor extends RichFlatMapFunction<AppsFlyerEvent, String> {

    private AppConfig appConfig;

    private JdbiContext jdbiContext;
    private GameAccountDao gameAccountDao;
    private ServerRoleDao serverRoleDao;

    public PurchaseToOrderDataProcessor(AppConfig appConfig) {
        this.appConfig = appConfig;
    }

    @Override
    public void open(Configuration parameters) throws Exception {
        super.open(parameters);
        jdbiContext = DatabaseUtils.getCHGenJdbiClient(appConfig.getDbHost(), appConfig.getDbUser(), appConfig.getDbPassword());
        gameAccountDao = jdbiContext.getJdbi().onDemand(GameAccountDao.class);
        serverRoleDao = jdbiContext.getJdbi().onDemand(ServerRoleDao.class);
    }

    @Override
    public void flatMap(AppsFlyerEvent value, Collector<String> out) throws Exception {
        try {
            AppsflyerPurchase appsflyerPurchase = new Gson().fromJson(value.getEvent_value(), AppsflyerPurchase.class);
            if (appsflyerPurchase == null || appsflyerPurchase.getBundle_id() == null) {  //不是我们上报的格式
                return;
            }
            if ("ios".equalsIgnoreCase(value.getPlatform())) {
                String bundleId = appsflyerPurchase.getBundle_id();
                value.setGame_id(bundleId == null ? value.getGame_id() : bundleId);
            }

            OrderData orderData = new OrderData(value);
            Optional<GameAccount> accountActivition = gameAccountDao.findByPrimary(value, Constants.TYPE_ACTIVIYION);
            if (accountActivition.isPresent()) {
                GameAccount gameAccount = accountActivition.get();
                orderData.setActivation_time(gameAccount.getEvent_time());
                orderData.setData_type(CommonUtils.setType(Long.parseLong(DateUtils.formatAsYMD(gameAccount.getEvent_time())), orderData.getMedia_source(), orderData.getData_type()));
            }

            Optional<GameAccount> accountRegister = gameAccountDao.findByPrimary(value, Constants.TYPE_REGISTER);
            if (accountRegister.isPresent()) {
                GameAccount gameAccount = accountRegister.get();
                orderData.setReg_time(gameAccount.getEvent_time());
                if (orderData.getActivation_time() == null) {
                    orderData.setActivation_time(gameAccount.getEvent_time());
                }
            }

            Optional<GameAccount> accountRetarget = gameAccountDao.findByPrimary(value, Constants.TYPE_RETARGETING);
            if (accountRetarget.isPresent()) {
                GameAccount gameAccount = accountRetarget.get();
                orderData.setRetargeting_time(gameAccount.getEvent_time());
            }

            Optional<ServerRoleAccount> serverAccount = serverRoleDao.findByPrimary(value, appsflyerPurchase.getServerid(), Constants.TYPE_ACTIVIYION);
            if (serverAccount.isPresent()) {
                String event_time = serverAccount.get().getEvent_time();
                orderData.setReg_server_id(appsflyerPurchase.getServerid());
                orderData.setReg_server_time(event_time);
            }

            gameAccountDao.insertPauchase(value);

            SinkMetricEvent sinkMetricEvent = new SinkMetricEvent();
            sinkMetricEvent.setEventType(Constants.TYPE_SINK_ORDER);
            sinkMetricEvent.setOrderData(orderData);
            out.collect(new Gson().toJson(sinkMetricEvent));
        } catch (Exception e) {
            return;
        }
    }


    @Override
    public void close() throws Exception {
        super.close();
        if (jdbiContext != null) {
            jdbiContext.getDataSource().close();
        }

    }
}
