package com.fshark.overseas.advert.processor;


import com.alibaba.fastjson.JSONObject;
import com.fshark.overseas.advert.entity.ServerRoleAccount;
import com.fshark.overseas.advert.entity.dao.ServerRoleDao;
import com.fshark.overseas.advert.modle.AppsFlyerEvent;
import com.fshark.overseas.advert.modle.AppsFlyerWithAccountEvent;
import com.fshark.overseas.advert.modle.metrics.BaseServerMetrics;
import com.fshark.overseas.advert.modle.metrics.ServerActivationMetrics;
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.time.LocalDateTime;
import java.util.Date;
import java.util.Locale;
import java.util.Optional;

/**
 * 转化成激活注册指标数据
 */
public class ServerActivationProcessor extends RichFlatMapFunction<AppsFlyerEvent, ServerActivationMetrics> {

    private AppConfig appConfig;

    private JdbiContext jdbiContext;

    private ServerRoleDao serverRoleDao;

    public ServerActivationProcessor(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());
        serverRoleDao = jdbiContext.getJdbi().onDemand(ServerRoleDao.class);


    }

    @Override
    public void flatMap(AppsFlyerEvent value, Collector<ServerActivationMetrics> out) throws Exception {

        JSONObject jsonObject = JSONObject.parseObject(value.getEvent_value());
        String serverid = jsonObject.getString("serverid");
        String roleId = jsonObject.getString("roleid");
        if (serverid == null) {
            return;
        }
        Optional<ServerRoleAccount> serverAccount = serverRoleDao.findByPrimary(value, serverid, Constants.TYPE_ACTIVIYION);
        AppsFlyerWithAccountEvent appsFlyerWithAccountEvent = copyEvent(value);
        ServerActivationMetrics activationMetrics = new ServerActivationMetrics();
        copyBaseMetrics(appsFlyerWithAccountEvent, activationMetrics);

        activationMetrics.setServer_id(serverid);
        appsFlyerWithAccountEvent.setRegister_server_id(serverid);
        String time = DateUtils.formatAsYMDHMS(value.getEvent_time());
        if (serverAccount.isPresent()) {
            ServerRoleAccount serverRole = serverAccount.get();
            String register_server_time = serverRole.getEvent_time();
            Optional<ServerRoleAccount> loginRole = serverRoleDao.findByPrimary(value, serverid, Constants.TYPE_ROLELOGIN);
            if (loginRole.isPresent()) {
                String last_role_login_time = loginRole.get().getEvent_time();
                activationMetrics.setData_date(Long.valueOf(DateUtils.formatAsYMD(register_server_time)));
                activationMetrics.setData_hour(Integer.valueOf(DateUtils.formatAsHH(register_server_time)));
                //当日登录排除当日注册用户 dau
                LocalDateTime last_login_date = DateUtils.formatAsDate(last_role_login_time);
                if (DateUtils.daysBetween(last_login_date, value.getEvent_time()) > 0) {
                    long daysBetween = DateUtils.daysBetween(DateUtils.formatAsDate(register_server_time), value.getEvent_time());
                    if (daysBetween > 0) {
                        activationMetrics.setDateRemind(daysBetween);
                        out.collect(activationMetrics);
                        ServerActivationMetrics activationMetrics1 = new ServerActivationMetrics();
                        copyBaseMetrics(appsFlyerWithAccountEvent, activationMetrics1);
                        activationMetrics1.setData_date(Long.valueOf(DateUtils.formatAsYMD(value.getEvent_time())));
                        activationMetrics1.setData_hour(Integer.valueOf(DateUtils.formatAsHH(value.getEvent_time())));
                        activationMetrics1.setData_active_day_dau(1L);
                        activationMetrics1.setServer_id(serverid);
                        out.collect(activationMetrics1);
                        appsFlyerWithAccountEvent.setReg_event_time(time);
                    }
                }
            }

        } else {
            activationMetrics.setData_date(Long.valueOf(DateUtils.formatAsYMD(time)));
            activationMetrics.setData_hour(Integer.valueOf(DateUtils.formatAsHH(time)));
            activationMetrics.setData_register(1L);
            activationMetrics.setData_create_role(1L);
            activationMetrics.setData_day_register_create(1L);
            appsFlyerWithAccountEvent.setRole_id(roleId);
            appsFlyerWithAccountEvent.setReg_event_time(time);
            serverRoleDao.insertServerRole(appsFlyerWithAccountEvent);
            out.collect(activationMetrics);
        }
        serverRoleDao.inserttServerLogin(appsFlyerWithAccountEvent);
    }


    private void copyBaseMetrics(AppsFlyerWithAccountEvent value, BaseServerMetrics metrics) {
        metrics.setTime_zone(value.getTime_zone());
        metrics.setPlatform(value.getPlatform());
        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.setData_type(value.getData_type());
        metrics.setChannel(value.getChannel());
        metrics.setMedia_source(value.getMedia_source());
        value.setData_type(1);
        if (value.getIs_retargeting()) { //再营销数据
            value.setData_type(2);
        }

        if (value.getCampaign().toLowerCase(Locale.ROOT).startsWith("acp")) { //预注册数据
            value.setData_type(3);
        }
    }

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

    private AppsFlyerWithAccountEvent copyEvent(AppsFlyerEvent value) {
        Gson gson = new Gson();
        return gson.fromJson(gson.toJson(value), AppsFlyerWithAccountEvent.class);
    }
}
