<?php
/**
 * @package         FireBox
 * @version         3.1.1 Pro
 * 
 * @author          FirePlugins <info@fireplugins.com>
 * @link            https://www.fireplugins.com
 * @copyright       Copyright © 2025 FirePlugins All Rights Reserved
 * @license         GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
*/

namespace FireBox\Core\Analytics\Ajax;

if (!defined('ABSPATH'))
{
	exit; // Exit if accessed directly.
}

class Main
{
    use Shared;
    
    public function __construct()
    {
        add_action('wp_ajax_firebox_analytics_stats', [$this, 'firebox_analytics_stats']);
        add_action('wp_ajax_nopriv_firebox_analytics_stats', [$this, 'firebox_analytics_stats']);

        add_action('wp_ajax_firebox_analytics_get_campaigns', [$this, 'firebox_analytics_get_campaigns']);
        add_action('wp_ajax_nopriv_firebox_analytics_get_campaigns', [$this, 'firebox_analytics_get_campaigns']);

        add_action('wp_ajax_firebox_analytics_get_dropdown_campaigns', [$this, 'firebox_analytics_get_dropdown_campaigns']);
        add_action('wp_ajax_nopriv_firebox_analytics_get_dropdown_campaigns', [$this, 'firebox_analytics_get_dropdown_campaigns']);

        add_action('wp_ajax_firebox_delete_campaign', [$this, 'firebox_delete_campaign']);
        add_action('wp_ajax_nopriv_firebox_delete_campaign', [$this, 'firebox_delete_campaign']);

        add_action('wp_ajax_firebox_duplicate_campaign', [$this, 'firebox_duplicate_campaign']);
        add_action('wp_ajax_nopriv_firebox_duplicate_campaign', [$this, 'firebox_duplicate_campaign']);

        add_action('wp_ajax_firebox_analytics_get_charts_data', [$this, 'firebox_analytics_get_charts_data']);
        add_action('wp_ajax_nopriv_firebox_analytics_get_charts_data', [$this, 'firebox_analytics_get_charts_data']);

        add_action('wp_ajax_firebox_analytics_get_trending_templates', [$this, 'firebox_analytics_get_trending_templates']);
        add_action('wp_ajax_nopriv_firebox_analytics_get_trending_templates', [$this, 'firebox_analytics_get_trending_templates']);
    }

    /**
     * Analytics Counts
     * 
     * @return  void
     */
    public function firebox_analytics_stats()
    {
		if (!current_user_can('read_fireboxes'))
		{
			return;
        }
        
        $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
        
        // verify nonce
        if (!$verify = wp_verify_nonce($nonce, 'fpf_js_nonce'))
        {
            return false;
		}

        $date_period = isset($_POST['date_period']) ? sanitize_text_field(wp_unslash($_POST['date_period'])) : '';
        $start_date = isset($_POST['start_date']) ? sanitize_text_field(wp_unslash($_POST['start_date'])) : '';
        $end_date = isset($_POST['end_date']) ? sanitize_text_field(wp_unslash($_POST['end_date'])) : '';

        if (!$start_date || $start_date === 'false' || !$end_date || $end_date === 'false')
        {
            return;
        }
        
        $selected_campaign = isset($_POST['selected_campaign']) && !empty($_POST['selected_campaign']) ? intval(wp_unslash($_POST['selected_campaign'])) : '';
        
        $data = new \FireBox\Core\Analytics\Data($start_date, $end_date);

        $metrics = [
            'views',
            'clicks',
            'conversions',
            'conversionrate',
            'revenue'
        ];

        $filters = [];
        if ($selected_campaign)
        {
            $filters['campaign'] = [
                'value' => [$selected_campaign]
            ];
        }

        // Use new fluent interface
        $data->metrics($metrics)->filters($filters);

        // Get current period data
        $currentData = $data->getData('count');
        
        
        // Get attribution breakdown for view-through and conversion-through revenue
        $revenueData = new \FireBox\Core\Analytics\Data($start_date, $end_date);
        $revenueData->metrics(['revenue'])->filters($filters);
        
        $attributionData = $revenueData->getData('attribution_breakdown');
        $attributionBreakdown = $attributionData['revenue'];
        $currentViewThroughRevenue = 0;
        $currentClickThroughRevenue = 0;

        foreach ($attributionBreakdown as $attribution) {
            if ($attribution->attribution_type === 'impression') {
                $currentViewThroughRevenue = floatval($attribution->total_revenue);
            } elseif ($attribution->attribution_type === 'conversion') {
                $currentClickThroughRevenue = floatval($attribution->total_revenue);
            }
        }

        $currentData['view_through_revenue'] = $currentViewThroughRevenue;
        $currentData['conversion_through_revenue'] = $currentClickThroughRevenue;
        

        // Calculate previous period data
        $start_date_ts = strtotime($start_date);
        $end_date_ts = strtotime($end_date);
        $days_between = ceil(abs($end_date_ts - $start_date_ts) / 86400);

        $previousPeriodData = [
            'views' => 0,
            'clicks' => 0,
            'conversions' => 0,
            'conversionrate' => 0,
            'revenue' => 0,
            'view_through_revenue' => 0,
            'conversion_through_revenue' => 0
        ];
        
        if ($previousPeriodDates = $this->getPreviousPeriodDates($start_date, $days_between))
        {
            $previousData = new \FireBox\Core\Analytics\Data($previousPeriodDates[0], $previousPeriodDates[1]);
    
            $metrics = [
                'views',
                'conversions',
                'conversionrate',
                
                'clicks',
                'revenue'
                
            ];
            
            $filters = [];
            if ($selected_campaign)
            {
                $filters['campaign'] = [
                    'value' => [$selected_campaign]
                ];
            }
            
            // Use new fluent interface
            $previousData->metrics($metrics)->filters($filters);

            $previousPeriodData = $previousData->getData('count');
            
            
            // Get previous period attribution breakdown
            $previousRevenueData = new \FireBox\Core\Analytics\Data($previousPeriodDates[0], $previousPeriodDates[1]);
            $previousRevenueData->metrics(['revenue'])->filters($filters);
            
            $previousAttributionData = $previousRevenueData->getData('attribution_breakdown');
            $previousAttributionBreakdown = $previousAttributionData['revenue'];
            $previousViewThroughRevenue = 0;
            $previousClickThroughRevenue = 0;
            
            foreach ($previousAttributionBreakdown as $attribution) {
                if ($attribution->attribution_type === 'impression') {
                    $previousViewThroughRevenue = floatval($attribution->total_revenue);
                } elseif ($attribution->attribution_type === 'conversion') {
                    $previousClickThroughRevenue = floatval($attribution->total_revenue);
                }
            }
            $previousPeriodData['view_through_revenue'] = $previousViewThroughRevenue;
            $previousPeriodData['conversion_through_revenue'] = $previousClickThroughRevenue;
            
        }

        echo wp_json_encode([
            'current' => $currentData,
            'previous' => $previousPeriodData
        ]);
        wp_die();
    }

    /**
     * Analytics Get All Dropdown Campaigns
     * 
     * @return  void
     */
    public function firebox_analytics_get_dropdown_campaigns()
    {
		if (!current_user_can('read_fireboxes'))
		{
			return;
        }
        
        $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
        
        // verify nonce
        if (!$verify = wp_verify_nonce($nonce, 'fpf_js_nonce'))
        {
            return false;
		}

        if (!current_user_can('read_fireboxes'))
        {
            echo wp_json_encode([
                'permission_denied' => true
            ]);
            wp_die();
        }
        
        $boxes = \FireBox\Core\Helpers\BoxHelper::getAllBoxes(['draft', 'publish']);
		$boxes = $boxes->posts;

		if (!count($boxes))
		{
            echo wp_json_encode([]);
            wp_die();
		}

		$data = [
            [
                'id' => null,
                'label' => 'All Campaigns'
            ]
        ];
		
		foreach ($boxes as $box)
		{
			$data[] = [
				'id' => $box->ID,
				'label' => $box->post_title
			];
		}

        echo wp_json_encode($data);
        wp_die();
    }

    /**
     * Analytics Get Chart Data
     * 
     * @return  void
     */
    public function firebox_analytics_get_charts_data()
    {
		if (!current_user_can('read_fireboxes'))
		{
			return;
        }
        
        $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
        
        // verify nonce
        if (!$verify = wp_verify_nonce($nonce, 'fpf_js_nonce'))
        {
            return false;
		}

        $start_date = isset($_POST['start_date']) ? sanitize_text_field(wp_unslash($_POST['start_date'])) : '';
        $end_date = isset($_POST['end_date']) ? sanitize_text_field(wp_unslash($_POST['end_date'])) : '';

        if (!$start_date || $start_date === 'false' || !$end_date || $end_date === 'false')
        {
            return;
        }

        $filter = isset($_POST['filter']) ? sanitize_text_field(wp_unslash($_POST['filter'])) : 'list';

        $start_date_ts = strtotime($start_date);
        $end_date_ts = strtotime($end_date);
        $days_between = ceil(abs($end_date_ts - $start_date_ts) / 86400);

        // prepare labels
        $labels = [];

        // We are fetching data for a single day
        if ($days_between == 1)
        {
            for ($hour = 0; $hour < 24; $hour++)
            {
                $start_hour = sprintf('%02d', $hour);
                $labels[] = $start_hour . ':00';
            }
        }
        // Multiple days
        else if ($days_between > 1)
        {
            switch ($filter)
            {
                case 'list':
                default:
                    $tmp_start_date_ts = $start_date_ts;
                    for ($i = 0; $i < $days_between; $i++)
                    {
                        $labels[] = gmdate('Y-m-d', $tmp_start_date_ts);
                        $tmp_start_date_ts = strtotime("+1 day", $tmp_start_date_ts);
                    }
                    break;
                
                case 'weekly':
                    $startDate = new \DateTime();
                    $startDate->setTimestamp($start_date_ts);

                    $endDate = new \DateTime();
                    $endDate->setTimestamp($end_date_ts);

                    // Find the nearest Monday to the start date
                    while ($startDate->format('N') != 1)
                    {
                        $startDate->modify('-1 day');
                    }

                    while ($startDate <= $endDate)
                    {
                        $labels[] = $startDate->format('d M y');
                        $startDate->modify('+1 week');
                    }
                    break;
                
                case 'monthly':
                    $startDate = new \DateTime();
                    $startDate->setTimestamp($start_date_ts);

                    $endDate = new \DateTime();
                    $endDate->setTimestamp($end_date_ts);

                    // Set the start date to the first day of the month
                    $startDate->modify('first day of this month');

                    while ($startDate <= $endDate)
                    {
                        $labels[] = $startDate->format('M Y');
                        $startDate->modify('+1 month');
                    }
                    break;
            }
        }
        
		$selected_campaign = isset($_POST['selected_campaign']) && !empty($_POST['selected_campaign']) ? intval(wp_unslash($_POST['selected_campaign'])) : '';
        
        $data = new \FireBox\Core\Analytics\Data($start_date, $end_date);

        $metrics = [
            'views',
            'clicks',
            'conversions',
            'conversionrate',
            'revenue'
        ];

        $filters = [];
        if ($selected_campaign)
        {
            $filters = [
                'campaign' => [
                    'value' => [$selected_campaign]
                ]
            ];
        }

        // Use new fluent interface
        $data->metrics($metrics)->filters($filters);

        $chartData = $data->getData($filter);

        $revenueBreakdownByLabel = [];
        
        
        if (!empty(array_filter($chartData)))
        {
            // Get attribution breakdown for view-through and conversion-through revenue by time period
            // Convert dates to UTC to match the main chart data timezone handling
            $utcTimeZone = new \DateTimeZone('UTC');
            $tz = new \DateTimeZone(wp_timezone()->getName());
    
            // Convert start_date to UTC
            $utc_start_date = $start_date;
            if ($start_date_obj = \DateTime::createFromFormat('Y/m/d H:i:s', $start_date, $tz))
            {
                $start_date_obj->setTimezone($utcTimeZone);
                $utc_start_date = $start_date_obj->format('Y/m/d H:i:s');
            }
    
            // Convert end_date to UTC
            $utc_end_date = $end_date;
            if ($end_date_obj = \DateTime::createFromFormat('Y/m/d H:i:s', $end_date, $tz))
            {
                $end_date_obj->setTimezone($utcTimeZone);
                $utc_end_date = $end_date_obj->format('Y/m/d H:i:s');
            }
    
            $revenueMetric = new \FireBox\Core\Analytics\Metrics\Revenue($utc_start_date, $utc_end_date, 'attribution_breakdown_by_period', ['chart_filter' => $filter, 'days_between' => $days_between]);
            if ($selected_campaign)
            {
                $revenueMetric->filters([
                    'campaign' => [
                        'value' => [$selected_campaign]
                    ]
                ]);
            }
            
            $attributionBreakdownData = $revenueMetric->getData($filter);
            
            // Convert attribution breakdown data to indexed format for chart tooltip lookup
            // Initialize with zeros for all time periods to ensure consistent data structure
            
            // Initialize all labels with zero values
            foreach ($labels as $label)
            {
                $revenueBreakdownByLabel[$label] = [
                    'view_through_revenue' => 0.0,
                    'conversion_through_revenue' => 0.0
                ];
            }
            
            // Populate actual data where it exists
            foreach ($attributionBreakdownData as $attribution)
            {
                if (isset($revenueBreakdownByLabel[$attribution->label]))
                {
                    $revenueBreakdownByLabel[$attribution->label] = [
                        'view_through_revenue' => floatval(isset($attribution->view_through_revenue) ? $attribution->view_through_revenue : 0),
                        'conversion_through_revenue' => floatval(isset($attribution->conversion_through_revenue) ? $attribution->conversion_through_revenue : 0)
                    ];
                }
            }
        }
        

        echo wp_json_encode([
            'labels' => $labels,
            'data' => $chartData,
            'revenue_breakdown' => $revenueBreakdownByLabel
        ]);
        wp_die();
    }

    /**
     * Analytics Get Latest 5 Campaigns
     * 
     * @return  void
     */
    public function firebox_analytics_get_campaigns()
    {
		if (!current_user_can('read_fireboxes'))
		{
			return;
        }
        
        $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
        
        // verify nonce
        if (!$verify = wp_verify_nonce($nonce, 'fpf_js_nonce'))
        {
            return false;
		}
        
        if (!current_user_can('read_fireboxes'))
        {
            echo wp_json_encode([
                'permission_denied' => true
            ]);
            wp_die();
        }

        $boxes = \FireBox\Core\Analytics\Helpers\Campaigns::getRecentCampaignsList(5);

		if (!count($boxes->posts))
		{
            echo wp_json_encode([]);
            wp_die();
		}

        $start_date = isset($_POST['start_date']) ? sanitize_text_field(wp_unslash($_POST['start_date'])) : '';
        $end_date = isset($_POST['end_date']) ? sanitize_text_field(wp_unslash($_POST['end_date'])) : '';
		
		$data = [];
		
		foreach ($boxes->posts as $box)
		{
            $meta = \FireBox\Core\Helpers\BoxHelper::getMeta($box->ID);

			$data[] = [
				'id' => $box->ID,
				'label' => $box->post_title,
				'status' => $box->post_status,
				'trigger' => isset($meta['triggermethod']) ? $meta['triggermethod'] : '',
				'position' => isset($meta['position']) ? $meta['position'] : '',
				'totals' => $this->getBoxAnalyticsTotals($box->ID, $start_date, $end_date)
			];
		}

        echo wp_json_encode($data);
        wp_die();
    }

    /**
     * Delete a campaign by ID.
     * 
     * @return  void
     */
    public function firebox_delete_campaign()
    {
		if (!current_user_can('delete_fireboxes'))
		{
			return;
        }
        
        $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
        
        // verify nonce
        if (!$verify = wp_verify_nonce($nonce, 'fpf_js_nonce'))
        {
            return false;
		}

        $id = isset($_POST['id']) ? intval($_POST['id']) : '';
        if (!$id)
        {
            return;
        }
		
        $error = false;

        if (!wp_delete_post($id, true))
        {
            $error = true;
        }
        
        echo wp_json_encode([
            'error' => $error
        ]);
        wp_die();
    }

    /**
     * Duplicate a campaign by ID.
     * 
     * @return  void
     */
    public function firebox_duplicate_campaign()
    {
		if (!current_user_can('edit_fireboxes'))
		{
			return;
        }
        
        $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
        
        // verify nonce
        if (!$verify = wp_verify_nonce($nonce, 'fpf_js_nonce'))
        {
            return false;
		}

        $id = isset($_POST['id']) ? intval($_POST['id']) : '';
        if (!$id)
        {
            return;
        }
		
        $error = false;

        if (!\FireBox\Core\Helpers\BoxHelper::duplicateBox($id))
        {
            $error = true;
        }
        
        echo wp_json_encode([
            'error' => $error
        ]);
        wp_die();
    }

    /**
     * Retrieve trending templates.
     * 
     * @return  void
     */
    public function firebox_analytics_get_trending_templates()
    {
		if (!current_user_can('read_fireboxes'))
		{
			return;
        }
        
        $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
        
        // verify nonce
        if (!$verify = wp_verify_nonce($nonce, 'fpf_js_nonce'))
        {
            return false;
		}

        $templates = \FPFramework\Helpers\Templates::getTemplates('firebox');

        if (!isset($templates->templates))
        {
            echo wp_json_encode([
                'templates' => []
            ]);
            wp_die();
        }

        $templates = $templates->templates;

        // Find top trending templates
        usort($templates, function($a, $b) {
            return $b->sort->trending - $a->sort->trending;
        });

        // First top 6 trending templates
        $templates = array_slice($templates, 0, 6);

        echo wp_json_encode($templates);
        wp_die();
    }

    private function getBoxAnalyticsTotals($id = null, $start_date = null, $end_date = null)
    {
        if (!$id || !$start_date || !$end_date)
        {
            return;
        }

        $data = new \FireBox\Core\Analytics\Data($start_date, $end_date);

        $metrics = [
            'views',
            'clicks',
            'conversions',
            'conversionrate'
        ];

    	$filters = [
            'campaign' => [
                'value' => [$id]
            ]
        ];
        
        // Use new fluent interface
        $data->metrics($metrics)->filters($filters);

        return $data->getData('count');
    }
}