<?php

require_once __DIR__ . '/../config/database.php';
require_once __DIR__ . '/../utils/ForestCalculations.php';
require_once __DIR__ . '/../models/Rodal.php';
require_once __DIR__ . '/../models/Project.php';
require_once __DIR__ . '/../models/FieldData.php';
require_once __DIR__ . '/../utils/Cache.php';

class ReportController {
    private $db;
    
    public function __construct() {
        $this->db = Database::getConnection();
    }
    
    /**
     * Obtiene cálculos automáticos para un rodal específico
     * GET /api/rodales/{id}/calculations
     */
    public function getCalculationsByRodal($rodalId) {
        try {
            $cacheKey = 'calculations_rodal_' . $rodalId;
            
            // Try to get from cache first (10 minutes TTL)
            $response = Cache::get($cacheKey);
            $fromCache = true;
            
            if ($response === null) {
                // Verificar que el rodal existe
                $rodal = new Rodal($this->db);
                $rodalData = $rodal->getById($rodalId);
                
                if (!$rodalData) {
                    http_response_code(404);
                    echo json_encode(['error' => 'Rodal no encontrado']);
                    return;
                }
                
                // Obtener datos de campo del rodal con información de especies
                $fieldData = new FieldData($this->db);
                $registros = $fieldData->getByRodalIdWithSpecies($rodalId);
                
                if (empty($registros)) {
                    // Si no hay registros, devolver métricas en cero
                    $metricas = [
                        'conteo_arboles' => 0,
                        'dap_promedio' => 0,
                        'altura_promedio' => 0,
                        'area_basal' => 0,
                        'volumen' => 0,
                        'area_rodal' => $rodalData['area_ha'],
                        'especies' => []
                    ];
                } else {
                    // Calcular métricas forestales
                    $metricas = ForestCalculations::calcularMetricasCompletas($registros, $rodalData['area_ha']);
                }
                
                // Agregar información adicional
                $response = [
                    'rodal_id' => $rodalId,
                    'nombre_rodal' => $rodalData['nombre_rodal'],
                    'area_ha' => $rodalData['area_ha'],
                    'fecha_calculo' => date('Y-m-d H:i:s'),
                    'metricas' => $metricas,
                    'total_registros' => count($registros)
                ];
                
                // Cache with tags for easy invalidation (10 minutes TTL)
                Cache::tag(['calculations', 'rodal_' . $rodalId], $cacheKey, $response, 600);
                $fromCache = false;
            }
            
            // Add cache info to response
            $response['cached'] = $fromCache;
            
            http_response_code(200);
            echo json_encode($response);
            
        } catch (Exception $e) {
            http_response_code(500);
            echo json_encode(['error' => 'Error al calcular métricas: ' . $e->getMessage()]);
        }
    }
    
    /**
     * Exporta datos de un rodal a formato CSV
     * GET /api/rodales/{id}/export-csv
     */
    public function exportRodalToCSV($rodalId) {
        try {
            // Verificar que el rodal existe
            $rodal = new Rodal($this->db);
            $rodalData = $rodal->getById($rodalId);
            
            if (!$rodalData) {
                http_response_code(404);
                echo json_encode(['error' => 'Rodal no encontrado']);
                return;
            }
            
            // Obtener información del proyecto
            $project = new Project($this->db);
            $proyectoData = $project->getById($rodalData['proyecto_id']);
            
            if (!$proyectoData) {
                http_response_code(404);
                echo json_encode(['error' => 'Proyecto no encontrado']);
                return;
            }
            
            // Obtener datos de campo del rodal
            $fieldData = new FieldData($this->db);
            $registros = $fieldData->getByRodalId($rodalId);
            
            // Generar datos para CSV
            $datosCSV = ForestCalculations::generarDatosCSV($registros, $rodalData, $proyectoData);
            
            // Configurar headers para descarga de archivo CSV
            $filename = 'inventario_' . $rodalData['nombre_rodal'] . '_' . date('Y-m-d') . '.csv';
            
            header('Content-Type: text/csv; charset=utf-8');
            header('Content-Disposition: attachment; filename="' . $filename . '"');
            header('Cache-Control: no-cache, must-revalidate');
            header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
            
            // Crear el archivo CSV
            $output = fopen('php://output', 'w');
            
            // Agregar BOM para UTF-8
            fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF));
            
            // Escribir datos al CSV
            foreach ($datosCSV as $fila) {
                fputcsv($output, $fila, ',', '"');
            }
            
            fclose($output);
            
        } catch (Exception $e) {
            http_response_code(500);
            echo json_encode(['error' => 'Error al exportar CSV: ' . $e->getMessage()]);
        }
    }
    
    /**
     * Obtiene resumen completo de un proyecto con todos sus rodales
     * GET /api/projects/{id}/summary
     */
    public function getProjectSummary($projectId) {
        try {
            // Verificar que el proyecto existe
            $project = new Project($this->db);
            $proyectoData = $project->getById($projectId);
            
            if (!$proyectoData) {
                http_response_code(404);
                echo json_encode(['error' => 'Proyecto no encontrado']);
                return;
            }
            
            // Obtener todos los rodales del proyecto
            $rodal = new Rodal($this->db);
            $rodales = $rodal->getByProjectId($projectId);
            
            $resumenRodales = [];
            $totalesProyecto = [
                'total_arboles' => 0,
                'area_total' => 0,
                'area_basal_total' => 0,
                'volumen_total' => 0
            ];
            
            foreach ($rodales as $rodalData) {
                // Obtener datos de campo para cada rodal
                $fieldData = new FieldData($this->db);
                $registros = $fieldData->getByRodalId($rodalData['id']);
                
                if (!empty($registros)) {
                    $metricas = ForestCalculations::calcularMetricasCompletas($registros, $rodalData['area_ha']);
                    
                    // Acumular totales del proyecto
                    $totalesProyecto['total_arboles'] += $metricas['conteo_arboles'];
                    $totalesProyecto['area_total'] += $rodalData['area_ha'];
                    $totalesProyecto['area_basal_total'] += $metricas['area_basal'] * $rodalData['area_ha'];
                    $totalesProyecto['volumen_total'] += $metricas['volumen'] * $rodalData['area_ha'];
                } else {
                    $metricas = [
                        'conteo_arboles' => 0,
                        'dap_promedio' => 0,
                        'altura_promedio' => 0,
                        'area_basal' => 0,
                        'volumen' => 0,
                        'area_rodal' => $rodalData['area_ha']
                    ];
                    
                    $totalesProyecto['area_total'] += $rodalData['area_ha'];
                }
                
                $resumenRodales[] = [
                    'rodal_id' => $rodalData['id'],
                    'nombre_rodal' => $rodalData['nombre_rodal'],
                    'area_ha' => $rodalData['area_ha'],
                    'total_registros' => count($registros),
                    'metricas' => $metricas
                ];
            }
            
            // Calcular promedios del proyecto
            if ($totalesProyecto['area_total'] > 0) {
                $totalesProyecto['area_basal_promedio'] = round($totalesProyecto['area_basal_total'] / $totalesProyecto['area_total'], 2);
                $totalesProyecto['volumen_promedio'] = round($totalesProyecto['volumen_total'] / $totalesProyecto['area_total'], 2);
            } else {
                $totalesProyecto['area_basal_promedio'] = 0;
                $totalesProyecto['volumen_promedio'] = 0;
            }
            
            $response = [
                'proyecto' => $proyectoData,
                'fecha_reporte' => date('Y-m-d H:i:s'),
                'totales_proyecto' => $totalesProyecto,
                'rodales' => $resumenRodales,
                'total_rodales' => count($rodales)
            ];
            
            http_response_code(200);
            echo json_encode($response);
            
        } catch (Exception $e) {
            http_response_code(500);
            echo json_encode(['error' => 'Error al generar resumen: ' . $e->getMessage()]);
        }
    }
    
    /**
     * Actualiza cálculos automáticamente después de sincronización
     * POST /api/calculations/refresh/{rodalId}
     */
    public function refreshCalculations($rodalId) {
        try {
            // Simplemente devolver los cálculos actualizados
            $this->getCalculationsByRodal($rodalId);
            
        } catch (Exception $e) {
            http_response_code(500);
            echo json_encode(['error' => 'Error al actualizar cálculos: ' . $e->getMessage()]);
        }
    }
}