package com.fshark.overseas.advert.processor;

import com.alibaba.fastjson.JSONObject;
import com.fshark.overseas.advert.entity.GameAccount;
import com.fshark.overseas.advert.entity.dao.GameAccountDao;
import com.fshark.overseas.advert.modle.AppsFlyerEvent;
import com.fshark.overseas.advert.modle.EventTypeEnum;
import com.fshark.overseas.advert.modle.metrics.ActivationMetrics;
import com.fshark.overseas.advert.modle.metrics.BaseMetrics;
import com.fshark.overseas.advert.util.*;
import org.apache.flink.api.common.functions.RichFlatMapFunction;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.util.Collector;
import org.apache.http.util.TextUtils;
import org.gradle.internal.impldep.org.joda.time.DateTime;

import java.time.LocalDateTime;
import java.util.Locale;
import java.util.Optional;

/**
 * 设备激活
 */
public class OuidLoginProcess extends RichFlatMapFunction<AppsFlyerEvent, ActivationMetrics> {

    private AppConfig appConfig;

    private JdbiContext jdbiContext;
    private GameAccountDao gameAccountDao;

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

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

    @Override
    public void flatMap(AppsFlyerEvent value, Collector<ActivationMetrics> out) throws Exception {
        JSONObject jsonObject = JSONObject.parseObject(value.getEvent_value());
        if (jsonObject == null) return;
        String ouid = jsonObject.getString("ouid");
        if (TextUtils.isEmpty(ouid)) {
            return;
        }
        ActivationMetrics activationMetrics = new ActivationMetrics();
        ActivationMetrics retentMetrics = new ActivationMetrics();
        copyBaseMetrics(value, activationMetrics);
        copyBaseMetrics(value, retentMetrics);
        retentMetrics.setUid(ouid);
        activationMetrics.setUid(ouid);
        String event_time = DateUtils.formatAsYMDHMS(value.getEvent_time());
        activationMetrics.setData_date(Long.parseLong(DateUtils.formatAsYMD(event_time)));
        activationMetrics.setData_hour(Integer.parseInt(DateUtils.formatAsHH(event_time)));
        Optional<GameAccount> account = gameAccountDao.findByOuid(value, ouid, Constants.TYPE_OUID_REGISTER);
        if (!account.isPresent()) {
            gameAccountDao.insertOuidRegister(value, event_time, ouid);
            activationMetrics.setData_ouid_register(1L);
            if (EventTypeEnum.createRoleEvent(value)) {
                Optional<GameAccount> accountCreateRole = gameAccountDao.findByOuid(value, ouid,Constants.TYPE_CREATEROLE);
                if (!accountCreateRole.isPresent()) {
                    activationMetrics.setData_create_role(1L);
                    activationMetrics.setData_day_register_create(1L);
                    gameAccountDao.insertOuidEvent(value,ouid,Constants.TYPE_CREATEROLE);
                }
            }
        } else {
            GameAccount gameAccount = account.get();
            copyOuidMetrics(gameAccount, activationMetrics);
            copyOuidMetrics(gameAccount, retentMetrics);
            String activationTime = account.get().getEvent_time();
            LocalDateTime activition = DateUtils.formatAsDate(activationTime);
            retentMetrics.setData_date(Long.parseLong(DateUtils.formatAsYMD(activationTime)));
            retentMetrics.setData_hour(Integer.parseInt(DateUtils.formatAsHH(activationTime)));
            Optional<GameAccount> accountRoleLogin = gameAccountDao.findByOuid(value, ouid, Constants.TYPE_OUID_LOGIN);
            if (accountRoleLogin.isPresent()) {
                String last_login_time = accountRoleLogin.get().getEvent_time();
                LocalDateTime date = DateUtils.formatAsDate(last_login_time);
                if (DateUtils.daysBetween(date, value.getEvent_time()) > 0) { //排除当日登录用户
                    long daysBetween = DateUtils.daysBetween(activition, value.getEvent_time());
                    if (daysBetween > 0) {
                        retentMetrics.setDateRemind(daysBetween); //留存天数
                        activationMetrics.setData_active_day_dau(1L);
                    }
                }
            } else {
                long daysBetween = DateUtils.daysBetween(activition, value.getEvent_time());
                if (daysBetween > 0) {
                    retentMetrics.setDateRemind(daysBetween); //留存天数
                    activationMetrics.setData_active_day_dau(1L);
                }
            }
            if (EventTypeEnum.roleEvent(value)) {
                boolean isRole = false;
                Optional<GameAccount> accountCreateRole = gameAccountDao.findByOuid(value, ouid,Constants.TYPE_CREATEROLE);
                if (!accountCreateRole.isPresent()) {
                    retentMetrics.setData_create_role(1L);
                    gameAccountDao.insertOuidEvent(value,ouid,Constants.TYPE_CREATEROLE);
                    isRole = true;
                }
                if (DateUtils.daysBetween(DateUtils.formatAsDate(gameAccount.getEvent_time()), value.getEvent_time()) == 0 && isRole) { //当日注册创角
                    retentMetrics.setData_day_register_create(1L);
                }
            }
        }
        out.collect(retentMetrics);
        out.collect(activationMetrics);
        gameAccountDao.insertOuidEvent(value, ouid, Constants.TYPE_OUID_LOGIN);
    }

    private void copyOuidMetrics(GameAccount gameAccount, ActivationMetrics activationMetrics) {
        activationMetrics.setPlatform(gameAccount.getPlatform());
        activationMetrics.setMedia_source(gameAccount.getMediaSource());
        activationMetrics.setCampaign_id(gameAccount.getCampaign_id());
        activationMetrics.setAd_set_id(gameAccount.getAd_set_id());
        activationMetrics.setAd_id(gameAccount.getAd_id());
        activationMetrics.setChannel(gameAccount.getChannel());
        activationMetrics.setRegion(gameAccount.getRegion());
    }


    private void copyBaseMetrics(AppsFlyerEvent value, BaseMetrics metrics) {
        metrics.setTime_zone(value.getTime_zone());
        metrics.setPlatform(value.getPlatform());
        metrics.setMedia_source(value.getMedia_source());
        metrics.setGame_id(value.getGame_id());
        metrics.setCampaign_id(value.getCampaign_id());
        metrics.setAd_set_id(value.getAd_set_id());
        metrics.setAd_id(value.getAd_id());
        metrics.setRegion(value.getRegion());
        metrics.setChannel(value.getChannel());
        metrics.setData_type(1);
        if (value.getIs_retargeting()) { //再营销数据
            metrics.setData_type(2);
        }
        if (value.getCampaign().toLowerCase(Locale.ROOT).startsWith("acp")) { //预注册数据
            metrics.setData_type(3);
        }

    }

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

}
