<?php 

namespace Lcmigrator\LcMigrator\Event;

use Lcmigrator\LcMigrator\Backend\LMRequest;
use Lcmigrator\LcMigrator\Logger\Logger;
use Lcmigrator\LcMigrator\OptionManager\OptionManager;

class EventUpdater{
    /**
     * @var string $eventName The name of the event
     */
    private string $eventName;
    private array $eventAttributes;
    private string $eventUpdateEndPoint = 'wordpress/lc-plugin/migrator/events/update';  

    /**
     * Constructor for the PendoEvent
     * @param string $eventName The name of the event
     * @param array $eventAttributes K,V pairs of the event attributes
     * @return static 
     */
    public function __construct(string $eventName, array $eventAttributes){
        $this->eventName = $eventName;
        $this->eventAttributes = $eventAttributes;
        $accountId = $this->getAccountId();
        // Only append account ID if it's not empty (skip event tracking in CLI if no account ID)
        if (!empty($accountId)) {
            $this->eventUpdateEndPoint = $this->eventUpdateEndPoint . "/" . $accountId;
        }
        return $this;
    }

    /**
     * Function to add an attribute to the event
     * @param string $attributeName
     * @param mixed $attributeValue
     * @return PendoEvent
     */
    public function addEventAttribute(string $attributeName, $attributeValue): PendoEvent {
        $this->eventAttributes[$attributeName] = $attributeValue;
        return $this;
    }

    /**
     * Function to add multiple attributes to the event
     * @param array $eventAttributes
     * @return PendoEvent
     */
    public function addEventAttributes(array $eventAttributes): PendoEvent {
        $this->eventAttributes = array_merge($this->eventAttributes, $eventAttributes);
        return $this;
    }

    private function getAccountId(string $locationId = null): string{
        $leadMigratorOptions = OptionManager::getInstance();
        if($locationId){
            return $locationId;
        }
        $accountId = $leadMigratorOptions->get('location_id');
        // Return empty string if location_id is not set (e.g., in CLI mode)
        return $accountId ?? '';
    }
    
    private function getAdditionalEventAttributes(): array{
        return array(
            'remote_ip' => $_SERVER['REMOTE_ADDR'] ?? 'CLI',
            'host' => $_SERVER['HTTP_HOST'] ?? (defined('WP_CLI') && WP_CLI ? 'CLI' : ''),
            'admin_email' => get_option('admin_email'),
            'php_version' => phpversion(),
        );
    }

    /**
     * Creates the event body that is sent to Backend
     * @return array
     */
    private function createEventBody(): Array{
        $body = Array(
            'eventName' => $this->eventName,
            'eventAttributes' => array_merge($this->eventAttributes, $this->getAdditionalEventAttributes()),
            'accountId' => $this->getAccountId(),
        );
        return $body;
    }

    /**
     * Sends the event to the backend
     * @return bool True if the event was sent successfully, false otherwise
     */
    public function send(): bool {
        try{
            // Skip event tracking if no account ID (e.g., CLI mode without authentication)
            $accountId = $this->getAccountId();
            if (empty($accountId)) {
                $logger = Logger::getInstance();
                $logger->info("Skipping event tracking: No account ID available (CLI mode)");
                return true; // Return true to not break the flow
            }

            // Sanity checks for event name and attributes
            if (empty($this->eventName)) {
                throw new \Exception('Event name cannot be empty');
            }

            if (!is_array($this->eventAttributes)) {
                throw new \Exception('Event attributes must be an array');
            }
            $request = new LMRequest();
            $response = $request->request($this->eventUpdateEndPoint, 'POST', $this->createEventBody());
            if (isset($response->success) && $response->success === true) {
                $logger = Logger::getInstance();
                $logger->info("Pendo Event Tracked Successfully");
            }
            else{
                $logger = Logger::getInstance();
                $logger->error("Pendo API Call Failed: " . ($response->message ?? 'Unknown error'));
            }
            return true;
        }
        catch(\Exception $e){
            $logger = Logger::getInstance();
            $logger->error("Pendo Event Failed : " . $e->getMessage());
            return false;
        }
    }
}