<?php

namespace Tests\Feature;

use App\Models\AreaTrabajo;
use App\Models\Asignacion;
use App\Models\Departamento;
use App\Models\Ejecucion;
use App\Models\Solicitud;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Tests\TestCase;

/**
 * Suite completa de pruebas funcionales para SISER v2.
 *
 * Cubre el ciclo de vida completo de una solicitud de servicio:
 *   Creación → Recepción/Asignación → Ejecución → Conformación (Aprobación / Rechazo)
 */
class SolicitudLifecycleTest extends TestCase
{
    use DatabaseMigrations;

    protected function setUp(): void
    {
        parent::setUp();
        
        $this->artisan('migrate', [
            '--database' => 'pgsql_mantenimiento',
            '--path' => 'database/migrations/mantenimiento',
        ]);
    }

    // -------------------------------------------------------------------------
    // HELPERS: datos de prueba reutilizables
    // -------------------------------------------------------------------------

    private function crearDepartamento(): Departamento
    {
        $direccion = \App\Models\Direccion::firstOrCreate(
            ['codigo' => 'DTIC'],
            ['nombre' => 'Dirección de Tecnología e Información', 'activo' => true]
        );

        $gerencia = \App\Models\Gerencia::firstOrCreate(
            ['codigo' => 'GSIST'],
            ['nombre' => 'Gerencia de Sistemas', 'direccion_id' => $direccion->id, 'activo' => true]
        );

        return Departamento::create([
            'codigo' => 'SISTEMAS',
            'nombre' => 'Departamento de Sistemas',
            'descripcion' => 'Área TI',
            'gerencia_id' => $gerencia->id,
            'activo' => true,
        ]);
    }

    private function crearArea(): AreaTrabajo
    {
        return AreaTrabajo::create([
            'codigo' => 'REDES',
            'nombre' => 'Redes y Comunicaciones',
            'activo' => true,
        ]);
    }

    private function crearUsuario(array $attrs = []): User
    {
        $depto = $this->crearDepartamento();
        return User::factory()->create(array_merge([
            'departamento_id' => $depto->id,
        ], $attrs));
    }

    // =========================================================================
    // BLOQUE 1 — AUTENTICACIÓN
    // =========================================================================

    /** @test */
    public function la_pantalla_de_login_es_accesible()
    {
        $response = $this->get('/login');
        $response->assertStatus(200);
        $response->assertSee('Nombre de Usuario');
    }

    /** @test */
    public function un_usuario_puede_iniciar_sesion_con_cedula_y_contrasena_correctas()
    {
        $usuario = $this->crearUsuario(); // factory usa 'password' por defecto

        $response = $this->post('/login', [
            'username' => $usuario->username,
            'password' => 'password',
        ]);

        $this->assertAuthenticated();
        $response->assertRedirect(route('dashboard'));
    }

    /** @test */
    public function un_usuario_no_puede_iniciar_sesion_con_contrasena_incorrecta()
    {
        $usuario = $this->crearUsuario(); // factory usa 'password' por defecto

        $this->post('/login', [
            'username' => $usuario->username,
            'password' => 'incorrecta',
        ]);

        $this->assertGuest();
    }

    /** @test */
    public function un_usuario_no_autenticado_es_redirigido_al_login()
    {
        $this->get(route('dashboard'))->assertRedirect('/login');
        $this->get(route('solicitudes.index'))->assertRedirect('/login');
        $this->get(route('asignaciones.index'))->assertRedirect('/login');
        $this->get(route('ejecuciones.index'))->assertRedirect('/login');
        $this->get(route('conformaciones.index'))->assertRedirect('/login');
    }

    // =========================================================================
    // BLOQUE 2 — DASHBOARD
    // =========================================================================

    /** @test */
    public function el_dashboard_carga_correctamente_con_usuario_autenticado()
    {
        $usuario = $this->crearUsuario();
        $response = $this->actingAs($usuario)->get(route('dashboard'));

        $response->assertStatus(200);
        $response->assertSee('Panel de Control');
        $response->assertSee($usuario->name);
    }

    // =========================================================================
    // BLOQUE 3 — CREACIÓN DE SOLICITUD
    // =========================================================================

    /** @test */
    public function el_formulario_de_nueva_solicitud_es_accesible()
    {
        $usuario = $this->crearUsuario();

        $response = $this->actingAs($usuario)->get(route('solicitudes.create'));
        $response->assertStatus(200);
        $response->assertSee('departamento');
    }

    /** @test */
    public function un_usuario_puede_crear_una_solicitud_valida()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $usuario = User::factory()->create(['departamento_id' => $depto->id]);

        $response = $this->actingAs($usuario)->post(route('solicitudes.store'), [
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'El servidor de archivos no responde desde ayer en la tarde.',
            'observaciones' => 'Urgente, afecta a todo el departamento.',
        ]);

        $response->assertRedirect(route('solicitudes.index'));
        $this->assertDatabaseHas('solicitudes', [
            'usuario_id' => $usuario->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'estado' => 'I',
        ]);
    }

    /** @test */
    public function no_se_puede_crear_una_solicitud_con_descripcion_muy_corta()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $usuario = User::factory()->create(['departamento_id' => $depto->id]);

        $response = $this->actingAs($usuario)->post(route('solicitudes.store'), [
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Corto',   // < 10 caracteres
        ]);

        $response->assertSessionHasErrors(['descripcion']);
        $this->assertDatabaseCount('solicitudes', 0);
    }

    /** @test */
    public function no_se_puede_crear_una_solicitud_sin_departamento()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $usuario = User::factory()->create(['departamento_id' => $depto->id]);

        $response = $this->actingAs($usuario)->post(route('solicitudes.store'), [
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Descripción suficientemente larga para pasar validación.',
        ]);

        $response->assertSessionHasErrors(['departamento_id']);
    }

    /** @test */
    public function la_solicitud_creada_genera_numero_correlativo_unico()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $usuario = User::factory()->create(['departamento_id' => $depto->id]);

        $payload = [
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Primera solicitud para verificar numeración correlativa.',
        ];

        $this->actingAs($usuario)->post(route('solicitudes.store'), $payload);
        $this->actingAs($usuario)->post(route('solicitudes.store'), $payload);

        $numeros = Solicitud::pluck('numero')->toArray();
        // No deben repetirse
        $this->assertCount(2, array_unique($numeros));
    }

    /** @test */
    public function el_listado_de_solicitudes_muestra_solo_las_del_usuario_autenticado()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $usuario1 = User::factory()->create(['departamento_id' => $depto->id]);
        $usuario2 = User::factory()->create(['departamento_id' => $depto->id]);

        Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $usuario1->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Solicitud del usuario uno.',
            'estado' => 'I',
        ]);

        Solicitud::create([
            'numero' => '2026-0002',
            'usuario_id' => $usuario2->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Solicitud del usuario dos, no debe verse.',
            'estado' => 'I',
        ]);

        $response = $this->actingAs($usuario1)->get(route('solicitudes.index'));

        $response->assertStatus(200);
        $response->assertSee('2026-0001');
        $response->assertDontSee('2026-0002');
    }

    // =========================================================================
    // BLOQUE 4 — RECEPCIÓN / ASIGNACIÓN
    // =========================================================================

    /** @test */
    public function la_bandeja_de_asignaciones_muestra_solicitudes_en_estado_ingresada()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $usuario = User::factory()->create(['departamento_id' => $depto->id]);

        Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $usuario->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Solicitud ingresada visible en bandeja.',
            'estado' => 'I',
        ]);

        $analista = User::factory()->create(['departamento_id' => $depto->id, 'cargo' => 'técnico']);
        $response = $this->actingAs($analista)->get(route('asignaciones.index'));

        $response->assertStatus(200);
        $response->assertSee('2026-0001');
    }

    /** @test */
    public function un_analista_puede_recibir_y_asignar_una_solicitud_ingresada()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);
        $analista = User::factory()->create(['departamento_id' => $depto->id, 'cargo' => 'Jefe de Área']);

        $solicitud = Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Falla en impresora de red del piso 3.',
            'estado' => 'I',
        ]);

        $response = $this->actingAs($analista)->patch(route('asignaciones.update', $solicitud->id), [
            'fecha_estimada' => now()->addDays(2)->format('Y-m-d'),
            'observaciones_asignacion' => 'Recibido y asignado al analista disponible.',
        ]);

        $response->assertRedirect(route('asignaciones.index'));
        $this->assertDatabaseHas('asignaciones', [
            'solicitud_id' => $solicitud->id,
            'analista_id' => $analista->id,
        ]);
        $this->assertDatabaseHas('solicitudes', [
            'id' => $solicitud->id,
            'estado' => 'A',
        ]);
    }

    /** @test */
    public function no_se_puede_asignar_una_solicitud_en_estado_no_activo()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);
        $analista = User::factory()->create(['departamento_id' => $depto->id, 'cargo' => 'Jefe de Área']);

        // Estado 'CO' (Conformación pendiente) no es un estado activo reasignable
        $solicitud = Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Solicitud en estado de conformación, no reasignable.',
            'estado' => 'CO',
        ]);

        $response = $this->actingAs($analista)->patch(route('asignaciones.update', $solicitud->id));

        $response->assertRedirect();
        $response->assertSessionHas('error');
        $this->assertDatabaseCount('asignaciones', 0);
    }

    // =========================================================================
    // BLOQUE 5 — EJECUCIÓN DEL SERVICIO
    // =========================================================================

    /** @test */
    public function la_bandeja_de_ejecuciones_muestra_solicitudes_asignadas_al_analista()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);
        $analista = User::factory()->create(['departamento_id' => $depto->id, 'cargo' => 'técnico']);

        $solicitud = Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Solicitud para el analista de prueba.',
            'estado' => 'A',
        ]);

        Asignacion::create([
            'solicitud_id' => $solicitud->id,
            'analista_id' => $analista->id,
            'observaciones' => 'Asignada.',
        ]);

        $response = $this->actingAs($analista)->get(route('ejecuciones.index'));

        $response->assertStatus(200);
        $response->assertSee('2026-0001');
    }

    /** @test */
    public function abrir_una_solicitud_asignada_mantiene_el_estado_asignada()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);
        $analista = User::factory()->create(['departamento_id' => $depto->id, 'cargo' => 'técnico']);

        $solicitud = Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Apertura mantiene estado a A.',
            'estado' => 'A',
        ]);

        Asignacion::create([
            'solicitud_id' => $solicitud->id,
            'analista_id' => $analista->id,
            'observaciones' => 'Asignada.',
        ]);

        $this->actingAs($analista)->get(route('ejecuciones.show', $solicitud->id));

        $this->assertDatabaseHas('solicitudes', [
            'id' => $solicitud->id,
            'estado' => 'A',
        ]);
    }

    /** @test */
    public function un_analista_puede_registrar_la_solucion_de_una_solicitud()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);
        $analista = User::factory()->create(['departamento_id' => $depto->id, 'cargo' => 'técnico']);

        $solicitud = Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Falla resuelta con reinicio de switch.',
            'estado' => 'A',
        ]);

        Asignacion::create([
            'solicitud_id' => $solicitud->id,
            'analista_id' => $analista->id,
            'observaciones' => 'Asignada.',
        ]);

        $response = $this->actingAs($analista)->patch(route('ejecuciones.update', $solicitud->id), [
            'solucion' => 'Se reinició el switch de distribución del piso 2, servicio restaurado.',
            'observaciones' => 'Tiempo de respuesta: 45 minutos.',
            'tiempo_actividad' => '45 minutos',
        ]);

        $response->assertRedirect(route('ejecuciones.index', ['tab' => 'ejecutadas']));
        $this->assertDatabaseHas('ejecuciones', [
            'solicitud_id' => $solicitud->id,
            'analista_id' => $analista->id,
        ]);
        $this->assertDatabaseHas('solicitudes', [
            'id' => $solicitud->id,
            'estado' => 'CO',
        ]);
    }

    /** @test */
    public function no_se_puede_registrar_solucion_con_texto_muy_corto()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);
        $analista = User::factory()->create(['departamento_id' => $depto->id, 'cargo' => 'técnico']);

        $solicitud = Solicitud::create([
            'numero' => '2026-0002',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Test validación de solución.',
            'estado' => 'A',
        ]);

        Asignacion::create([
            'solicitud_id' => $solicitud->id,
            'analista_id' => $analista->id,
            'observaciones' => 'Asignada.',
        ]);

        $response = $this->actingAs($analista)->patch(route('ejecuciones.update', $solicitud->id), [
            'solucion' => 'Ok',  // < 10 caracteres
            'tiempo_actividad' => '10 minutos',
        ]);

        $response->assertSessionHasErrors(['solucion']);
        $this->assertDatabaseCount('ejecuciones', 0);
    }

    // =========================================================================
    // BLOQUE 6 — CONFORMACIÓN (APROBACIÓN / RECHAZO)
    // =========================================================================

    /** @test */
    public function la_bandeja_de_conformaciones_muestra_las_solicitudes_co_del_solicitante()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);

        Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Solicitud lista para conformar.',
            'estado' => 'CO',
        ]);

        $response = $this->actingAs($solicitante)->get(route('conformaciones.index'));

        $response->assertStatus(200);
        $response->assertSee('2026-0001');
    }

    /** @test */
    public function solo_el_solicitante_original_puede_ver_su_conformacion()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);
        $otroUsuario = User::factory()->create(['departamento_id' => $depto->id]);

        $solicitud = Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Solo el dueño la puede conformar.',
            'estado' => 'CO',
        ]);

        // Otro usuario intenta acceder a la conformación
        $response = $this->actingAs($otroUsuario)->get(route('conformaciones.show', $solicitud->id));

        $response->assertRedirect(route('conformaciones.index'));
        $response->assertSessionHas('error');
    }

    /** @test */
    public function el_solicitante_puede_calificar_su_solicitud_y_queda_pendiente_de_cierre()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);

        $solicitud = Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Solicitud resuelta y lista para calificar.',
            'estado' => 'CO',
        ]);

        $response = $this->actingAs($solicitante)->patch(route('conformaciones.update', $solicitud->id), [
            'calificacion' => 5,
            'observaciones_conformacion' => 'Todo quedó perfecto, muy buen servicio.',
        ]);

        $response->assertRedirect(route('conformaciones.index'));
        $response->assertSessionHas('success');
        // El estado pasa a CF (Conformada) y queda pendiente de cierre
        $this->assertDatabaseHas('solicitudes', [
            'id' => $solicitud->id,
            'estado' => 'CF',
            'calificacion' => 5,
        ]);
    }

    /** @test */
    public function no_se_puede_conformar_sin_calificacion()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);

        $solicitud = Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Solicitud para validar que la calificación es obligatoria.',
            'estado' => 'CO',
        ]);

        $response = $this->actingAs($solicitante)->patch(route('conformaciones.update', $solicitud->id), [
            'observaciones_conformacion' => 'Sin calificación enviada.',
            // 'calificacion' omitido intencionalmente
        ]);

        $response->assertSessionHasErrors(['calificacion']);
        // El estado no debe cambiar
        $this->assertDatabaseHas('solicitudes', ['id' => $solicitud->id, 'estado' => 'CO']);
    }

    /** @test */
    public function no_se_puede_conformar_con_calificacion_fuera_de_rango()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);

        $solicitud = Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Test calificación fuera de rango en conformación.',
            'estado' => 'CO',
        ]);

        $response = $this->actingAs($solicitante)->patch(
            route('conformaciones.update', $solicitud->id),
            ['calificacion' => 10]  // Fuera del rango permitido (1-5)
        );

        $response->assertSessionHasErrors(['calificacion']);
        // El estado no debe cambiar
        $this->assertDatabaseHas('solicitudes', ['id' => $solicitud->id, 'estado' => 'CO']);
    }

    // =========================================================================
    // BLOQUE 7 — CICLO DE VIDA COMPLETO (end-to-end)
    // =========================================================================

    /** @test */
    public function ciclo_completo_de_una_solicitud_desde_creacion_hasta_conformacion()
    {
        // Setup: departamento, área y dos usuarios
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);
        $analista = User::factory()->create(['departamento_id' => $depto->id, 'cargo' => 'Jefe de Área']);

        // PASO 1 — El SOLICITANTE crea la solicitud
        $this->actingAs($solicitante)->post(route('solicitudes.store'), [
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Sin acceso a internet en el piso 4 desde esta mañana.',
        ]);

        $solicitud = Solicitud::first();
        $this->assertEquals('I', $solicitud->estado, 'Debe estar Ingresada tras creación.');

        // PASO 2 — El ANALISTA recepciona la solicitud
        $this->actingAs($analista)->patch(route('asignaciones.update', $solicitud->id), [
            'fecha_estimada' => now()->addDay()->format('Y-m-d'),
            'observaciones_asignacion' => 'Recibido y atendido.',
        ]);

        $solicitud->refresh();
        $this->assertEquals('A', $solicitud->estado, 'Debe pasar a Asignada.');
        $this->assertDatabaseCount('asignaciones', 1);

        // PASO 3 — El ANALISTA abre la solicitud
        $this->actingAs($analista)->get(route('ejecuciones.show', $solicitud->id));

        $solicitud->refresh();
        $this->assertEquals('A', $solicitud->estado, 'Al abrir para atender, el estado se mantiene en Asignada.');

        // PASO 4 — El ANALISTA registra la solución
        $this->actingAs($analista)->patch(route('ejecuciones.update', $solicitud->id), [
            'solucion' => 'Se restableció la conexión configurando la VLAN correcta en el switch del piso 4.',
            'observaciones' => 'Tiempo de resolución: 2 horas.',
            'tiempo_actividad' => '2 horas',
        ]);

        $solicitud->refresh();
        $this->assertEquals('CO', $solicitud->estado, 'Debe pasar a Pendiente de Conformación.');
        $this->assertDatabaseCount('ejecuciones', 1);

        // PASO 5 — El SOLICITANTE califica el servicio
        $this->actingAs($solicitante)->patch(route('conformaciones.update', $solicitud->id), [
            'calificacion' => 5,
            'observaciones_conformacion' => 'Excelente servicio, muy rápido.',
        ]);

        $solicitud->refresh();
        $this->assertEquals('CF', $solicitud->estado, 'El ticket debe pasar a estado Conformado.');
        $this->assertEquals(5, $solicitud->calificacion, 'La calificación debe haberse guardado.');

        // PASO 6 — El ANALISTA realiza el cierre definitivo
        $this->actingAs($analista)->post(route('ejecuciones.cerrar', $solicitud->id));

        $solicitud->refresh();
        $this->assertEquals('CE', $solicitud->estado, 'El ticket debe pasar a estado Cerrado.');
    }

    /** @test */
    public function solo_el_solicitante_puede_calificar_su_propia_solicitud()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $solicitante = User::factory()->create(['departamento_id' => $depto->id]);
        $otroUsuario = User::factory()->create(['departamento_id' => $depto->id]);

        $solicitud = Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $solicitante->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Solicitud que otro usuario intenta calificar.',
            'estado' => 'CO',
        ]);

        // Otro usuario intenta calificar una solicitud que no le pertenece
        $response = $this->actingAs($otroUsuario)->patch(route('conformaciones.update', $solicitud->id), [
            'calificacion' => 4,
        ]);

        $response->assertRedirect(route('conformaciones.index'));
        $response->assertSessionHas('error');
        // El estado y calificación no deben cambiar
        $this->assertDatabaseHas('solicitudes', [
            'id' => $solicitud->id,
            'estado' => 'CO',
            'calificacion' => null,
        ]);
    }

    /** @test */
    public function el_reporte_de_solicitudes_cerradas_incluye_solicitudes_ejecutadas_pero_no_conformadas()
    {
        $depto = $this->crearDepartamento();
        $area = $this->crearArea();
        $admin = User::factory()->create([
            'departamento_id' => $depto->id,
            'cargo' => 'Admin'
        ]);

        $solicitudCerrada = Solicitud::create([
            'numero' => '2026-0001',
            'usuario_id' => $admin->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Cerrada',
            'estado' => 'CE',
        ]);

        $solicitudConformada = Solicitud::create([
            'numero' => '2026-0002',
            'usuario_id' => $admin->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Conformada',
            'estado' => 'CF',
        ]);

        $solicitudEjecutada = Solicitud::create([
            'numero' => '2026-0003',
            'usuario_id' => $admin->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Ejecutada/Por conformar',
            'estado' => 'CO',
        ]);

        $solicitudIngresada = Solicitud::create([
            'numero' => '2026-0004',
            'usuario_id' => $admin->id,
            'departamento_id' => $depto->id,
            'area_trabajo_id' => $area->id,
            'descripcion' => 'Ingresada',
            'estado' => 'I',
        ]);

        $response = $this->actingAs($admin)->get(route('reportes.generate', [
            'estado' => 'CE',
            'format' => 'html',
        ]));

        $response->assertStatus(200);
        $response->assertViewHas('solicitudes');
        $solicitudes = $response->viewData('solicitudes');

        $this->assertTrue($solicitudes->contains($solicitudCerrada));
        $this->assertFalse($solicitudes->contains($solicitudConformada));
        $this->assertTrue($solicitudes->contains($solicitudEjecutada));
        $this->assertFalse($solicitudes->contains($solicitudIngresada));
    }

    /** @test */
    public function el_usuario_de_mantenimiento_con_rol_superior_se_inicializa_en_mantenimiento()
    {
        $direccion = \App\Models\Direccion::create([
            'codigo' => 'DOPER',
            'nombre' => 'Dirección de Operaciones',
            'activo' => true,
        ]);

        $gerenciaMantenimiento = \App\Models\Gerencia::create([
            'codigo' => 'GMANT',
            'nombre' => 'Gerencia de Mantenimiento',
            'direccion_id' => $direccion->id,
            'activo' => true,
        ]);

        $depto = Departamento::create([
            'codigo' => 'MANT',
            'nombre' => 'Departamento de Mantenimiento',
            'gerencia_id' => $gerenciaMantenimiento->id,
            'activo' => true,
        ]);

        $usuario = User::factory()->create([
            'departamento_id' => $depto->id,
            'gerencia_id' => $gerenciaMantenimiento->id,
            'cargo' => 'técnico',
        ]);

        $response = $this->actingAs($usuario)->get(route('dashboard'));

        $response->assertStatus(200);
        $this->assertEquals('mantenimiento', session('modulo_activo'));
    }

    /** @test */
    public function el_usuario_regular_de_mantenimiento_permanece_en_tecnologia()
    {
        $direccion = \App\Models\Direccion::create([
            'codigo' => 'DOPER',
            'nombre' => 'Dirección de Operaciones',
            'activo' => true,
        ]);

        $gerenciaMantenimiento = \App\Models\Gerencia::create([
            'codigo' => 'GMANT',
            'nombre' => 'Gerencia de Mantenimiento',
            'direccion_id' => $direccion->id,
            'activo' => true,
        ]);

        $depto = Departamento::create([
            'codigo' => 'MANT',
            'nombre' => 'Departamento de Mantenimiento',
            'gerencia_id' => $gerenciaMantenimiento->id,
            'activo' => true,
        ]);

        $usuario = User::factory()->create([
            'departamento_id' => $depto->id,
            'gerencia_id' => $gerenciaMantenimiento->id,
            'cargo' => 'Usuario',
        ]);

        $response = $this->actingAs($usuario)->get(route('dashboard'));

        $response->assertStatus(200);
        $this->assertNotEquals('mantenimiento', session('modulo_activo'));
    }
}
