<?php

namespace FleekDash\Controllers;

use FleekDash\Controllers\Stats\StatsCache;
use FleekDash\Controllers\Stats\StatsHelpers;
use FleekDash\Libs\API\ResponseService;

/**
 * Stats Controller - Refactored
 *
 * Handles statistics and chart data API endpoints
 * Delegates caching to StatsCache service
 *
 * @package FleekDash\Controllers
 */
class StatsController
{
    private $cache;

    public function __construct()
    {
        $this->cache = new StatsCache();
    }

    /**
     * Register cache invalidation hooks
     */
    public static function register_cache_invalidation_hooks(): void
    {
        StatsCache::registerInvalidationHooks();
    }

    /**
     * Invalidate caches on content change
     */
    public static function invalidate_stats_caches_on_content_change(): void
    {
        StatsCache::invalidateStatsCache();
    }

    /**
     * Check permissions
     */
    public function check_permissions()
    {
        return StatsHelpers::checkPermissions();
    }

    /**
     * Get posts statistics by date range
     */
    public function postsByDate($request)
    {
        try {
            global $wpdb;

            $start_date = $request->get_param('start_date') ?? date('Y-m-d', strtotime('-30 days'));
            $end_date = $request->get_param('end_date') ?? date('Y-m-d');
            $status = $request->get_param('status') ?? 'publish';
            $post_type = $request->get_param('post_type') ?? 'post';

            $cache_key = "posts_by_date_{$start_date}_{$end_date}_{$status}_{$post_type}";
            $cached = $this->cache->get($cache_key);

            if ($cached !== false) {
                return ResponseService::success($cached, 'Posts data (cached)');
            }

            // FIX: Use DATE() for proper date comparison
            $query = $wpdb->prepare(
                "SELECT DATE(post_date) as date, COUNT(*) as count
                 FROM {$wpdb->posts}
                 WHERE post_type = %s
                 AND post_status = %s
                 AND DATE(post_date) >= %s
                 AND DATE(post_date) <= %s
                 GROUP BY DATE(post_date)
                 ORDER BY date ASC",
                $post_type,
                $status,
                $start_date,
                $end_date
            );

            $results = $wpdb->get_results($query, ARRAY_A);

            $this->cache->set($cache_key, $results, 3600);

            return ResponseService::success($results, 'Posts data retrieved');

        } catch (\Exception $e) {
            return ResponseService::error($e->getMessage());
        }
    }

    /**
     * Get posts by author
     */
    public function postsByAuthor($request)
    {
        try {
            global $wpdb;

            $start_date = $request->get_param('start_date') ?? date('Y-m-d', strtotime('-30 days'));
            $end_date = $request->get_param('end_date') ?? date('Y-m-d');
            $post_type = $request->get_param('post_type') ?? 'post';

            $cache_key = "posts_by_author_{$start_date}_{$end_date}_{$post_type}";
            $cached = $this->cache->get($cache_key);

            if ($cached !== false) {
                return ResponseService::success($cached, 'Author data (cached)');
            }

            // FIX: Use DATE() for proper date comparison
            $query = $wpdb->prepare(
                "SELECT u.display_name as author, COUNT(*) as post_count
                 FROM {$wpdb->posts} p
                 INNER JOIN {$wpdb->users} u ON p.post_author = u.ID
                 WHERE p.post_type = %s
                 AND p.post_status = 'publish'
                 AND DATE(p.post_date) >= %s
                 AND DATE(p.post_date) <= %s
                 GROUP BY p.post_author
                 ORDER BY post_count DESC",
                $post_type,
                $start_date,
                $end_date
            );

            $results = $wpdb->get_results($query, ARRAY_A);

            $this->cache->set($cache_key, $results, 3600);

            return ResponseService::success($results, 'Author data retrieved');

        } catch (\Exception $e) {
            return ResponseService::error($e->getMessage());
        }
    }

    /**
     * Get posts by taxonomy
     */
    public function postsByTaxonomy($request)
    {
        try {
            global $wpdb;

            $taxonomy = $request->get_param('taxonomy') ?? 'category';
            $post_type = $request->get_param('post_type') ?? 'post';

            $cache_key = "posts_by_taxonomy_{$taxonomy}_{$post_type}";
            $cached = $this->cache->get($cache_key);

            if ($cached !== false) {
                return ResponseService::success($cached, 'Taxonomy data (cached)');
            }

            $query = $wpdb->prepare(
                "SELECT t.name as term, COUNT(*) as post_count
                 FROM {$wpdb->posts} p
                 INNER JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id
                 INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
                 INNER JOIN {$wpdb->terms} t ON tt.term_id = t.term_id
                 WHERE p.post_type = %s
                 AND p.post_status = 'publish'
                 AND tt.taxonomy = %s
                 GROUP BY t.term_id
                 ORDER BY post_count DESC
                 LIMIT 10",
                $post_type,
                $taxonomy
            );

            $results = $wpdb->get_results($query, ARRAY_A);

            $this->cache->set($cache_key, $results, 3600);

            return ResponseService::success($results, 'Taxonomy data retrieved');

        } catch (\Exception $e) {
            return ResponseService::error($e->getMessage());
        }
    }

    /**
     * Get comments by date
     */
    public function commentsByDate($request)
    {
        try {
            global $wpdb;

            $start_date = $request->get_param('start_date') ?? date('Y-m-d', strtotime('-30 days'));
            $end_date = $request->get_param('end_date') ?? date('Y-m-d');

            $cache_key = "comments_by_date_{$start_date}_{$end_date}";
            $cached = $this->cache->get($cache_key);

            if ($cached !== false) {
                return ResponseService::success($cached, 'Comments data (cached)');
            }

            // FIX: Use DATE() for proper date comparison
            $query = $wpdb->prepare(
                "SELECT DATE(comment_date) as date, COUNT(*) as count
                 FROM {$wpdb->comments}
                 WHERE comment_approved = '1'
                 AND DATE(comment_date) >= %s
                 AND DATE(comment_date) <= %s
                 GROUP BY DATE(comment_date)
                 ORDER BY date ASC",
                $start_date,
                $end_date
            );

            $results = $wpdb->get_results($query, ARRAY_A);

            $this->cache->set($cache_key, $results, 3600);

            return ResponseService::success($results, 'Comments data retrieved');

        } catch (\Exception $e) {
            return ResponseService::error($e->getMessage());
        }
    }

    /**
     * Get user registrations by date
     */
    public function userRegistrationsByDate($request)
    {
        try {
            global $wpdb;

            $start_date = $request->get_param('start_date') ?? date('Y-m-d', strtotime('-30 days'));
            $end_date = $request->get_param('end_date') ?? date('Y-m-d');

            $cache_key = "user_registrations_{$start_date}_{$end_date}";
            $cached = $this->cache->get($cache_key);

            if ($cached !== false) {
                return ResponseService::success($cached, 'User data (cached)');
            }

            // FIX: Use DATE() for proper date comparison
            $query = $wpdb->prepare(
                "SELECT DATE(user_registered) as date, COUNT(*) as count
                 FROM {$wpdb->users}
                 WHERE DATE(user_registered) >= %s
                 AND DATE(user_registered) <= %s
                 GROUP BY DATE(user_registered)
                 ORDER BY date ASC",
                $start_date,
                $end_date
            );

            $results = $wpdb->get_results($query, ARRAY_A);

            $this->cache->set($cache_key, $results, 3600);

            return ResponseService::success($results, 'User registrations retrieved');

        } catch (\Exception $e) {
            return ResponseService::error($e->getMessage());
        }
    }

    /**
     * Get dashboard stats
     */
    public function dashboardStats($request)
    {
        try {
            $cache_key = 'dashboard_stats';
            $cached = $this->cache->get($cache_key);

            if ($cached !== false) {
                return ResponseService::success($cached, 'Dashboard stats (cached)');
            }

            $stats = [
                'posts' => [
                    'total' => wp_count_posts()->publish ?? 0,
                    'draft' => wp_count_posts()->draft ?? 0,
                ],
                'comments' => [
                    'total' => wp_count_comments()->approved ?? 0,
                    'pending' => wp_count_comments()->moderated ?? 0,
                ],
                'users' => [
                    'total' => count_users()['total_users'] ?? 0,
                ],
                'pages' => [
                    'total' => wp_count_posts('page')->publish ?? 0,
                ]
            ];

            $this->cache->set($cache_key, $stats, 300);

            return ResponseService::success($stats, 'Dashboard stats retrieved');

        } catch (\Exception $e) {
            return ResponseService::error($e->getMessage());
        }
    }

    /**
     * Clear stats cache
     */
    public function clearCache($request)
    {
        StatsCache::invalidateStatsCache();
        return ResponseService::success([], 'Cache cleared successfully');
    }

    /**
     * Get large dataset with resampling
     */
    public function largeDataset($request)
    {
        try {
            global $wpdb;

            $max_points = (int) $request->get_param('max_points') ?? 100;
            $days = (int) $request->get_param('days') ?? 365;

            $cache_key = "large_dataset_{$days}_{$max_points}";
            $cached = $this->cache->get($cache_key);

            if ($cached !== false) {
                return ResponseService::success($cached, 'Large dataset (cached)');
            }

            $start_date = date('Y-m-d', strtotime("-{$days} days"));
            $end_date = date('Y-m-d');

            // FIX: Use DATE() for proper date comparison
            $query = $wpdb->prepare(
                "SELECT DATE(post_date) as date, COUNT(*) as count
                 FROM {$wpdb->posts}
                 WHERE post_type = 'post'
                 AND post_status = 'publish'
                 AND DATE(post_date) >= %s
                 AND DATE(post_date) <= %s
                 GROUP BY DATE(post_date)
                 ORDER BY date ASC",
                $start_date,
                $end_date
            );

            $results = $wpdb->get_results($query, ARRAY_A);

            $labels = array_column($results, 'date');
            $values = array_column($results, 'count');

            $resampled = StatsHelpers::resampleDataPoints($labels, $values, $max_points);

            $this->cache->set($cache_key, $resampled, 1800);

            return ResponseService::success($resampled, 'Large dataset retrieved');

        } catch (\Exception $e) {
            return ResponseService::error($e->getMessage());
        }
    }

    /**
     * Get chart data
     */
    public function chartData($request)
    {
        try {
            $type = $request->get_param('type') ?? 'posts';
            $period = $request->get_param('period') ?? '30d';

            $cache_key = "chart_data_{$type}_{$period}";
            $cached = $this->cache->get($cache_key);

            if ($cached !== false) {
                return ResponseService::success($cached, 'Chart data (cached)');
            }

            // Map period to days
            $days_map = ['7d' => 7, '30d' => 30, '90d' => 90, '1y' => 365];
            $days = $days_map[$period] ?? 30;

            $data = [];

            switch ($type) {
                case 'posts':
                    $request->set_param('start_date', date('Y-m-d', strtotime("-{$days} days")));
                    $request->set_param('end_date', date('Y-m-d'));
                    $response = $this->postsByDate($request);
                    $data = $response->get_data()['data'] ?? [];
                    break;

                case 'comments':
                    $request->set_param('start_date', date('Y-m-d', strtotime("-{$days} days")));
                    $request->set_param('end_date', date('Y-m-d'));
                    $response = $this->commentsByDate($request);
                    $data = $response->get_data()['data'] ?? [];
                    break;

                case 'users':
                    $request->set_param('start_date', date('Y-m-d', strtotime("-{$days} days")));
                    $request->set_param('end_date', date('Y-m-d'));
                    $response = $this->userRegistrationsByDate($request);
                    $data = $response->get_data()['data'] ?? [];
                    break;
            }

            $this->cache->set($cache_key, $data, 1800);

            return ResponseService::success($data, 'Chart data retrieved');

        } catch (\Exception $e) {
            return ResponseService::error($e->getMessage());
        }
    }
}
