<?php

namespace App\Controllers;

use CodeIgniter\Exceptions\PageNotFoundException;
use App\Models\ArchivoModel;
use App\Models\OrganizacionModel;

class Archivos extends BaseController
{
    protected $archivoModel;

    public function __construct()
    {
        $this->archivoModel = new ArchivoModel();
        $this->organizacionModel = new \App\Models\OrganizacionModel();
    }

    public function index(): string
    {
        permiso('Archivos', 'Visualizar', true);
        $data['organizaciones'] = $this->organizacionModel->getListadoActivas();
        $data['tipos'] = TIPO_ARCHIVO;
        $data['crear_permiso'] = permiso('Archivos', 'Crear', false);
        $data['editar_permiso'] = permiso('Archivos', 'Editar', false);
        $data['eliminar_permiso'] = permiso('Archivos', 'Eliminar', false);
        return view('archivos/index', $data);
    }

    public function store()
    {
        permiso('Archivos', 'Crear', true);
        $this->response->setContentType('application/json');
        
        $data = $this->request->getPost();
        unset($data['archivo_file']);
        
        log_message('error', 'Store archivo - Data recibida: ' . json_encode($data));
        
        try {
            // Validar que el nombre del archivo no exista para la misma organización
            $existeArchivo = $this->archivoModel
                ->where('nombre', $data['nombre'])
                ->where('organizacion_id', 1) // TODO: Cambiar por session()->get('usuario')['organizacion_id']
                ->where('deleted_at', null)
                ->first();

            if ($existeArchivo) {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'Ya existe un archivo con ese nombre en esta organización.'
                ]);
            }

            // Manejar subida de archivo
            $archivoUrl = null;
            $archivo = $this->request->getFile('archivo_file');
            
            log_message('error', '=== DEBUG ARCHIVO ===');
            log_message('error', 'Archivo objeto: ' . ($archivo ? 'existe' : 'null'));
            
            if ($archivo && $archivo->isValid() && !$archivo->hasMoved()) {
                log_message('error', '>>> PROCESANDO ARCHIVO <<<');
                
                // Validar tamaño (máximo 10MB)
                if ($archivo->getSize() > 10485760) {
                    return $this->response->setJSON([
                        'success' => false,
                        'message' => 'El archivo no debe superar los 10MB.'
                    ]);
                }
                
                // Crear directorio si no existe
                $uploadPath = FCPATH . 'uploads/archivos';
                if (!is_dir($uploadPath)) {
                    mkdir($uploadPath, 0775, true);
                }
                
                @chmod($uploadPath, 0775);
                
                // Generar nombre único
                $extension = $archivo->getExtension();
                $nuevoNombre = 'archivo_' . time() . '_' . uniqid() . '.' . $extension;
                
                log_message('error', 'Intentando mover archivo a: ' . $uploadPath . '/' . $nuevoNombre);
                
                try {
                    $archivo->move($uploadPath, $nuevoNombre);
                    log_message('error', 'Archivo movido exitosamente');
                } catch (\Exception $moveException) {
                    log_message('error', 'Error moviendo archivo: ' . $moveException->getMessage());
                    return $this->response->setJSON([
                        'success' => false,
                        'message' => 'Error al guardar el archivo: ' . $moveException->getMessage()
                    ]);
                }
                
                $archivoUrl = 'uploads/archivos/' . $nuevoNombre;
                $data['url'] = $archivoUrl;               
                
                log_message('error', 'Archivo URL guardada: ' . $archivoUrl);
            } else {
                log_message('error', '>>> NO SE PROCESÓ EL ARCHIVO <<<');
            }

            // Valores por defecto
            if (!isset($data['visibilidad'])) {
                $data['visibilidad'] = 'publico';
            }
            
            // Campos requeridos
            $data['usuario_id'] = session()->get('usuario')['id'] ?? 1;

            $saved = $this->archivoModel->save($data);
            
            log_message('error', 'Resultado save: ' . ($saved ? 'true' : 'false'));
            log_message('error', 'Errores modelo: ' . json_encode($this->archivoModel->errors()));
            
            if ($saved) {
                session()->setFlashdata('success', 'Archivo creado correctamente.');
                
                return $this->response->setJSON([
                    'success' => true,
                    'message' => 'Archivo guardado exitosamente.',
                    'data' => ['id' => $this->archivoModel->getInsertID()]
                ]);
            } else {
                if ($archivoUrl && file_exists(FCPATH . $archivoUrl)) {
                    unlink(FCPATH . $archivoUrl);
                }
                
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'Error al guardar el archivo.',
                    'errors' => $this->archivoModel->errors()
                ]);
            }
        } catch (\Exception $e) {
            log_message('error', 'Exception en store: ' . $e->getMessage());
            
            if (isset($archivoUrl) && $archivoUrl && file_exists(FCPATH . $archivoUrl)) {
                unlink(FCPATH . $archivoUrl);
            }
            
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Error inesperado: ' . $e->getMessage()
            ]);
        }
    }

    public function update($id)
    {
        permiso('Archivos', 'Editar', true);
        $this->response->setContentType('application/json');
        
        $data = $this->request->getPost();

        $archivoActual = $this->archivoModel->find($id);
        if (!$archivoActual) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Archivo no encontrado.'
            ]);
        }

        // Validar nombre único (excluyendo el actual)
        $existeArchivo = $this->archivoModel
            ->where('nombre', $data['nombre'])
            ->where('organizacion_id', 1) // TODO: Cambiar por session()->get('usuario')['organizacion_id']
            ->where('id !=', $id)
            ->where('deleted_at', null)
            ->first();

        if ($existeArchivo) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Ya existe un archivo con ese nombre en esta organización.'
            ]);
        }

        try {
            $archivo = [
                'nombre' => $data['nombre'],
                'descripcion' => $data['descripcion'],
                'visibilidad' => $data['visibilidad'],
                'tipo' => $data['tipo'],
                'categorias' => $data['categorias']
            ];

            // Manejar eliminación de archivo
            if (isset($data['eliminar_archivo']) && $data['eliminar_archivo'] == '1') {
                if (!empty($archivoActual['url']) && file_exists(FCPATH . $archivoActual['url'])) {
                    unlink(FCPATH . $archivoActual['url']);
                }
                $archivo['url'] = null;
            }

            // Manejar nuevo archivo
            $archivoFile = $this->request->getFile('archivo_file');
            if ($archivoFile && $archivoFile->isValid() && !$archivoFile->hasMoved()) {
                // Validar tamaño
                if ($archivoFile->getSize() > 10485760) {
                    return $this->response->setJSON([
                        'success' => false,
                        'message' => 'El archivo no debe superar los 10MB.'
                    ]);
                }
                
                $uploadPath = FCPATH . 'uploads/archivos';
                if (!is_dir($uploadPath)) {
                    mkdir($uploadPath, 0775, true);
                }
                
                @chmod($uploadPath, 0775);
                
                $extension = $archivoFile->getExtension();
                $nuevoNombre = 'archivo_' . time() . '_' . uniqid() . '.' . $extension;
                
                try {
                    $archivoFile->move($uploadPath, $nuevoNombre);
                    
                    // Eliminar archivo anterior
                    if (!empty($archivoActual['url']) && file_exists(FCPATH . $archivoActual['url'])) {
                        unlink(FCPATH . $archivoActual['url']);
                    }
                    
                    $archivo['url'] = 'uploads/archivos/' . $nuevoNombre;
                    
                    // Actualizar tipo si cambió
                    $archivo['tipo'] = $this->detectarTipoArchivo($extension);
                    
                } catch (\Exception $moveException) {
                    return $this->response->setJSON([
                        'success' => false,
                        'message' => 'Error al guardar el archivo: ' . $moveException->getMessage()
                    ]);
                }
            }

            if ($this->archivoModel->update($id, $archivo)) {
                session()->setFlashdata('success', 'Archivo actualizado correctamente.');
                
                return $this->response->setJSON([
                    'success' => true,
                    'message' => 'Archivo actualizado exitosamente.',
                    'data' => $this->archivoModel->find($id)
                ]);
            } else {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'Error al actualizar el archivo.',
                    'errors' => $this->archivoModel->errors()
                ]);
            }
        } catch (\Exception $e) {
            log_message('error', 'Exception en update: ' . $e->getMessage());
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Error inesperado: ' . $e->getMessage()
            ]);
        }
    }

    public function delete($id)
    {
        permiso('Archivos', 'Eliminar', true);
        
        $this->response->setContentType('application/json');
        
        $archivo = $this->archivoModel->find($id);
        if (!$archivo) {
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Archivo no encontrado.'
            ]);
        }

        try {
            // Eliminar archivo físico si existe
            if (!empty($archivo['url']) && file_exists(FCPATH . $archivo['url'])) {
                unlink(FCPATH . $archivo['url']);
            }

            if ($this->archivoModel->delete($id)) {
                session()->setFlashdata('success', 'Archivo eliminado correctamente.');
                
                return $this->response->setJSON([
                    'success' => true,
                    'message' => 'Archivo eliminado exitosamente.'
                ]);
            } else {
                return $this->response->setJSON([
                    'success' => false,
                    'message' => 'Error al eliminar el archivo.'
                ]);
            }
        } catch (\Exception $e) {
            log_message('error', 'Exception en delete: ' . $e->getMessage());
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Error inesperado: ' . $e->getMessage()
            ]);
        }
    }

    public function datatable()
    {
        permiso('Archivos', 'Visualizar', true);
        $json = $this->archivoModel->getDatatable($this->request);
        return $this->response->setJSON($json);
    }

    public function listado()
    {
        permiso('Archivos', 'Visualizar', true);
        
        $this->response->setContentType('application/json');
        
        try {
            // Obtener parámetros de búsqueda
            $busqueda = $this->request->getGet('busqueda') ?? '';
            $categoria = $this->request->getGet('categoria') ?? '';
            $tipo = $this->request->getGet('tipo') ?? '';
            
            // Preparar filtros
            $filtros = [
                'busqueda' => $busqueda,
                'categoria' => $categoria,
                'tipo' => $tipo
            ];
            
            // Obtener archivos con permisos aplicados (máximo 10)
            $archivos = $this->archivoModel->getArchivosConPermisos(
                $filtros,
                10
            );
            
            return $this->response->setJSON([
                'success' => true,
                'data' => $archivos,
                'total' => count($archivos)
            ]);
            
        } catch (\Exception $e) {
            log_message('error', 'Exception en listado: ' . $e->getMessage());
            return $this->response->setJSON([
                'success' => false,
                'message' => 'Error inesperado: ' . $e->getMessage()
            ]);
        }
    }
}
