<?php

namespace FleekDash\Controllers;

// Load debug helpers
if (!function_exists('fleekdash_log_debug')) {
    require_once FLEEKDASH_PLUGIN_DIR . 'includes/Core/debug-helpers.php';
}

use FleekDash\Core\AuthMiddleware;
use FleekDash\Services\SiteGrowthMeterService;
use FleekDash\Controllers\SiteGrowth\GrowthEventsRepository;
use FleekDash\Controllers\SiteGrowth\GrowthDataProcessor;
use FleekDash\Controllers\SiteGrowth\EventsManagement;
use FleekDash\Controllers\SiteGrowth\GoalsManagement;
use FleekDash\Controllers\SiteGrowth\TemplatesManagement;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;

/**
 * @since 2.2.0 Refactored - Uses GrowthEventsRepository, GrowthDataProcessor and management traits
 */
class SiteGrowthMeterController
{
    use EventsManagement;
    use GoalsManagement;
    use TemplatesManagement;

    private $growth_service;
    private $repository;
    private $processor;

    public function __construct()
    {
        $this->growth_service = new SiteGrowthMeterService();
        $this->repository = new GrowthEventsRepository();
        $this->processor = new GrowthDataProcessor();
    }

    /**
     * Initialize Site Growth Meter
     */
    public function initialize(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth_graceful('authenticated');

            if (!($auth['authenticated'] ?? false)) {
                return new WP_REST_Response([
                    'success' => false,
                    'message' => 'Authentication required to initialize Growth Meter',
                    'auth_status' => 'fallback'
                ], 401);
            }

            $template_id = $request->get_param('template_id');
            $result = $this->growth_service->initializeSiteGrowthMeter($template_id);

            return new WP_REST_Response([
                'success' => $result['success'],
                'data' => $result,
                'message' => $result['message'],
                'auth_status' => 'authenticated'
            ], $result['success'] ? 200 : 400);

        } catch (\Exception $e) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Error initializing Site Growth Meter: ' . $e->getMessage(),
                'auth_status' => 'error'
            ], 500);
        }
    }

    /**
     * Get dashboard data
     */
    public function getDashboard(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth_graceful('authenticated');

            $period = $request->get_param('period') ?: 'monthly';
            $data = $this->growth_service->getDashboardData($period);

            return new WP_REST_Response([
                'success' => true,
                'data' => $data,
                'auth_status' => ($auth['authenticated'] ?? false) ? 'authenticated' : 'fallback'
            ], 200);

        } catch (\Exception $e) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Error getting dashboard data: ' . $e->getMessage(),
                'auth_status' => 'error'
            ], 500);
        }
    }


    /**
     * Get current points map (weights)
     */
    public function getPointsMap(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth_graceful('authenticated');
            $map = $this->growth_service->getEventPointsMap();
            return new WP_REST_Response([
                'success' => true,
                'data' => [
                    'points_map' => $map,
                ],
                'auth_status' => ($auth['authenticated'] ?? false) ? 'authenticated' : 'fallback'
            ], 200);
        } catch (\Exception $e) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Error getting points map: ' . $e->getMessage(),
                'auth_status' => 'error'
            ], 500);
        }
    }

    /**
     * Save full points map
     */
    public function savePointsMap(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth_graceful('authenticated');

            if (!($auth['authenticated'] ?? false)) {
                return new WP_REST_Response([
                    'success' => false,
                    'message' => 'Authentication required to save points map',
                    'auth_status' => 'fallback'
                ], 401);
            }

            $params = $request->get_json_params();
            $map = isset($params['points_map']) && is_array($params['points_map']) ? $params['points_map'] : [];
            $saved = $this->growth_service->savePointsMap($map);

            return new WP_REST_Response([
                'success' => true,
                'data' => [
                    'points_map' => $saved,
                ],
                'auth_status' => 'authenticated'
            ], 200);

        } catch (\Exception $e) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Error saving points map: ' . $e->getMessage(),
                'auth_status' => 'error'
            ], 500);
        }
    }


    /**
     * Get analytics data
     */
    public function getAnalytics(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth_graceful('authenticated');

            if (!($auth['authenticated'] ?? false)) {
                return new WP_REST_Response([
                    'success' => false,
                    'message' => 'Authentication required to get analytics',
                    'auth_status' => 'fallback'
                ], 401);
            }

            $period = $request->get_param('period') ?: 'monthly';
            $days = $request->get_param('days') ?: 30;

            $raw = $this->growth_service->getAnalyticsData($period, $days);

            // Build analytics shape expected by frontend: analytics.chart_data/breakdown/trends
            $breakdown = [];
            if (!empty($raw['metrics']) && is_array($raw['metrics'])) {
                foreach ($raw['metrics'] as $type => $row) {
                    $points = isset($row['points']) ? (int) $row['points'] : 0;
                    $breakdown[$type] = $points;
                }
            }

            // Translate trends to expected fields
            $trendData = [
                'trend' => 'stable',
                'change' => 0,
                'recent_avg' => 0,
                'earlier_avg' => 0,
            ];
            if (!empty($raw['trends']) && is_array($raw['trends'])) {
                $dir = isset($raw['trends']['trend_direction']) ? (string) $raw['trends']['trend_direction'] : 'stable';
                $rate = isset($raw['trends']['growth_rate']) ? (float) $raw['trends']['growth_rate'] : 0;
                $trendData['trend'] = in_array($dir, ['rising', 'falling', 'stable'], true) ? $dir : 'stable';
                $trendData['change'] = $rate;
            }

            $data = [
                'period' => $period,
                'days' => (int) $days,
                'analytics' => [
                    'chart_data' => [], // No historical series yet; can be populated from site_growth_scores snapshots
                    'breakdown' => $breakdown,
                    'trends' => $trendData,
                ],
            ];

            return new WP_REST_Response([
                'success' => true,
                'data' => $data,
                'auth_status' => 'authenticated'
            ], 200);

        } catch (\Exception $e) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Error getting analytics: ' . $e->getMessage(),
                'auth_status' => 'error'
            ], 500);
        }
    }

    /**
     * Force initialize Site Growth Meter
     */
    public function forceInitialize(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth_graceful('authenticated');

            if (!($auth['authenticated'] ?? false)) {
                return new WP_REST_Response([
                    'success' => false,
                    'message' => 'Authentication required to force initialize Growth Meter',
                    'auth_status' => 'fallback'
                ], 401);
            }

            $result = $this->growth_service->initializeSiteGrowthMeter();

            return new WP_REST_Response([
                'success' => $result['success'],
                'data' => $result,
                'message' => $result['success'] ? 'Site Growth Meter initialized successfully' : 'Failed to initialize Site Growth Meter',
                'auth_status' => 'authenticated'
            ], $result['success'] ? 200 : 400);

        } catch (\Exception $e) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Error force initializing Site Growth Meter: ' . $e->getMessage(),
                'auth_status' => 'error'
            ], 500);
        }
    }



    /**
     * Get leaderboard data
     */
    public function getLeaderboard(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth_graceful('authenticated');

            if (!($auth['authenticated'] ?? false)) {
                return new WP_REST_Response([
                    'success' => false,
                    'message' => 'Authentication required to get leaderboard',
                    'auth_status' => 'fallback'
                ], 401);
            }

            $period = $request->get_param('period') ?: 'monthly';
            $limit = $request->get_param('limit') ?: 10;

            // For site-wide, leaderboard could show top performing events or goals
            $data = [
                'top_events' => \FleekDash\Models\SiteGrowthEvent::getActive(),
                // Goals system removed - using Achievements system instead
                'period' => $period,
                'limit' => $limit
            ];

            return new WP_REST_Response([
                'success' => true,
                'data' => $data,
                'auth_status' => 'authenticated'
            ], 200);

        } catch (\Exception $e) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Error getting leaderboard: ' . $e->getMessage(),
                'auth_status' => 'error'
            ], 500);
        }
    }


    /**
     * Export data
     */
    public function exportData(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth_graceful('authenticated');

            if (!($auth['authenticated'] ?? false)) {
                return new WP_REST_Response([
                    'success' => false,
                    'message' => 'Authentication required to export data',
                    'auth_status' => 'fallback'
                ], 401);
            }

            $format = $request->get_param('format') ?: 'json';

            $data = [
                'events' => \FleekDash\Models\SiteGrowthEvent::getActive(),
                // Goals system removed - using Achievements system instead
                'templates' => \FleekDash\Models\SiteGrowthTemplate::getActive(),
                'exported_at' => \current_time('mysql'),
                'format' => $format
            ];

            return new WP_REST_Response([
                'success' => true,
                'data' => $data,
                'auth_status' => 'authenticated'
            ], 200);

        } catch (\Exception $e) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Error exporting data: ' . $e->getMessage(),
                'auth_status' => 'error'
            ], 500);
        }
    }

    /**
     * Check authentication
     */
    private function check_auth($required_level = 'authenticated')
    {
        if (!\is_user_logged_in()) {
            throw new \Exception('User not authenticated');
        }

        $user = \wp_get_current_user();

        if ($required_level === 'admin' && !\current_user_can('manage_options')) {
            throw new \Exception('Insufficient permissions');
        }

        if (!$user || !is_object($user) || empty($user->ID)) {
            throw new \Exception('User object is invalid or not found');
        }

        return [
            'user_id' => $user->ID,
            'user_login' => isset($user->user_login) ? $user->user_login : '',
            'user_email' => isset($user->user_email) ? $user->user_email : ''
        ];
    }

    /**
     * Get snapshot scheduler status
     */
    public function getSnapshotStatus(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth_graceful('authenticated');

            if (!class_exists('FleekDash\\Services\\SiteGrowthMeter\\SnapshotScheduler')) {
                return new WP_REST_Response([
                    'success' => false,
                    'message' => 'SnapshotScheduler class not found',
                    'auth_status' => 'error'
                ], 500);
            }

            $next_run = \FleekDash\Services\SiteGrowthMeter\SnapshotScheduler::isScheduled();
            $cron_disabled = defined('DISABLE_WP_CRON') && DISABLE_WP_CRON;

            return new WP_REST_Response([
                'success' => true,
                'data' => [
                    'scheduled' => $next_run !== false,
                    'next_run' => $next_run ? date('Y-m-d H:i:s', $next_run) : null,
                    'next_run_timestamp' => $next_run,
                    'cron_disabled' => $cron_disabled,
                    'hook' => 'fleekdash_growth_meter_monthly_snapshot',
                    'interval' => 'monthly'
                ],
                'auth_status' => ($auth['authenticated'] ?? false) ? 'authenticated' : 'fallback'
            ], 200);

        } catch (\Exception $e) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Error getting snapshot status: ' . $e->getMessage(),
                'auth_status' => 'error'
            ], 500);
        }
    }

    /**
     * Manually trigger snapshot creation
     */
    public function triggerSnapshot(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth_graceful('admin');

            if (!($auth['authenticated'] ?? false)) {
                return new WP_REST_Response([
                    'success' => false,
                    'message' => 'Admin access required',
                    'auth_status' => 'fallback'
                ], 401);
            }

            if (!class_exists('FleekDash\\Services\\SiteGrowthMeter\\SnapshotScheduler')) {
                return new WP_REST_Response([
                    'success' => false,
                    'message' => 'SnapshotScheduler class not found',
                    'auth_status' => 'error'
                ], 500);
            }

            $month_year = $request->get_param('month_year');

            $result = \FleekDash\Services\SiteGrowthMeter\SnapshotScheduler::triggerManually($month_year);

            return new WP_REST_Response([
                'success' => $result,
                'message' => $result
                    ? 'Snapshot created successfully'
                    : 'Failed to create snapshot',
                'data' => [
                    'month_year' => $month_year ?: date('Y-m')
                ],
                'auth_status' => 'authenticated'
            ], $result ? 200 : 500);

        } catch (\Exception $e) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Error triggering snapshot: ' . $e->getMessage(),
                'auth_status' => 'error'
            ], 500);
        }
    }

    /**
     * Recalculate all points manually
     *
     * Allows users to manually trigger a recalculation of all growth points
     * by syncing event occurrences with real WordPress data and updating snapshots
     */
    public function recalculatePoints(WP_REST_Request $request)
    {
        try {
            $auth = $this->check_auth_graceful('authenticated');

            if (!($auth['authenticated'] ?? false)) {
                return new WP_REST_Response([
                    'success' => false,
                    'message' => 'Authentication required to recalculate points',
                    'auth_status' => 'fallback'
                ], 401);
            }

            $result = $this->growth_service->recalculatePoints();

            return new WP_REST_Response([
                'success' => $result['success'],
                'data' => $result,
                'message' => $result['message'] ?? 'Points recalculated successfully',
                'auth_status' => 'authenticated'
            ], $result['success'] ? 200 : 500);

        } catch (\Exception $e) {
            return new WP_REST_Response([
                'success' => false,
                'message' => 'Error recalculating points: ' . $e->getMessage(),
                'auth_status' => 'error'
            ], 500);
        }
    }

    /**
     * Graceful auth check: never throws, logs and returns unauthenticated state
     */
    private function check_auth_graceful($required_level = 'authenticated')
    {
        try {
            $auth = AuthMiddleware::check($required_level);
            if (!$auth['authenticated']) {
                fleekdash_log_debug('FleekDash: Access without proper authentication');
            }
            return $auth;
        } catch (\Throwable $e) {
            fleekdash_log_error('FleekDash: AuthMiddleware error: ' . $e->getMessage());
            return [
                'authenticated' => false,
                'user_id' => 0,
                'level' => $required_level,
            ];
        }
    }
}
