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

<?php

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

/**
 * Desk-Moloni Logs Controller
 * Handles log viewing and monitoring
 * 
 * @package    Desk-Moloni
 * @version    3.0.0
 * @author     Descomplicar Business Solutions
 */
class Logs extends AdminController
{
    public function __construct()
    {
        parent::__construct();
        $this->load->model('desk_moloni/desk_moloni_sync_log_model', 'sync_log_model');
        $this->load->model('desk_moloni/desk_moloni_config_model', 'config_model');
    }

    /**
     * Logs viewing interface
     */
    public function index()
    {
        if (!has_permission('desk_moloni', '', 'view')) {
            access_denied('desk_moloni');
        }

        $data = [
            'title' => _l('desk_moloni_sync_logs'),
            'entity_types' => ['client', 'product', 'invoice', 'estimate', 'credit_note'],
            'log_stats' => method_exists($this->sync_log_model, 'get_log_statistics') ? $this->sync_log_model->get_log_statistics() : []
        ];

        $this->load->view('admin/includes/header', $data);
        $this->load->view('admin/logs', $data);
        $this->load->view('admin/includes/footer');
    }

    /**
     * Get logs with filtering and pagination
     */
    public function get_logs()
    {
        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 {
            $filters = [
                'entity_type' => $this->input->get('entity_type'),
                'status' => $this->input->get('status'),
                'operation_type' => $this->input->get('operation_type'),
                'direction' => $this->input->get('direction'),
                'from_date' => $this->input->get('from_date'),
                'to_date' => $this->input->get('to_date'),
                'search' => $this->input->get('search')
            ];

            $pagination = [
                'limit' => (int) $this->input->get('limit') ?: 100,
                'offset' => (int) $this->input->get('offset') ?: 0
            ];

            $sort = [
                'field' => $this->input->get('sort_field') ?: 'created_at',
                'direction' => $this->input->get('sort_direction') ?: 'desc'
            ];

            $log_data = $this->sync_log_model->get_filtered_logs($filters, $pagination, $sort);

            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => true,
                    'data' => [
                        'total' => $log_data['total'],
                        'logs' => $log_data['logs'],
                        'pagination' => [
                            'current_page' => floor($pagination['offset'] / $pagination['limit']) + 1,
                            'per_page' => $pagination['limit'],
                            'total_items' => $log_data['total'],
                            'total_pages' => ceil($log_data['total'] / $pagination['limit'])
                        ]
                    ]
                ]));

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

    /**
     * Get detailed log entry
     */
    public function get_log_details($log_id)
    {
        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 {
            $log_id = (int) $log_id;
            
            if (!$log_id) {
                throw new Exception(_l('desk_moloni_invalid_log_id'));
            }

            $log = method_exists($this->sync_log_model, 'get_log_details') ? $this->sync_log_model->get_log_details($log_id) : null;

            if (!$log) {
                throw new Exception(_l('desk_moloni_log_not_found'));
            }

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

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

    /**
     * Get log statistics
     */
    public function get_statistics()
    {
        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');

            $statistics = [
                'summary' => $this->sync_log_model->get_log_summary($days, $entity_type),
                'trends' => $this->sync_log_model->get_log_trends($days, $entity_type),
                'top_errors' => $this->sync_log_model->get_top_errors($days, 10),
                'performance_stats' => $this->sync_log_model->get_performance_statistics($days, $entity_type)
            ];

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

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

    /**
     * Export logs
     */
    public function export()
    {
        if (!has_permission('desk_moloni_view', '', 'view')) {
            access_denied('desk_moloni');
        }

        try {
            $format = $this->input->get('format') ?: 'csv';
            $filters = [
                'entity_type' => $this->input->get('entity_type'),
                'status' => $this->input->get('status'),
                'operation_type' => $this->input->get('operation_type'),
                'direction' => $this->input->get('direction'),
                'from_date' => $this->input->get('from_date'),
                'to_date' => $this->input->get('to_date'),
                'search' => $this->input->get('search')
            ];

            $logs = $this->sync_log_model->get_logs_for_export($filters);

            if ($format === 'json') {
                $this->_export_as_json($logs);
            } else {
                $this->_export_as_csv($logs);
            }

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

    /**
     * Clear old logs
     */
    public function clear_old_logs()
    {
        if (!has_permission('desk_moloni', '', 'delete')) {
            $this->output
                ->set_status_header(403)
                ->set_content_type('application/json')
                ->set_output(json_encode(['success' => false, 'message' => _l('access_denied')]));
            return;
        }

        try {
            $days_old = (int) $this->input->post('days_old') ?: 30;
            $keep_errors = $this->input->post('keep_errors') === '1';

            $deleted_count = $this->sync_log_model->clear_old_logs($days_old, $keep_errors);

            $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode([
                    'success' => true,
                    'message' => sprintf(
                        _l('desk_moloni_logs_cleared'),
                        $deleted_count
                    ),
                    'data' => ['deleted_count' => $deleted_count]
                ]));

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

    /**
     * Get error analysis
     */
    public function get_error_analysis()
    {
        if (!has_permission('desk_moloni_view', '', '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;
            
            $analysis = [
                'error_categories' => $this->sync_log_model->get_error_categories($days),
                'error_trends' => $this->sync_log_model->get_error_trends($days),
                'frequent_errors' => $this->sync_log_model->get_frequent_errors($days, 20),
                'error_by_entity' => $this->sync_log_model->get_errors_by_entity($days),
                'resolution_suggestions' => $this->_get_resolution_suggestions()
            ];

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

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

    /**
     * Search logs
     */
    public function search()
    {
        if (!has_permission('desk_moloni_view', '', 'view')) {
            $this->output
                ->set_status_header(403)
                ->set_content_type('application/json')
                ->set_output(json_encode(['success' => false, 'message' => _l('access_denied')]));
            return;
        }

        try {
            $query = $this->input->get('q');
            $limit = (int) $this->input->get('limit') ?: 50;

            if (empty($query) || strlen($query) < 3) {
                throw new Exception(_l('desk_moloni_search_query_too_short'));
            }

            $results = $this->sync_log_model->search_logs($query, $limit);

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

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

    /**
     * Export logs as CSV
     */
    private function _export_as_csv($logs)
    {
        $filename = 'desk_moloni_logs_' . date('Y-m-d_H-i-s') . '.csv';
        
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Cache-Control: no-cache, must-revalidate');
        header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
        
        $output = fopen('php://output', 'w');
        
        // CSV headers
        $headers = [
            'ID',
            'Timestamp',
            'Operation',
            'Entity Type',
            'Perfex ID',
            'Moloni ID',
            'Direction',
            'Status',
            'Execution Time (ms)',
            'Error Message'
        ];
        
        fputcsv($output, $headers);
        
        // CSV data
        foreach ($logs as $log) {
            $row = [
                $log['id'],
                $log['created_at'],
                $log['operation_type'],
                $log['entity_type'],
                $log['perfex_id'] ?: '',
                $log['moloni_id'] ?: '',
                $log['direction'],
                $log['status'],
                $log['execution_time_ms'] ?: '',
                $log['error_message'] ?: ''
            ];
            
            fputcsv($output, $row);
        }
        
        fclose($output);
        exit;
    }

    /**
     * Export logs as JSON
     */
    private function _export_as_json($logs)
    {
        $filename = 'desk_moloni_logs_' . date('Y-m-d_H-i-s') . '.json';
        
        header('Content-Type: application/json');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Cache-Control: no-cache, must-revalidate');
        header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
        
        echo json_encode([
            'export_date' => date('Y-m-d H:i:s'),
            'total_records' => count($logs),
            'logs' => $logs
        ], JSON_PRETTY_PRINT);
        
        exit;
    }

    /**
     * Get resolution suggestions for common errors
     */
    private function _get_resolution_suggestions()
    {
        return [
            'authentication_failed' => [
                'title' => _l('desk_moloni_auth_error_title'),
                'description' => _l('desk_moloni_auth_error_desc'),
                'actions' => [
                    _l('desk_moloni_refresh_oauth_token'),
                    _l('desk_moloni_check_api_credentials')
                ]
            ],
            'rate_limit_exceeded' => [
                'title' => _l('desk_moloni_rate_limit_title'),
                'description' => _l('desk_moloni_rate_limit_desc'),
                'actions' => [
                    _l('desk_moloni_reduce_sync_frequency'),
                    _l('desk_moloni_implement_backoff')
                ]
            ],
            'validation_error' => [
                'title' => _l('desk_moloni_validation_error_title'),
                'description' => _l('desk_moloni_validation_error_desc'),
                'actions' => [
                    _l('desk_moloni_check_required_fields'),
                    _l('desk_moloni_verify_data_format')
                ]
            ],
            'network_error' => [
                'title' => _l('desk_moloni_network_error_title'),
                'description' => _l('desk_moloni_network_error_desc'),
                'actions' => [
                    _l('desk_moloni_check_connectivity'),
                    _l('desk_moloni_verify_firewall')
                ]
            ]
        ];
    }
}