<?php
class Project {
    private $conn;
    private $table_name = "proyectos";

    public $id;
    public $fecha_creacion;
    public $nombre_proyecto;
    public $nombre_finca;
    public $departamento;
    public $municipio;
    public $aldea;
    public $nombre_propietario;
    public $nombre_regente_forestal;
    public $doc_tenencia_path;
    public $doc_regencia_path;
    public $usuario_id;

    public function __construct($db) {
        $this->conn = $db;
    }

    // Crear nuevo proyecto
    public function create() {
        $query = "INSERT INTO " . $this->table_name . " 
                  (nombre_proyecto, nombre_finca, departamento, municipio, aldea, 
                   nombre_propietario, nombre_regente_forestal, doc_tenencia_path, 
                   doc_regencia_path, usuario_id) 
                  VALUES (:nombre_proyecto, :nombre_finca, :departamento, :municipio, :aldea, 
                          :nombre_propietario, :nombre_regente_forestal, :doc_tenencia_path, 
                          :doc_regencia_path, :usuario_id)";

        $stmt = $this->conn->prepare($query);

        // Sanitizar datos
        $this->nombre_proyecto = htmlspecialchars(strip_tags($this->nombre_proyecto));
        $this->nombre_finca = htmlspecialchars(strip_tags($this->nombre_finca));
        $this->departamento = htmlspecialchars(strip_tags($this->departamento));
        $this->municipio = htmlspecialchars(strip_tags($this->municipio));
        $this->aldea = htmlspecialchars(strip_tags($this->aldea));
        $this->nombre_propietario = htmlspecialchars(strip_tags($this->nombre_propietario));
        $this->nombre_regente_forestal = htmlspecialchars(strip_tags($this->nombre_regente_forestal));

        // Bind de parámetros
        $stmt->bindParam(":nombre_proyecto", $this->nombre_proyecto);
        $stmt->bindParam(":nombre_finca", $this->nombre_finca);
        $stmt->bindParam(":departamento", $this->departamento);
        $stmt->bindParam(":municipio", $this->municipio);
        $stmt->bindParam(":aldea", $this->aldea);
        $stmt->bindParam(":nombre_propietario", $this->nombre_propietario);
        $stmt->bindParam(":nombre_regente_forestal", $this->nombre_regente_forestal);
        $stmt->bindParam(":doc_tenencia_path", $this->doc_tenencia_path);
        $stmt->bindParam(":doc_regencia_path", $this->doc_regencia_path);
        $stmt->bindParam(":usuario_id", $this->usuario_id);

        if ($stmt->execute()) {
            $this->id = $this->conn->lastInsertId();
            return true;
        }

        return false;
    }

    // Obtener todos los proyectos
    public function read() {
        $query = "SELECT p.*, u.nombre as usuario_nombre 
                  FROM " . $this->table_name . " p
                  LEFT JOIN usuarios u ON p.usuario_id = u.id
                  ORDER BY p.fecha_creacion DESC";

        $stmt = $this->conn->prepare($query);
        $stmt->execute();

        return $stmt;
    }

    // Obtener proyectos por usuario
    public function readByUser($userId) {
        $query = "SELECT p.*, u.nombre as usuario_nombre 
                  FROM " . $this->table_name . " p
                  LEFT JOIN usuarios u ON p.usuario_id = u.id
                  WHERE p.usuario_id = :usuario_id
                  ORDER BY p.fecha_creacion DESC";

        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(":usuario_id", $userId);
        $stmt->execute();

        return $stmt;
    }

    // Buscar proyecto por ID
    public function findById($id) {
        $query = "SELECT p.*, u.nombre as usuario_nombre 
                  FROM " . $this->table_name . " p
                  LEFT JOIN usuarios u ON p.usuario_id = u.id
                  WHERE p.id = :id 
                  LIMIT 1";

        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(":id", $id);
        $stmt->execute();

        if ($stmt->rowCount() > 0) {
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            
            $this->id = $row['id'];
            $this->fecha_creacion = $row['fecha_creacion'];
            $this->nombre_proyecto = $row['nombre_proyecto'];
            $this->nombre_finca = $row['nombre_finca'];
            $this->departamento = $row['departamento'];
            $this->municipio = $row['municipio'];
            $this->aldea = $row['aldea'];
            $this->nombre_propietario = $row['nombre_propietario'];
            $this->nombre_regente_forestal = $row['nombre_regente_forestal'];
            $this->doc_tenencia_path = $row['doc_tenencia_path'];
            $this->doc_regencia_path = $row['doc_regencia_path'];
            $this->usuario_id = $row['usuario_id'];
            
            return true;
        }

        return false;
    }

    // Obtener proyecto por ID como array
    public function getById($id) {
        $query = "SELECT p.*, u.nombre as usuario_nombre 
                  FROM " . $this->table_name . " p
                  LEFT JOIN usuarios u ON p.usuario_id = u.id
                  WHERE p.id = :id 
                  LIMIT 1";

        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(":id", $id);
        $stmt->execute();

        if ($stmt->rowCount() > 0) {
            return $stmt->fetch(PDO::FETCH_ASSOC);
        }

        return null;
    }

    // Actualizar proyecto
    public function update() {
        $query = "UPDATE " . $this->table_name . " 
                  SET nombre_proyecto = :nombre_proyecto, nombre_finca = :nombre_finca, 
                      departamento = :departamento, municipio = :municipio, aldea = :aldea,
                      nombre_propietario = :nombre_propietario, 
                      nombre_regente_forestal = :nombre_regente_forestal,
                      doc_tenencia_path = :doc_tenencia_path, doc_regencia_path = :doc_regencia_path
                  WHERE id = :id";

        $stmt = $this->conn->prepare($query);

        // Sanitizar datos
        $this->nombre_proyecto = htmlspecialchars(strip_tags($this->nombre_proyecto));
        $this->nombre_finca = htmlspecialchars(strip_tags($this->nombre_finca));
        $this->departamento = htmlspecialchars(strip_tags($this->departamento));
        $this->municipio = htmlspecialchars(strip_tags($this->municipio));
        $this->aldea = htmlspecialchars(strip_tags($this->aldea));
        $this->nombre_propietario = htmlspecialchars(strip_tags($this->nombre_propietario));
        $this->nombre_regente_forestal = htmlspecialchars(strip_tags($this->nombre_regente_forestal));

        // Bind de parámetros
        $stmt->bindParam(":nombre_proyecto", $this->nombre_proyecto);
        $stmt->bindParam(":nombre_finca", $this->nombre_finca);
        $stmt->bindParam(":departamento", $this->departamento);
        $stmt->bindParam(":municipio", $this->municipio);
        $stmt->bindParam(":aldea", $this->aldea);
        $stmt->bindParam(":nombre_propietario", $this->nombre_propietario);
        $stmt->bindParam(":nombre_regente_forestal", $this->nombre_regente_forestal);
        $stmt->bindParam(":doc_tenencia_path", $this->doc_tenencia_path);
        $stmt->bindParam(":doc_regencia_path", $this->doc_regencia_path);
        $stmt->bindParam(":id", $this->id);

        return $stmt->execute();
    }

    // Eliminar proyecto
    public function delete() {
        // Verificar si tiene rodales asociados
        $checkQuery = "SELECT COUNT(*) as count FROM rodales WHERE proyecto_id = :id";
        $checkStmt = $this->conn->prepare($checkQuery);
        $checkStmt->bindParam(":id", $this->id);
        $checkStmt->execute();
        $result = $checkStmt->fetch(PDO::FETCH_ASSOC);

        if ($result['count'] > 0) {
            return ['error' => 'No se puede eliminar el proyecto porque tiene rodales asociados'];
        }

        $query = "DELETE FROM " . $this->table_name . " WHERE id = :id";
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(":id", $this->id);

        return $stmt->execute();
    }

    // Validar datos según estándares INAB
    public function validate() {
        $errors = [];

        // Validar nombre del proyecto
        if (empty($this->nombre_proyecto)) {
            $errors[] = "El nombre del proyecto es requerido";
        } elseif (strlen($this->nombre_proyecto) < 3) {
            $errors[] = "El nombre del proyecto debe tener al menos 3 caracteres";
        } elseif (strlen($this->nombre_proyecto) > 200) {
            $errors[] = "El nombre del proyecto no puede exceder 200 caracteres";
        }

        // Validar nombre de la finca
        if (empty($this->nombre_finca)) {
            $errors[] = "El nombre de la finca es requerido";
        } elseif (strlen($this->nombre_finca) > 200) {
            $errors[] = "El nombre de la finca no puede exceder 200 caracteres";
        }

        // Validar departamento (según divisiones de Guatemala)
        $departamentosGuatemala = [
            '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'
        ];

        if (empty($this->departamento)) {
            $errors[] = "El departamento es requerido";
        } elseif (!in_array($this->departamento, $departamentosGuatemala)) {
            $errors[] = "El departamento debe ser uno de los 22 departamentos de Guatemala";
        }

        // Validar municipio
        if (empty($this->municipio)) {
            $errors[] = "El municipio es requerido";
        } elseif (strlen($this->municipio) > 100) {
            $errors[] = "El municipio no puede exceder 100 caracteres";
        }

        // Validar aldea
        if (empty($this->aldea)) {
            $errors[] = "La aldea es requerida";
        } elseif (strlen($this->aldea) > 100) {
            $errors[] = "La aldea no puede exceder 100 caracteres";
        }

        // Validar nombre del propietario
        if (empty($this->nombre_propietario)) {
            $errors[] = "El nombre del propietario es requerido";
        } elseif (strlen($this->nombre_propietario) < 2) {
            $errors[] = "El nombre del propietario debe tener al menos 2 caracteres";
        } elseif (strlen($this->nombre_propietario) > 200) {
            $errors[] = "El nombre del propietario no puede exceder 200 caracteres";
        }

        // Validar nombre del regente forestal
        if (empty($this->nombre_regente_forestal)) {
            $errors[] = "El nombre del regente forestal es requerido";
        } elseif (strlen($this->nombre_regente_forestal) < 2) {
            $errors[] = "El nombre del regente forestal debe tener al menos 2 caracteres";
        } elseif (strlen($this->nombre_regente_forestal) > 200) {
            $errors[] = "El nombre del regente forestal no puede exceder 200 caracteres";
        }

        // Validar usuario_id
        if (empty($this->usuario_id)) {
            $errors[] = "El ID del usuario es requerido";
        }

        return $errors;
    }

    // Verificar si el nombre del proyecto ya existe
    public function projectNameExists($nombre, $excludeId = null) {
        $query = "SELECT id FROM " . $this->table_name . " WHERE nombre_proyecto = :nombre";
        
        if ($excludeId) {
            $query .= " AND id != :exclude_id";
        }

        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(":nombre", $nombre);
        
        if ($excludeId) {
            $stmt->bindParam(":exclude_id", $excludeId);
        }
        
        $stmt->execute();

        return $stmt->rowCount() > 0;
    }

    // Obtener resumen del proyecto con estadísticas
    public function getProjectSummary($projectId) {
        $query = "SELECT 
                    p.*,
                    u.nombre as usuario_nombre,
                    COUNT(DISTINCT r.id) as total_rodales,
                    COALESCE(SUM(r.area_ha), 0) as area_total_ha,
                    COUNT(DISTINCT dc.id) as total_registros_campo,
                    COUNT(DISTINCT CASE WHEN dc.estado_sincronizacion = 'Sincronizado' THEN dc.id END) as registros_sincronizados,
                    COUNT(DISTINCT CASE WHEN dc.estado_sincronizacion = 'Pendiente' THEN dc.id END) as registros_pendientes
                  FROM " . $this->table_name . " p
                  LEFT JOIN usuarios u ON p.usuario_id = u.id
                  LEFT JOIN rodales r ON p.id = r.proyecto_id
                  LEFT JOIN datos_campo dc ON r.id = dc.rodal_id
                  WHERE p.id = :project_id
                  GROUP BY p.id";

        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(":project_id", $projectId);
        $stmt->execute();

        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    // Actualizar ruta de documento
    public function updateDocumentPath($documentType, $filePath) {
        if (!in_array($documentType, ['tenencia', 'regencia'])) {
            return false;
        }

        $field = ($documentType === 'tenencia') ? 'doc_tenencia_path' : 'doc_regencia_path';
        
        $query = "UPDATE " . $this->table_name . " 
                  SET " . $field . " = :file_path 
                  WHERE id = :id";

        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(":file_path", $filePath);
        $stmt->bindParam(":id", $this->id);

        return $stmt->execute();
    }

    // Buscar proyectos por filtros
    public function searchProjects($filters = []) {
        $query = "SELECT p.*, u.nombre as usuario_nombre 
                  FROM " . $this->table_name . " p
                  LEFT JOIN usuarios u ON p.usuario_id = u.id
                  WHERE 1=1";
        
        $params = [];

        if (!empty($filters['departamento'])) {
            $query .= " AND p.departamento = :departamento";
            $params[':departamento'] = $filters['departamento'];
        }

        if (!empty($filters['municipio'])) {
            $query .= " AND p.municipio LIKE :municipio";
            $params[':municipio'] = '%' . $filters['municipio'] . '%';
        }

        if (!empty($filters['nombre_proyecto'])) {
            $query .= " AND p.nombre_proyecto LIKE :nombre_proyecto";
            $params[':nombre_proyecto'] = '%' . $filters['nombre_proyecto'] . '%';
        }

        if (!empty($filters['usuario_id'])) {
            $query .= " AND p.usuario_id = :usuario_id";
            $params[':usuario_id'] = $filters['usuario_id'];
        }

        $query .= " ORDER BY p.fecha_creacion DESC";

        $stmt = $this->conn->prepare($query);
        
        foreach ($params as $key => $value) {
            $stmt->bindValue($key, $value);
        }
        
        $stmt->execute();

        return $stmt;
    }

    // Métodos estáticos para testing
    public static function validateProjectData($data) {
        $errors = [];
        
        $requiredFields = [
            'nombre_proyecto' => 'El nombre del proyecto es requerido',
            'nombre_finca' => 'El nombre de la finca es requerido',
            'departamento' => 'El departamento es requerido',
            'municipio' => 'El municipio es requerido',
            'aldea' => 'La aldea es requerida',
            'nombre_propietario' => 'El nombre del propietario es requerido',
            'nombre_regente_forestal' => 'El nombre del regente forestal es requerido'
        ];
        
        foreach ($requiredFields as $field => $message) {
            if (empty($data[$field])) {
                $errors[] = $message;
            }
        }
        
        // Validar departamento
        if (!empty($data['departamento']) && !in_array($data['departamento'], self::getValidDepartments())) {
            $errors[] = 'Departamento inválido';
        }
        
        return [
            'valid' => empty($errors),
            'errors' => $errors
        ];
    }
    
    public static function sanitizeProjectData($data) {
        $sanitized = [];
        
        $fields = [
            'nombre_proyecto', 'nombre_finca', 'departamento', 'municipio', 
            'aldea', 'nombre_propietario', 'nombre_regente_forestal'
        ];
        
        foreach ($fields as $field) {
            if (isset($data[$field])) {
                $sanitized[$field] = ucwords(strtolower(trim($data[$field])));
            }
        }
        
        return $sanitized;
    }
    
    public static function getValidDepartments() {
        return [
            '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'
        ];
    }
    
    public static function validateDocumentUpload($file) {
        $errors = [];
        
        if ($file['error'] !== UPLOAD_ERR_OK) {
            $errors[] = 'Error en la carga del archivo';
        }
        
        if ($file['type'] !== 'application/pdf') {
            $errors[] = 'Solo se permiten archivos PDF';
        }
        
        if ($file['size'] > 5 * 1024 * 1024) { // 5MB
            $errors[] = 'El archivo es demasiado grande (máximo 5MB)';
        }
        
        return [
            'valid' => empty($errors),
            'errors' => $errors
        ];
    }
    
    public static function generateProjectCode($projectData) {
        $dept = strtoupper(substr($projectData['departamento'], 0, 2));
        $muni = strtoupper(substr(str_replace(' ', '', $projectData['municipio']), 0, 3));
        $timestamp = date('ymd');
        
        return $dept . '-' . $muni . '-' . $timestamp;
    }
    
    public static function calculateProjectStats($projectId, $rodales) {
        $totalRodales = count($rodales);
        $areaTotal = array_sum(array_column($rodales, 'area_ha'));
        $areaPromedio = $totalRodales > 0 ? $areaTotal / $totalRodales : 0;
        
        return [
            'total_rodales' => $totalRodales,
            'area_total_ha' => $areaTotal,
            'area_promedio_ha' => round($areaPromedio, 2)
        ];
    }
    
    public static function canUserAccessProject($rol, $userId, $projectUserId) {
        if ($rol === 'Administrador') {
            return true;
        }
        
        if ($rol === 'Regente') {
            return $userId === $projectUserId;
        }
        
        return false;
    }
    
    public static function canUserReadProject($rol, $projectId) {
        return in_array($rol, ['Administrador', 'Regente', 'Técnico de Campo']);
    }
    
    public static function canUserModifyProject($rol, $projectId) {
        return in_array($rol, ['Administrador', 'Regente']);
    }
}
?>