<?php
require_once __DIR__ . '/../models/Project.php';
require_once __DIR__ . '/../middleware/AuthMiddleware.php';
require_once __DIR__ . '/../middleware/RoleMiddleware.php';
require_once __DIR__ . '/../utils/SecureFileManager.php';
require_once __DIR__ . '/../utils/SecurityLogger.php';
require_once __DIR__ . '/../utils/Cache.php';

class ProjectController {
    private $db;
    private $project;
    private $fileManager;
    
    public function __construct($database) {
        $this->db = $database;
        $this->project = new Project($this->db);
        $this->fileManager = new SecureFileManager();
    }

    // GET /api/projects - Obtener todos los proyectos
    public function index() {
        try {
            // Verificar autenticación
            $user = AuthMiddleware::authenticate();
            
            // Los técnicos de campo no pueden ver proyectos
            RoleMiddleware::checkRole(['Administrador', 'Regente']);
            
            $filters = [];
            
            // Si es regente, solo puede ver sus propios proyectos
            if ($user['rol'] === 'Regente') {
                $filters['usuario_id'] = $user['user_id'];
            }
            
            // Aplicar filtros de query parameters
            if (isset($_GET['departamento'])) {
                $filters['departamento'] = $_GET['departamento'];
            }
            if (isset($_GET['municipio'])) {
                $filters['municipio'] = $_GET['municipio'];
            }
            if (isset($_GET['nombre_proyecto'])) {
                $filters['nombre_proyecto'] = $_GET['nombre_proyecto'];
            }
            
            // Create cache key based on user and filters
            $cacheKey = 'projects_list_' . $user['user_id'] . '_' . md5(serialize($filters));
            
            // Try to get from cache first (5 minutes TTL)
            $projects = Cache::get($cacheKey);
            
            if ($projects === null) {
                $stmt = $this->project->searchProjects($filters);
                $projects = [];
            
                while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                    $projects[] = [
                        'id' => (int)$row['id'],
                        'fecha_creacion' => $row['fecha_creacion'],
                        'nombre_proyecto' => $row['nombre_proyecto'],
                        'nombre_finca' => $row['nombre_finca'],
                        'departamento' => $row['departamento'],
                        'municipio' => $row['municipio'],
                        'aldea' => $row['aldea'],
                        'nombre_propietario' => $row['nombre_propietario'],
                        'nombre_regente_forestal' => $row['nombre_regente_forestal'],
                        'doc_tenencia_path' => $row['doc_tenencia_path'],
                        'doc_regencia_path' => $row['doc_regencia_path'],
                        'usuario_id' => (int)$row['usuario_id'],
                        'usuario_nombre' => $row['usuario_nombre']
                    ];
                }
                
                // Cache the results with tags for easy invalidation (5 minutes TTL)
                Cache::tag(['projects', 'user_' . $user['user_id']], $cacheKey, $projects, 300);
            }
            
            http_response_code(200);
            return json_encode([
                'success' => true,
                'data' => $projects,
                'total' => count($projects)
            ]);
            
        } catch (Exception $e) {
            http_response_code(500);
            return json_encode([
                'success' => false,
                'message' => 'Error al obtener proyectos: ' . $e->getMessage()
            ]);
        }
    }

    // GET /api/projects/{id} - Obtener proyecto específico
    public function show($id) {
        try {
            // Verificar autenticación
            $user = AuthMiddleware::authenticate();
            RoleMiddleware::checkRole(['Administrador', 'Regente']);
            
            if (!$this->project->findById($id)) {
                http_response_code(404);
                return json_encode([
                    'success' => false,
                    'message' => 'Proyecto no encontrado'
                ]);
            }
            
            // Verificar permisos: regentes solo pueden ver sus propios proyectos
            if ($user['rol'] === 'Regente' && $this->project->usuario_id != $user['user_id']) {
                http_response_code(403);
                return json_encode([
                    'success' => false,
                    'message' => 'No tiene permisos para ver este proyecto'
                ]);
            }
            
            // Obtener resumen del proyecto con estadísticas
            $summary = $this->project->getProjectSummary($id);
            
            http_response_code(200);
            return json_encode([
                'success' => true,
                'data' => [
                    'id' => (int)$summary['id'],
                    'fecha_creacion' => $summary['fecha_creacion'],
                    'nombre_proyecto' => $summary['nombre_proyecto'],
                    'nombre_finca' => $summary['nombre_finca'],
                    'departamento' => $summary['departamento'],
                    'municipio' => $summary['municipio'],
                    'aldea' => $summary['aldea'],
                    'nombre_propietario' => $summary['nombre_propietario'],
                    'nombre_regente_forestal' => $summary['nombre_regente_forestal'],
                    'doc_tenencia_path' => $summary['doc_tenencia_path'],
                    'doc_regencia_path' => $summary['doc_regencia_path'],
                    'usuario_id' => (int)$summary['usuario_id'],
                    'usuario_nombre' => $summary['usuario_nombre'],
                    'estadisticas' => [
                        'total_rodales' => (int)$summary['total_rodales'],
                        'area_total_ha' => (float)$summary['area_total_ha'],
                        'total_registros_campo' => (int)$summary['total_registros_campo'],
                        'registros_sincronizados' => (int)$summary['registros_sincronizados'],
                        'registros_pendientes' => (int)$summary['registros_pendientes']
                    ]
                ]
            ]);
            
        } catch (Exception $e) {
            http_response_code(500);
            return json_encode([
                'success' => false,
                'message' => 'Error al obtener proyecto: ' . $e->getMessage()
            ]);
        }
    }

    // POST /api/projects - Crear nuevo proyecto
    public function store() {
        try {
            // Verificar autenticación
            $user = AuthMiddleware::authenticate();
            RoleMiddleware::checkRole(['Administrador', 'Regente']);
            
            // Obtener datos del request
            $input = json_decode(file_get_contents('php://input'), true);
            
            if (!$input) {
                http_response_code(400);
                return json_encode([
                    'success' => false,
                    'message' => 'Datos de entrada inválidos'
                ]);
            }
            
            // Asignar datos al modelo
            $this->project->nombre_proyecto = $input['nombre_proyecto'] ?? '';
            $this->project->nombre_finca = $input['nombre_finca'] ?? '';
            $this->project->departamento = $input['departamento'] ?? '';
            $this->project->municipio = $input['municipio'] ?? '';
            $this->project->aldea = $input['aldea'] ?? '';
            $this->project->nombre_propietario = $input['nombre_propietario'] ?? '';
            $this->project->nombre_regente_forestal = $input['nombre_regente_forestal'] ?? '';
            $this->project->doc_tenencia_path = $input['doc_tenencia_path'] ?? null;
            $this->project->doc_regencia_path = $input['doc_regencia_path'] ?? null;
            $this->project->usuario_id = $user['user_id'];
            
            // Validar datos
            $errors = $this->project->validate();
            if (!empty($errors)) {
                http_response_code(400);
                return json_encode([
                    'success' => false,
                    'message' => 'Errores de validación',
                    'errors' => $errors
                ]);
            }
            
            // Verificar que el nombre del proyecto no exista
            if ($this->project->projectNameExists($this->project->nombre_proyecto)) {
                http_response_code(409);
                return json_encode([
                    'success' => false,
                    'message' => 'Ya existe un proyecto con este nombre'
                ]);
            }
            
            // Crear proyecto
            if ($this->project->create()) {
                // Invalidate project caches
                Cache::invalidateTag('projects');
                Cache::invalidateTag('user_' . $user['user_id']);
                
                http_response_code(201);
                return json_encode([
                    'success' => true,
                    'message' => 'Proyecto creado exitosamente',
                    'data' => [
                        'id' => (int)$this->project->id,
                        'nombre_proyecto' => $this->project->nombre_proyecto
                    ]
                ]);
            } else {
                http_response_code(500);
                return json_encode([
                    'success' => false,
                    'message' => 'Error al crear el proyecto'
                ]);
            }
            
        } catch (Exception $e) {
            http_response_code(500);
            return json_encode([
                'success' => false,
                'message' => 'Error al crear proyecto: ' . $e->getMessage()
            ]);
        }
    }

    // PUT /api/projects/{id} - Actualizar proyecto
    public function update($id) {
        try {
            // Verificar autenticación
            $user = AuthMiddleware::authenticate();
            RoleMiddleware::checkRole(['Administrador', 'Regente']);
            
            // Buscar proyecto
            if (!$this->project->findById($id)) {
                http_response_code(404);
                return json_encode([
                    'success' => false,
                    'message' => 'Proyecto no encontrado'
                ]);
            }
            
            // Verificar permisos: regentes solo pueden editar sus propios proyectos
            if ($user['rol'] === 'Regente' && $this->project->usuario_id != $user['user_id']) {
                http_response_code(403);
                return json_encode([
                    'success' => false,
                    'message' => 'No tiene permisos para editar este proyecto'
                ]);
            }
            
            // Obtener datos del request
            $input = json_decode(file_get_contents('php://input'), true);
            
            if (!$input) {
                http_response_code(400);
                return json_encode([
                    'success' => false,
                    'message' => 'Datos de entrada inválidos'
                ]);
            }
            
            // Actualizar solo los campos proporcionados
            if (isset($input['nombre_proyecto'])) {
                $this->project->nombre_proyecto = $input['nombre_proyecto'];
            }
            if (isset($input['nombre_finca'])) {
                $this->project->nombre_finca = $input['nombre_finca'];
            }
            if (isset($input['departamento'])) {
                $this->project->departamento = $input['departamento'];
            }
            if (isset($input['municipio'])) {
                $this->project->municipio = $input['municipio'];
            }
            if (isset($input['aldea'])) {
                $this->project->aldea = $input['aldea'];
            }
            if (isset($input['nombre_propietario'])) {
                $this->project->nombre_propietario = $input['nombre_propietario'];
            }
            if (isset($input['nombre_regente_forestal'])) {
                $this->project->nombre_regente_forestal = $input['nombre_regente_forestal'];
            }
            
            // Validar datos
            $errors = $this->project->validate();
            if (!empty($errors)) {
                http_response_code(400);
                return json_encode([
                    'success' => false,
                    'message' => 'Errores de validación',
                    'errors' => $errors
                ]);
            }
            
            // Verificar que el nombre del proyecto no exista (excluyendo el actual)
            if (isset($input['nombre_proyecto']) && 
                $this->project->projectNameExists($this->project->nombre_proyecto, $id)) {
                http_response_code(409);
                return json_encode([
                    'success' => false,
                    'message' => 'Ya existe un proyecto con este nombre'
                ]);
            }
            
            // Actualizar proyecto
            if ($this->project->update()) {
                // Invalidate project caches
                Cache::invalidateTag('projects');
                Cache::invalidateTag('user_' . $user['user_id']);
                Cache::delete('project_' . $id);
                
                http_response_code(200);
                return json_encode([
                    'success' => true,
                    'message' => 'Proyecto actualizado exitosamente'
                ]);
            } else {
                http_response_code(500);
                return json_encode([
                    'success' => false,
                    'message' => 'Error al actualizar el proyecto'
                ]);
            }
            
        } catch (Exception $e) {
            http_response_code(500);
            return json_encode([
                'success' => false,
                'message' => 'Error al actualizar proyecto: ' . $e->getMessage()
            ]);
        }
    }

    // DELETE /api/projects/{id} - Eliminar proyecto
    public function destroy($id) {
        try {
            // Verificar autenticación
            $user = AuthMiddleware::authenticate();
            RoleMiddleware::checkRole(['Administrador', 'Regente']);
            
            // Buscar proyecto
            if (!$this->project->findById($id)) {
                http_response_code(404);
                return json_encode([
                    'success' => false,
                    'message' => 'Proyecto no encontrado'
                ]);
            }
            
            // Verificar permisos: regentes solo pueden eliminar sus propios proyectos
            if ($user['rol'] === 'Regente' && $this->project->usuario_id != $user['user_id']) {
                http_response_code(403);
                return json_encode([
                    'success' => false,
                    'message' => 'No tiene permisos para eliminar este proyecto'
                ]);
            }
            
            // Guardar rutas de documentos para eliminar archivos
            $docTenencia = $this->project->doc_tenencia_path;
            $docRegencia = $this->project->doc_regencia_path;
            
            // Eliminar proyecto
            $result = $this->project->delete();
            
            if ($result === true) {
                // Invalidate project caches
                Cache::invalidateTag('projects');
                Cache::invalidateTag('user_' . $user['user_id']);
                Cache::delete('project_' . $id);
                
                // Eliminar archivos de documentos si existen usando SecureFileManager
                if ($docTenencia) {
                    try {
                        $this->fileManager->deleteFile(basename($docTenencia), $user['user_id'], $user['rol']);
                    } catch (Exception $e) {
                        SecurityLogger::logSystemError('Error eliminando documento de tenencia: ' . $e->getMessage());
                    }
                }
                if ($docRegencia) {
                    try {
                        $this->fileManager->deleteFile(basename($docRegencia), $user['user_id'], $user['rol']);
                    } catch (Exception $e) {
                        SecurityLogger::logSystemError('Error eliminando documento de regencia: ' . $e->getMessage());
                    }
                }
                
                http_response_code(200);
                return json_encode([
                    'success' => true,
                    'message' => 'Proyecto eliminado exitosamente'
                ]);
            } elseif (is_array($result) && isset($result['error'])) {
                http_response_code(409);
                return json_encode([
                    'success' => false,
                    'message' => $result['error']
                ]);
            } else {
                http_response_code(500);
                return json_encode([
                    'success' => false,
                    'message' => 'Error al eliminar el proyecto'
                ]);
            }
            
        } catch (Exception $e) {
            http_response_code(500);
            return json_encode([
                'success' => false,
                'message' => 'Error al eliminar proyecto: ' . $e->getMessage()
            ]);
        }
    }

    // POST /api/projects/{id}/documents - Subir documentos PDF
    public function uploadDocument($id) {
        try {
            // Verificar autenticación
            $user = AuthMiddleware::authenticate();
            RoleMiddleware::checkRole(['Administrador', 'Regente']);
            
            // Buscar proyecto
            if (!$this->project->findById($id)) {
                http_response_code(404);
                return json_encode([
                    'success' => false,
                    'message' => 'Proyecto no encontrado'
                ]);
            }
            
            // Verificar permisos: regentes solo pueden subir documentos a sus propios proyectos
            if ($user['rol'] === 'Regente' && $this->project->usuario_id != $user['user_id']) {
                http_response_code(403);
                return json_encode([
                    'success' => false,
                    'message' => 'No tiene permisos para subir documentos a este proyecto'
                ]);
            }
            
            // Verificar que se haya enviado un archivo
            if (!isset($_FILES['document'])) {
                http_response_code(400);
                return json_encode([
                    'success' => false,
                    'message' => 'No se ha enviado ningún archivo'
                ]);
            }
            
            // Verificar tipo de documento
            $documentType = $_POST['document_type'] ?? '';
            if (!in_array($documentType, ['tenencia', 'regencia'])) {
                http_response_code(400);
                return json_encode([
                    'success' => false,
                    'message' => 'Tipo de documento inválido. Debe ser "tenencia" o "regencia"'
                ]);
            }
            
            // Eliminar archivo anterior si existe
            $currentPath = ($documentType === 'tenencia') ? 
                $this->project->doc_tenencia_path : 
                $this->project->doc_regencia_path;
                
            if ($currentPath) {
                try {
                    $this->fileManager->deleteFile(basename($currentPath), $user['user_id'], $user['rol']);
                } catch (Exception $e) {
                    // Log pero no fallar si no se puede eliminar archivo anterior
                    SecurityLogger::logSystemError('Error eliminando archivo anterior: ' . $e->getMessage());
                }
            }
            
            // Usar SecureFileManager para subir archivo
            $uploadResult = $this->fileManager->uploadFile(
                $_FILES['document'], 
                $id, 
                $documentType, 
                $user['user_id'], 
                $user['rol']
            );
            
            // Actualizar ruta en base de datos
            if ($this->project->updateDocumentPath($documentType, $uploadResult['relative_path'])) {
                http_response_code(200);
                return json_encode([
                    'success' => true,
                    'message' => 'Documento subido exitosamente',
                    'data' => [
                        'document_type' => $documentType,
                        'file_path' => $uploadResult['relative_path'],
                        'original_name' => $uploadResult['original_name'],
                        'file_size' => $uploadResult['size']
                    ]
                ]);
            } else {
                // Si falla la actualización en BD, eliminar archivo
                try {
                    $this->fileManager->deleteFile($uploadResult['file_name'], $user['user_id'], $user['rol']);
                } catch (Exception $e) {
                    SecurityLogger::logSystemError('Error eliminando archivo tras fallo en BD: ' . $e->getMessage());
                }
                
                http_response_code(500);
                return json_encode([
                    'success' => false,
                    'message' => 'Error al actualizar la ruta del documento en la base de datos'
                ]);
            }
            
        } catch (Exception $e) {
            http_response_code(500);
            return json_encode([
                'success' => false,
                'message' => 'Error al subir documento: ' . $e->getMessage()
            ]);
        }
    }

    // GET /api/projects/{id}/documents/{type} - Descargar documento
    public function downloadDocument($id, $type) {
        try {
            // Verificar autenticación
            $user = AuthMiddleware::authenticate();
            RoleMiddleware::checkRole(['Administrador', 'Regente']);
            
            // Buscar proyecto
            if (!$this->project->findById($id)) {
                http_response_code(404);
                return json_encode([
                    'success' => false,
                    'message' => 'Proyecto no encontrado'
                ]);
            }
            
            // Verificar permisos: regentes solo pueden descargar documentos de sus propios proyectos
            if ($user['rol'] === 'Regente' && $this->project->usuario_id != $user['user_id']) {
                http_response_code(403);
                return json_encode([
                    'success' => false,
                    'message' => 'No tiene permisos para descargar documentos de este proyecto'
                ]);
            }
            
            // Verificar tipo de documento
            if (!in_array($type, ['tenencia', 'regencia'])) {
                http_response_code(400);
                return json_encode([
                    'success' => false,
                    'message' => 'Tipo de documento inválido'
                ]);
            }
            
            // Obtener ruta del documento
            $documentPath = ($type === 'tenencia') ? 
                $this->project->doc_tenencia_path : 
                $this->project->doc_regencia_path;
            
            if (!$documentPath) {
                http_response_code(404);
                return json_encode([
                    'success' => false,
                    'message' => 'Documento no encontrado'
                ]);
            }
            
            // Usar SecureFileManager para servir archivo de forma segura
            $fileName = basename($documentPath);
            $this->fileManager->serveFile($fileName, $user['user_id'], $user['rol'], $id);
            
            // serveFile hace exit, este código no se ejecutará
            
        } catch (Exception $e) {
            http_response_code(500);
            return json_encode([
                'success' => false,
                'message' => 'Error al descargar documento: ' . $e->getMessage()
            ]);
        }
    }



    // GET /api/projects/departments - Obtener lista de departamentos de Guatemala
    public function getDepartments() {
        try {
            $departamentos = [
                'Alta Verapaz', 'Baja Verapaz', 'Chimaltenango', 'Chiquimula', 
                'El Progreso', 'Escuintla', 'Guatemala', 'Huehuetenango', 
                'Izabal', 'Jalapa', 'Jutiapa', 'Petén', 'Quetzaltenango', 
                'Quiché', 'Retalhuleu', 'Sacatepéquez', 'San Marcos', 
                'Santa Rosa', 'Sololá', 'Suchitepéquez', 'Totonicapán', 'Zacapa'
            ];
            
            http_response_code(200);
            return json_encode([
                'success' => true,
                'data' => $departamentos
            ]);
            
        } catch (Exception $e) {
            http_response_code(500);
            return json_encode([
                'success' => false,
                'message' => 'Error al obtener departamentos: ' . $e->getMessage()
            ]);
        }
    }
}
?>