<?php
/**
 * ZLO Platform - Analytics Controller
 */

declare(strict_types=1);

require_once __DIR__ . '/../core/Router.php';

class AnalyticsController
{
    private Database $db;
    
    public function __construct()
    {
        $this->db = new Database();
    }
    
    /**
     * Track page view (public)
     */
    public function track(array $params): array
    {
        $body = Router::getBody();
        $security = new Security();
        
        $data = [
            'page' => $body['page'] ?? $_SERVER['HTTP_REFERER'] ?? '/',
            'page_type' => $body['page_type'] ?? 'page',
            'visitor_id' => $body['visitor_id'] ?? $this->generateVisitorId(),
            'session_id' => $body['session_id'] ?? null,
            'visitor_ip' => $security->getClientIp(),
            'country' => $body['country'] ?? null,
            'city' => $body['city'] ?? null,
            'device_type' => $this->detectDeviceType(),
            'browser' => $this->detectBrowser(),
            'os' => $this->detectOS(),
            'referrer' => $body['referrer'] ?? $_SERVER['HTTP_REFERER'] ?? null,
            'utm_source' => $body['utm_source'] ?? null,
            'utm_medium' => $body['utm_medium'] ?? null,
            'utm_campaign' => $body['utm_campaign'] ?? null,
            'time_on_page' => $body['time_on_page'] ?? 0,
            'visited_at' => date('Y-m-d H:i:s')
        ];
        
        try {
            $this->db->insert('analytics', $data);
            return ['success' => true];
        } catch (Exception $e) {
            return ['success' => false];
        }
    }
    
    /**
     * Get analytics dashboard (admin)
     */
    public function dashboard(array $params): array
    {
        AuthController::requirePermission('analytics.view');
        
        $query = Router::getQuery();
        $days = (int) ($query['days'] ?? 30);
        
        $startDate = date('Y-m-d', strtotime("-{$days} days"));
        
        return [
            'overview' => $this->getOverviewStats($startDate),
            'traffic' => $this->getTrafficStats($startDate),
            'devices' => $this->getDeviceStats($startDate),
            'top_pages' => $this->getTopPages($startDate),
            'referrers' => $this->getReferrers($startDate),
            'countries' => $this->getCountries($startDate),
            'utm_stats' => $this->getUtmStats($startDate)
        ];
    }
    
    /**
     * Get traffic data (admin)
     */
    public function traffic(array $params): array
    {
        AuthController::requirePermission('analytics.view');
        
        $query = Router::getQuery();
        $days = (int) ($query['days'] ?? 30);
        
        return [
            'daily' => $this->getDailyTraffic($days)
        ];
    }
    
    /**
     * Get real-time stats (admin)
     */
    public function realtime(array $params): array
    {
        AuthController::requirePermission('analytics.view');
        
        // Active visitors in last 5 minutes
        $activeVisitors = $this->db->fetchOne(
            "SELECT COUNT(DISTINCT visitor_id) as count FROM analytics WHERE visited_at >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)"
        );
        
        // Page views in last 30 minutes
        $recentViews = $this->db->fetchOne(
            "SELECT COUNT(*) as count FROM analytics WHERE visited_at >= DATE_SUB(NOW(), INTERVAL 30 MINUTE)"
        );
        
        // Current active pages
        $activePages = $this->db->fetchAll(
            "SELECT page, COUNT(*) as views 
             FROM analytics 
             WHERE visited_at >= DATE_SUB(NOW(), INTERVAL 5 MINUTE) 
             GROUP BY page 
             ORDER BY views DESC 
             LIMIT 10"
        );
        
        return [
            'active_visitors' => (int) ($activeVisitors['count'] ?? 0),
            'recent_views' => (int) ($recentViews['count'] ?? 0),
            'active_pages' => $activePages
        ];
    }
    
    /**
     * Get overview stats
     */
    private function getOverviewStats(string $startDate): array
    {
        // Total page views
        $pageViews = $this->db->fetchOne(
            "SELECT COUNT(*) as count FROM analytics WHERE DATE(visited_at) >= ?",
            [$startDate]
        );
        
        // Unique visitors
        $uniqueVisitors = $this->db->fetchOne(
            "SELECT COUNT(DISTINCT visitor_id) as count FROM analytics WHERE DATE(visited_at) >= ?",
            [$startDate]
        );
        
        // Unique sessions
        $sessions = $this->db->fetchOne(
            "SELECT COUNT(DISTINCT session_id) as count FROM analytics WHERE DATE(visited_at) >= ?",
            [$startDate]
        );
        
        // Avg time on page
        $avgTime = $this->db->fetchOne(
            "SELECT AVG(time_on_page) as avg FROM analytics WHERE DATE(visited_at) >= ? AND time_on_page > 0",
            [$startDate]
        );
        
        return [
            'page_views' => (int) ($pageViews['count'] ?? 0),
            'unique_visitors' => (int) ($uniqueVisitors['count'] ?? 0),
            'sessions' => (int) ($sessions['count'] ?? 0),
            'avg_time_on_page' => (int) ($avgTime['avg'] ?? 0),
            'pages_per_session' => $sessions['count'] > 0 ? round($pageViews['count'] / $sessions['count'], 2) : 0
        ];
    }
    
    /**
     * Get traffic stats
     */
    private function getTrafficStats(string $startDate): array
    {
        $result = $this->db->fetchOne(
            "SELECT 
                COUNT(*) as total_views,
                COUNT(DISTINCT visitor_id) as unique_visitors,
                COUNT(DISTINCT session_id) as sessions
             FROM analytics 
             WHERE DATE(visited_at) >= ?",
            [$startDate]
        );
        
        return [
            'total_views' => (int) ($result['total_views'] ?? 0),
            'unique_visitors' => (int) ($result['unique_visitors'] ?? 0),
            'sessions' => (int) ($result['sessions'] ?? 0)
        ];
    }
    
    /**
     * Get device stats
     */
    private function getDeviceStats(string $startDate): array
    {
        return $this->db->fetchAll(
            "SELECT device_type, COUNT(*) as count 
             FROM analytics 
             WHERE DATE(visited_at) >= ? 
             GROUP BY device_type 
             ORDER BY count DESC",
            [$startDate]
        );
    }
    
    /**
     * Get top pages
     */
    private function getTopPages(string $startDate, int $limit = 10): array
    {
        return $this->db->fetchAll(
            "SELECT page, page_type, COUNT(*) as views, COUNT(DISTINCT visitor_id) as unique_visitors 
             FROM analytics 
             WHERE DATE(visited_at) >= ? 
             GROUP BY page 
             ORDER BY views DESC 
             LIMIT ?",
            [$startDate, $limit]
        );
    }
    
    /**
     * Get referrers
     */
    private function getReferrers(string $startDate, int $limit = 10): array
    {
        return $this->db->fetchAll(
            "SELECT referrer, COUNT(*) as count 
             FROM analytics 
             WHERE DATE(visited_at) >= ? AND referrer IS NOT NULL 
             GROUP BY referrer 
             ORDER BY count DESC 
             LIMIT ?",
            [$startDate, $limit]
        );
    }
    
    /**
     * Get countries
     */
    private function getCountries(string $startDate, int $limit = 10): array
    {
        return $this->db->fetchAll(
            "SELECT country, COUNT(*) as count 
             FROM analytics 
             WHERE DATE(visited_at) >= ? AND country IS NOT NULL 
             GROUP BY country 
             ORDER BY count DESC 
             LIMIT ?",
            [$startDate, $limit]
        );
    }
    
    /**
     * Get UTM stats
     */
    private function getUtmStats(string $startDate): array
    {
        $sources = $this->db->fetchAll(
            "SELECT utm_source, COUNT(*) as count 
             FROM analytics 
             WHERE DATE(visited_at) >= ? AND utm_source IS NOT NULL 
             GROUP BY utm_source 
             ORDER BY count DESC 
             LIMIT 10",
            [$startDate]
        );
        
        $campaigns = $this->db->fetchAll(
            "SELECT utm_campaign, COUNT(*) as count 
             FROM analytics 
             WHERE DATE(visited_at) >= ? AND utm_campaign IS NOT NULL 
             GROUP BY utm_campaign 
             ORDER BY count DESC 
             LIMIT 10",
            [$startDate]
        );
        
        return [
            'sources' => $sources,
            'campaigns' => $campaigns
        ];
    }
    
    /**
     * Get daily traffic
     */
    private function getDailyTraffic(int $days): array
    {
        return $this->db->fetchAll(
            "SELECT 
                DATE(visited_at) as date,
                COUNT(*) as page_views,
                COUNT(DISTINCT visitor_id) as unique_visitors,
                COUNT(DISTINCT session_id) as sessions
             FROM analytics 
             WHERE visited_at >= DATE_SUB(NOW(), INTERVAL ? DAY)
             GROUP BY DATE(visited_at)
             ORDER BY date DESC",
            [$days]
        );
    }
    
    /**
     * Generate visitor ID
     */
    private function generateVisitorId(): string
    {
        return md5($_SERVER['HTTP_USER_AGENT'] ?? '' . $_SERVER['REMOTE_ADDR'] ?? '' . time());
    }
    
    /**
     * Detect device type
     */
    private function detectDeviceType(): string
    {
        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        
        if (preg_match('/(tablet|ipad|playbook)|(android(?!.*(mobi|opera mini)))/i', $userAgent)) {
            return 'tablet';
        }
        
        if (preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone|android|iemobile)/i', $userAgent)) {
            return 'mobile';
        }
        
        return 'desktop';
    }
    
    /**
     * Detect browser
     */
    private function detectBrowser(): ?string
    {
        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        
        $browsers = [
            'Chrome' => '/Chrome\/([0-9.]+)/',
            'Firefox' => '/Firefox\/([0-9.]+)/',
            'Safari' => '/Safari\/([0-9.]+)/',
            'Edge' => '/Edg\/([0-9.]+)/',
            'Opera' => '/Opera\/([0-9.]+)/',
        ];
        
        foreach ($browsers as $name => $pattern) {
            if (preg_match($pattern, $userAgent, $matches)) {
                return $name . ' ' . ($matches[1] ?? '');
            }
        }
        
        return null;
    }
    
    /**
     * Detect OS
     */
    private function detectOS(): ?string
    {
        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        
        $oses = [
            'Windows' => '/Windows NT ([0-9.]+)/',
            'Mac OS' => '/Mac OS X ([0-9._]+)/',
            'Linux' => '/Linux/',
            'Android' => '/Android ([0-9.]+)/',
            'iOS' => '/OS ([0-9_]+)/',
        ];
        
        foreach ($oses as $name => $pattern) {
            if (preg_match($pattern, $userAgent, $matches)) {
                return $name;
            }
        }
        
        return null;
    }
}
