<?php

namespace Game\Operation\SDK\ThinkData;

use Framework\Lib\Utils;
use Framework\Log\LogMark;
use Game\Constant\GameErrorCode;
use Game\Operation\EventLog\EventLog;
use Game\Operation\EventLog\EventLog_Manager;
use Game\Operation\EventLog\EventLogType;
use Game\Operation\EventLog\EventLogHandler;
use Game\Operation\PlatformManager;
use Throwable;

require_once "TaPhpSdk.php";

use ThinkingEngine\ThinkingDataAnalytics;
use ThinkingEngine\FileConsumer;
use ThinkingEngine\TALogger;
use ThinkingEngine\DebugConsumer;
use ThinkingEngine\BatchConsumer;
use ThinkingEngine\ThinkingDataException;

class SDK_ThinkData implements EventLogHandler
{
    private array $sdkLogMap = array(
        EventLogType::Login => ThinkLoginEvent::class,
        EventLogType::Logout => ThinkLogoutEvent::class,
        EventLogType::CompleteTask => ThinkTaskEvent::class,
        EventLogType::StartPVE => ThinkStartPVEEvent::class,
        EventLogType::StartPVP => ThinkStartPVPEvent::class,
        EventLogType::CompleteMatch => ThinkCompleteMatchEvent::class,
        EventLogType::CompletePVE => ThinkCompletePVEEvent::class,
        EventLogType::ItemAdd => ThinkItemAddEvent::class,
        EventLogType::ItemConsume => ThinkItemConsumeEvent::class,
        EventLogType::Car => ThinkCarEvent::class,
    );

    //用户数据key替换为SDK key
    private array $userKey2SDKkey = array(
        EventLogType::LOG_KEY_PLAYER_PROFICIENCY_LV => "current_level",
        EventLogType::LOG_KEY_CAREER_LEVEL_ID => "current_dungeon",
        EventLogType::LOG_KEY_ROLE_ID => "role_id",
        EventLogType::LOG_KEY_ROLE_NAME => "role_name",
        EventLogType::LOG_KEY_ROLE_FIRST_LOGIN_TIME => "first_login_time",
        EventLogType::LOG_KEY_ROLE_REGISTER_TIME => "register_time",
    );

    protected array $logDic = array();

    protected ThinkingDataAnalytics $sdk;

    protected string $account;

    protected string $distinct_id;

    protected array $clientInfo;

    public function initSDK($logPath, $account, $distinct_id, $prefix)
    {
        $this->account = $account;
        $this->distinct_id = $distinct_id;
        $consumer = new FileConsumer($logPath, 2000, true, $prefix);
        TALogger::$enable = false;
        $this->sdk = new ThinkingDataAnalytics($consumer, false);
    }

    public function setAccount($account, $distinct_id)
    {
        $this->account = $account;
        $this->distinct_id = $distinct_id;
    }

    public function finish()
    {
        $this->sdk->flush();
    }

    public function report(EventLog $log)
    {
        /**
         * @var ThinkDataEvent $thinkDataEvent
         */
        $thinkDataEvent = $this->getThinkDataEvent($log->GetLogType());
        if ($thinkDataEvent == null) {
            return;
        }
        if (!$thinkDataEvent->parsingLog($log)) {
            return;
        }
        $this->Log_mark($thinkDataEvent);
    }

    //覆盖用户属性
    public function setUserAttr(array $attr)
    {
        $tmp = array();
        foreach ($attr as $key => $value) {
            $tmp[$this->userKey2SDKkey[$key]] = $value;
        }
        try {
            $this->sdk->user_set($this->distinct_id, $this->account, $tmp);
        } catch (Throwable $exception) {
            LogMark::getInstance()->markError(
                -1,
                'SDK_ThinkData modify user Atte  error!',
                array("exception" => $exception->getMessage(), "code" => $exception->getCode(),
                    "file" => $exception->getFile(), "line" => $exception->getLine(),
                    "trace" => $exception->getTraceAsString())
            );
        }
    }

    protected function getThinkDataEvent(string $t)
    {
        if (array_key_exists($t, $this->logDic)) {
            return $this->logDic[$t];
        }
        $name = $this->sdkLogMap[$t] ?? null;
        if (is_null($name)) {
            return null;
        }
        $log = new $name();
        $log->init();
        $this->logDic[$t] = $log;
        return $log;
    }

    private function Log_mark(ThinkDataEvent $eventLog)
    {
        try {
            $log = array(
                "#ip" => Utils::getClientIp()
            );
            $zone = 0;
            foreach (EventLog_Manager::getInstance()->headData as $k => $v) {
                if ($k == "#distinct_id" || $k == "UUID") {
                    continue;
                }
                if ($k == "#zone_offset") {
                    $zone = $v;
                }
                $log[$k] = $v;
            }
            //替换时间--最后补位和客户端时间格式保持一致...
            $log["#time"] = Utils::getDateByTimeZone($zone).".".random_int(100, 999);
            foreach ($eventLog->eventValues as $k => $v) {
                $log[$k] = $v;
            }
            $this->sdk->track($this->distinct_id, $this->account, $eventLog->eventName, $log);
        } catch (Throwable $exception) {
            LogMark::getInstance()->markError(
                -1,
                'SDK_ThinkData mark  error!',
                array("exception" => $exception->getMessage(), "code" => $exception->getCode(),
                    "file" => $exception->getFile(), "line" => $exception->getLine(),
                    "trace" => $exception->getTraceAsString())
            );
        }
    }

    public function register(array $attr)
    {
        $tmp = array();
        foreach ($attr as $key => $value) {
            $tmp[$this->userKey2SDKkey[$key]] = $value;
        }
        try {
            $this->sdk->user_set($this->distinct_id, $this->account, $tmp);
        } catch (Throwable $exception) {
            LogMark::getInstance()->markError(
                -1,
                'SDK_ThinkData modify user Atte  error!',
                array("exception" => $exception->getMessage(), "code" => $exception->getCode(),
                    "file" => $exception->getFile(), "line" => $exception->getLine(),
                    "trace" => $exception->getTraceAsString())
            );
        }
    }
}