/**
 * Descomplicar® Crescimento Digital
 * https://descomplicar.pt
 */

<?php

defined('BASEPATH') or exit('No direct script access allowed');

/**
 * Desk-Moloni Dashboard Controller
 * Handles dashboard analytics and monitoring
 * 
 * @package    Desk-Moloni
 * @version    3.0.0
 * @author     Descomplicar Business Solutions
 */
class Dashboard extends AdminController
{
    /**
     * Dashboard Controller Constructor
     *
     * Initializes dashboard-specific models, helpers, and validates user authentication.
     * Sets up all necessary components for dashboard functionality and analytics.
     *
     * @since 3.0.0
     * @author Descomplicar®
     * @throws Exception If user authentication fails or models cannot be loaded
     */
    public function __construct()
    {
        parent::__construct();
        
        // Check if user is authenticated
        if (!is_staff_logged_in()) {
            redirect(admin_url('authentication'));
        }
        
        // Load models with correct names
        $this->load->model('desk_moloni/desk_moloni_config_model', 'config_model');
        $this->load->model('desk_moloni/desk_moloni_sync_queue_model', 'queue_model');
        $this->load->model('desk_moloni/desk_moloni_mapping_model', 'mapping_model');
        $this->load->model('desk_moloni/desk_moloni_sync_log_model', 'sync_log_model');
        $this->load->helper('desk_moloni');
        $this->load->library('form_validation');
    }

    /**
     * Main dashboard interface and analytics display
     *
     * Renders the primary dashboard interface with comprehensive analytics,
     * synchronization statistics, recent activities, and operational metrics.
     *
     * @return void Loads dashboard view with statistical data
     * @throws Exception If permissions are denied or data retrieval fails
     * @since 3.0.0
     * @author Descomplicar®
     */
    public function index(): void
    {
        if (!has_permission('desk_moloni', '', 'view')) {
            access_denied('desk_moloni');
        }

        $data = [
            'title' => _l('desk_moloni_dashboard'),
            'dashboard_stats' => $this->get_dashboard_stats(),
            'recent_activities' => $this->sync_log_model->get_recent_activity(10),
            'queue_summary' => $this->queue_model->get_queue_summary(),
            'mapping_stats' => $this->mapping_model->get_mapping_statistics()
        ];

        $data['title'] = 'Desk-Moloni Dashboard';
        $this->load->view('admin/includes/header', $data);
        $this->load->view('admin/dashboard', $data);
        $this->load->view('admin/includes/footer');
    }

    /**
     * Get dashboard statistics
     */
    private function get_dashboard_stats(): array
    {
        try {
            return [
                'total_queued' => $this->queue_model->get_count(['status' => 'pending']),
                'total_processing' => $this->queue_model->get_count(['status' => 'processing']),
                'total_completed' => $this->queue_model->get_count(['status' => 'completed']),
                'total_failed' => $this->queue_model->get_count(['status' => 'failed']),
                'total_mappings' => $this->mapping_model->get_total_count(),
                'oauth_status' => $this->config_model->isOAuthValid() ? 'connected' : 'disconnected'
            ];
        } catch (Exception $e) {
            log_message('error', 'Dashboard stats error: ' . $e->getMessage());
            return [
                'total_queued' => 0,
                'total_processing' => 0,
                'total_completed' => 0,
                'total_failed' => 0,
                'total_mappings' => 0,
                'oauth_status' => 'unknown'
            ];
        }
    }

    /**
     * Retrieve comprehensive dashboard analytics data
     *
     * Provides detailed analytics including summary statistics, chart data,
     * recent activities, error analysis, and performance metrics for specified time periods.
     *
     * @method GET
     * @param int $days Number of days for analytics period (default: 7)
     * @param string $entity_type Filter by specific entity type (optional)
     * @return void Outputs JSON response with analytics data
     * @throws Exception When analytics data retrieval fails or permissions are denied
     * @since 3.0.0
     * @author Descomplicar®
     */
    public function get_analytics(): void
    {
        if (!has_permission('desk_moloni', '', 'view')) {
            $this->output
                ->set_status_header(403)
                ->set_content_type('application/json')
                ->set_output(json_encode(['success' => false, 'message' => _l('access_denied')]));
            return;
        }

        try {
            $days = (int) $this->input->get('days') ?: 7;
            $entity_type = $this->input->get('entity_type');

            $analytics = [
                'summary' => $this->_get_summary_stats($days, $entity_type),
                'charts' => $this->_get_chart_data($days, $entity_type),
                'recent_activity' => $this->_get_recent_activity(20),
                'error_analysis' => $this->_get_error_analysis($days),
                'performance_metrics' => $this->_get_performance_metrics($days)
            ];

            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => true,
                    'data' => $analytics
                ]));

        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni dashboard analytics error: ' . $e->getMessage());
            
            $this->output
                ->set_status_header(500)
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => false,
                    'message' => $e->getMessage()
                ]));
        }
    }

    /**
     * Retrieve real-time synchronization status
     *
     * Provides live monitoring data including active synchronizations,
     * queue status, error counts, and API health status for real-time dashboard updates.
     *
     * @method GET
     * @return void Outputs JSON response with real-time status information
     * @throws Exception When real-time data retrieval fails or permissions are denied
     * @since 3.0.0
     * @author Descomplicar®
     */
    public function get_realtime_status(): void
    {
        if (!has_permission('desk_moloni', '', 'view')) {
            $this->output
                ->set_status_header(403)
                ->set_content_type('application/json')
                ->set_output(json_encode(['success' => false, 'message' => _l('access_denied')]));
            return;
        }

        try {
            $status = [
                'queue_status' => $this->_get_queue_realtime_status(),
                'active_syncs' => $this->_get_active_syncs(),
                'error_count_last_hour' => $this->_get_error_count_last_hour(),
                'last_successful_sync' => $this->_get_last_successful_sync(),
                'api_health' => $this->_check_api_health()
            ];

            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => true,
                    'data' => $status
                ]));

        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni realtime status error: ' . $e->getMessage());
            
            $this->output
                ->set_status_header(500)
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => false,
                    'message' => $e->getMessage()
                ]));
        }
    }

    /**
     * Get sync rate trends
     */
    public function get_sync_trends(): void
    {
        if (!has_permission('desk_moloni', '', 'view')) {
            $this->output
                ->set_status_header(403)
                ->set_content_type('application/json')
                ->set_output(json_encode(['success' => false, 'message' => _l('access_denied')]));
            return;
        }

        try {
            $period = $this->input->get('period') ?: 'daily';
            $entity_type = $this->input->get('entity_type');
            $days = (int) $this->input->get('days') ?: 30;

            $trends = $this->_get_sync_trends($period, $days, $entity_type);

            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => true,
                    'data' => $trends
                ]));

        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni sync trends error: ' . $e->getMessage());
            
            $this->output
                ->set_status_header(500)
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => false,
                    'message' => $e->getMessage()
                ]));
        }
    }

    /**
     * Export dashboard data
     */
    public function export_data(): void
    {
        if (!has_permission('desk_moloni', '', 'view')) {
            access_denied('desk_moloni');
        }

        try {
            $format = $this->input->get('format') ?: 'csv';
            $type = $this->input->get('type') ?: 'sync_logs';
            $days = (int) $this->input->get('days') ?: 30;

            switch ($type) {
                case 'sync_logs':
                    $this->_export_sync_logs($format, $days);
                    break;
                case 'error_report':
                    $this->_export_error_report($format, $days);
                    break;
                case 'performance_report':
                    $this->_export_performance_report($format, $days);
                    break;
                default:
                    throw new Exception(_l('desk_moloni_invalid_export_type'));
            }

        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni export error: ' . $e->getMessage());
            set_alert('danger', $e->getMessage());
            redirect(admin_url('modules/desk_moloni'));
        }
    }

    /**
     * Get summary statistics
     */
    private function _get_summary_stats(int $days, ?string $entity_type = null): array
    {
        try {
            $date_from = date('Y-m-d H:i:s', strtotime("-{$days} days"));
            
            $filters = ['created_at >=' => $date_from];
            if ($entity_type) {
                $filters['entity_type'] = $entity_type;
            }

            $total_synced = $this->sync_log_model->countLogs($filters);
            $successful_syncs = $this->sync_log_model->countLogs(array_merge($filters, ['status' => 'success']));
            $failed_syncs = $this->sync_log_model->countLogs(array_merge($filters, ['status' => 'error']));

            $stats = [
                'total_synced' => $total_synced,
                'successful_syncs' => $successful_syncs,
                'failed_syncs' => $failed_syncs,
                'sync_success_rate' => $total_synced > 0 ? round(($successful_syncs / $total_synced) * 100, 2) : 0,
                'avg_execution_time' => method_exists($this->sync_log_model, 'getAverageExecutionTime') ? $this->sync_log_model->getAverageExecutionTime($filters) : 0,
                'queue_health_score' => $this->_calculate_queue_health_score()
            ];
            
            return $stats;
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni summary stats error: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * Get chart data for dashboard visualizations
     */
    private function _get_chart_data(int $days, ?string $entity_type = null): array
    {
        try {
            return [
                'sync_volume_chart' => $this->_get_sync_volume_chart($days, $entity_type),
                'success_rate_chart' => $this->_get_success_rate_chart($days, $entity_type),
                'entity_distribution' => $this->_get_entity_sync_distribution($days),
                'error_category_chart' => $this->_get_error_category_distribution($days),
                'performance_chart' => $this->_get_performance_trend_chart($days)
            ];
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni chart data error: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * Get recent activity for dashboard feed
     */
    private function _get_recent_activity(int $limit = 20): array
    {
        try {
            return $this->sync_log_model->getRecentActivity($limit);
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni recent activity error: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * Get error analysis data
     */
    private function _get_error_analysis(int $days): array
    {
        try {
            $date_from = date('Y-m-d H:i:s', strtotime("-{$days} days"));
            
            return [
                'top_errors' => $this->sync_log_model->getTopErrors($days, 10),
                'error_trends' => $this->sync_log_model->getErrorTrends($days),
                'critical_errors' => $this->sync_log_model->getCriticalErrors($days),
                'resolution_suggestions' => $this->_get_error_resolution_suggestions()
            ];
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni error analysis error: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * Get performance metrics
     */
    private function _get_performance_metrics(int $days): array
    {
        try {
            $date_from = date('Y-m-d H:i:s', strtotime("-{$days} days"));
            
            return [
                'avg_response_time' => $this->sync_log_model->getAverageResponseTime($date_from),
                'throughput' => $this->sync_log_model->getThroughputPerHour($date_from),
                'resource_usage' => $this->_get_resource_usage($days),
                'bottlenecks' => $this->_identify_performance_bottlenecks($days)
            ];
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni performance metrics error: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * Check API health status
     */
    private function _check_api_health(): array
    {
        try {
            $this->load->library('desk_moloni/moloni_api_client');
            return $this->moloni_api_client->health_check();
        } catch (Exception $e) {
            return [
                'status' => 'error',
                'message' => $e->getMessage(),
                'timestamp' => date('Y-m-d H:i:s')
            ];
        }
    }

    /**
     * Calculate queue health score
     */
    private function _calculate_queue_health_score(): int
    {
        try {
            $total_tasks = $this->queue_model->countTasks();
            $failed_tasks = $this->queue_model->countTasks(['status' => 'failed']);
            $pending_tasks = $this->queue_model->countTasks(['status' => 'pending']);
            
            if ($total_tasks == 0) return 100;
            
            // Score based on failure rate and queue backlog
            $failure_rate = $failed_tasks / $total_tasks;
            $backlog_ratio = min($pending_tasks / max($total_tasks, 1), 1);
            
            $score = 100 - ($failure_rate * 50) - ($backlog_ratio * 30);
            
            return max(0, round($score, 1));
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni queue health score error: ' . $e->getMessage());
            return 0;
        }
    }

    /**
     * Get queue realtime status
     */
    private function _get_queue_realtime_status(): array
    {
        try {
            return [
                'total_tasks' => $this->queue_model->countTasks(),
                'pending_tasks' => $this->queue_model->countTasks(['status' => 'pending']),
                'processing_tasks' => $this->queue_model->countTasks(['status' => 'processing']),
                'failed_tasks' => $this->queue_model->countTasks(['status' => 'failed']),
                'completed_today' => $this->queue_model->countTasks([
                    'status' => 'completed',
                    'completed_at >=' => date('Y-m-d 00:00:00')
                ])
            ];
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni queue realtime status error: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * Get active syncs
     */
    private function _get_active_syncs(): array
    {
        try {
            return $this->queue_model->getActiveTasks();
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni active syncs error: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * Get error count from last hour
     */
    private function _get_error_count_last_hour(): int
    {
        try {
            $one_hour_ago = date('Y-m-d H:i:s', strtotime('-1 hour'));
            return $this->sync_log_model->countLogs([
                'status' => 'error',
                'created_at >=' => $one_hour_ago
            ]);
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni error count last hour error: ' . $e->getMessage());
            return 0;
        }
    }

    /**
     * Get last successful sync
     */
    private function _get_last_successful_sync(): ?string
    {
        try {
            return $this->sync_log_model->getLastSuccessfulSync();
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni last successful sync error: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * Get sync trends
     */
    private function _get_sync_trends(string $period, int $days, ?string $entity_type = null): array
    {
        try {
            return $this->sync_log_model->getSyncTrends($period, $days, $entity_type);
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni sync trends error: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * Export sync logs
     */
    private function _export_sync_logs(string $format, int $days): void
    {
        $date_from = date('Y-m-d H:i:s', strtotime("-{$days} days"));
        $logs = $this->sync_log_model->getLogsForExport(['created_at >=' => $date_from]);
        
        if ($format === 'csv') {
            $this->_export_as_csv($logs, 'sync_logs_' . date('Y-m-d'));
        } else {
            $this->_export_as_json($logs, 'sync_logs_' . date('Y-m-d'));
        }
    }

    /**
     * Export error report
     */
    private function _export_error_report(string $format, int $days): void
    {
        $date_from = date('Y-m-d H:i:s', strtotime("-{$days} days"));
        $errors = $this->sync_log_model->getErrorReport(['created_at >=' => $date_from]);
        
        if ($format === 'csv') {
            $this->_export_as_csv($errors, 'error_report_' . date('Y-m-d'));
        } else {
            $this->_export_as_json($errors, 'error_report_' . date('Y-m-d'));
        }
    }

    /**
     * Export performance report
     */
    private function _export_performance_report(string $format, int $days): void
    {
        $performance = $this->_get_performance_report($days);
        
        if ($format === 'csv') {
            $this->_export_as_csv($performance, 'performance_report_' . date('Y-m-d'));
        } else {
            $this->_export_as_json($performance, 'performance_report_' . date('Y-m-d'));
        }
    }

    /**
     * Export data as CSV
     */
    private function _export_as_csv(array $data, string $filename): void
    {
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="' . $filename . '.csv"');
        
        $output = fopen('php://output', 'w');
        
        if (!empty($data)) {
            fputcsv($output, array_keys($data[0]));
            foreach ($data as $row) {
                fputcsv($output, $row);
            }
        }
        
        fclose($output);
    }

    /**
     * Export data as JSON
     */
    private function _export_as_json(array $data, string $filename): void
    {
        header('Content-Type: application/json');
        header('Content-Disposition: attachment; filename="' . $filename . '.json"');
        
        echo json_encode($data, JSON_PRETTY_PRINT);
    }

    /**
     * Get performance report data
     */
    private function _get_performance_report(int $days): array
    {
        try {
            $date_from = date('Y-m-d H:i:s', strtotime("-{$days} days"));
            
            return [
                'period' => $days . ' days',
                'from_date' => $date_from,
                'to_date' => date('Y-m-d H:i:s'),
                'metrics' => $this->_get_performance_metrics($days)
            ];
        } catch (Exception $e) {
            log_message('error', 'Desk-Moloni performance report error: ' . $e->getMessage());
            return [];
        }
    }

    /**
     * Placeholder methods for complex analytics (to be implemented)
     */
    private function _get_sync_volume_chart(int $days, ?string $entity_type = null): array { return []; }
    private function _get_success_rate_chart(int $days, ?string $entity_type = null): array { return []; }
    private function _get_entity_sync_distribution(int $days): array { return []; }
    private function _get_error_category_distribution(int $days): array { return []; }
    private function _get_performance_trend_chart(int $days): array { return []; }
    private function _get_error_resolution_suggestions(): array { return []; }
    private function _get_resource_usage(int $days): array { return []; }
    private function _identify_performance_bottlenecks(int $days): array { return []; }
}