<?php

namespace App\Http\Controllers\Administracion;

use App\Http\Controllers\Controller;
use App\Models\Area;
use App\Models\Curso;
use App\Models\proceso;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class AreaController extends Controller
{
        public function index(Request $request)
        {
            $query = Area::withCount(['cursos', 'procesos']);

            if ($request->filled('search')) {
                $search = $request->search;
                $query->where(function ($q) use ($search) {
                    $q->where('nombre', 'like', "%{$search}%")
                    ->orWhere('codigo', 'like', "%{$search}%");
                });
            }

            if (!is_null($request->activo)) {
                $query->where('activo', $request->activo);
            }

            $areas = $query
                ->orderBy('created_at', 'desc')
                ->paginate($request->get('per_page', 10));

            return response()->json([
                'success' => true,
                'data' => $areas
            ]);
        }


    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'nombre'      => 'required|string|min:3|max:100',
            'codigo'      => 'required|string|min:2|max:20|regex:/^[A-Z0-9]+$/|unique:areas,codigo',
            'descripcion' => 'nullable|string|max:500',
            'activo'      => 'boolean',
        ], [
            'codigo.regex' => 'El código solo puede contener letras mayúsculas y números'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors'  => $validator->errors()
            ], 422);
        }

        $area = Area::create([
            'nombre'      => $request->nombre,
            'codigo'      => strtoupper($request->codigo),
            'descripcion' => $request->descripcion,
            'activo'      => $request->activo ?? true,
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Área creada correctamente',
            'data'    => $area
        ], 201);
    }

    public function show($id)
    {
        $area = Area::with(['cursos', 'examenes'])->find($id);

        if (!$area) {
            return response()->json([
                'success' => false,
                'message' => 'Área no encontrada'
            ], 404);
        }

        return response()->json([
            'success' => true,
            'data'    => $area
        ]);
    }

    public function update(Request $request, $id)
    {
        $area = Area::find($id);

        if (!$area) {
            return response()->json([
                'success' => false,
                'message' => 'Área no encontrada'
            ], 404);
        }

        $validator = Validator::make($request->all(), [
            'nombre'      => 'required|string|min:3|max:100',
            'codigo'      => 'required|string|min:2|max:20|regex:/^[A-Z0-9]+$/|unique:areas,codigo,' . $id,
            'descripcion' => 'nullable|string|max:500',
            'activo'      => 'boolean',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors'  => $validator->errors()
            ], 422);
        }

        $area->update([
            'nombre'      => $request->nombre,
            'codigo'      => strtoupper($request->codigo),
            'descripcion' => $request->descripcion,
            'activo'      => $request->activo ?? $area->activo, 
        ]);

        return response()->json([
            'success' => true,
            'message' => 'Área actualizada correctamente',
            'data'    => $area
        ]);
    }

    public function toggleEstado($id)
        {
            $area = Area::find($id);

            if (!$area) {
                return response()->json([
                    'success' => false,
                    'message' => 'Área no encontrada'
                ], 404);
            }

            $area->activo = !$area->activo;
            $area->save();

            return response()->json([
                'success' => true,
                'message' => $area->activo ? 'Área activada' : 'Área desactivada',
                'data'    => $area
            ]);
        }

    public function destroy($id)
    {
        $area = Area::with(['cursos', 'examenes'])->find($id);

        if (!$area) {
            return response()->json([
                'success' => false,
                'message' => 'Área no encontrada'
            ], 404);
        }

        if ($area->cursos()->count() > 0 || $area->examenes()->count() > 0) {
            return response()->json([
                'success' => false,
                'message' => 'No se puede eliminar un área con cursos o exámenes asociados'
            ], 409);
        }

        $area->delete();

        return response()->json([
            'success' => true,
            'message' => 'Área eliminada correctamente'
        ]);
    }




    public function vincularCursosArea(Request $request, $areaId)
    {
        try {
            $user = auth()->user();

            if (!$user->hasRole('administrador')) {
                return response()->json(['success' => false, 'message' => 'No autorizado'], 403);
            }

            $area = Area::find($areaId);

            if (!$area) {
                return response()->json(['success' => false, 'message' => 'Área no encontrada'], 404);
            }

            $validator = Validator::make($request->all(), [
                'cursos' => 'required|array',
                'cursos.*' => 'required|integer|exists:cursos,id'
            ]);

            if ($validator->fails()) {
                return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
            }
            $area->cursos()->sync($request->cursos);

            $area->load('cursos:id,nombre,codigo');

            return response()->json([
                'success' => true,
                'message' => 'Cursos vinculados a la área exitosamente',
                'data' => $area
            ]);

        } catch (\Exception $e) {
            Log::error('Error vinculando cursos a área', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'area_id' => $areaId,
                'request_data' => $request->all()
            ]);

            return response()->json(['success' => false, 'message' => 'Error al vincular cursos: ' . $e->getMessage()], 500);
        }
    }


    public function getCursosPorArea(Request $request, $areaId)
    {
        try {
            $user = auth()->user();

            if (!$user->hasRole('administrador')) {
                return response()->json(['success' => false, 'message' => 'No autorizado'], 403);
            }

            $area = Area::find($areaId);

            if (!$area) {
                return response()->json(['success' => false, 'message' => 'Área no encontrada'], 404);
            }

            $todosLosCursos = Curso::select('id', 'nombre', 'codigo')
                ->orderBy('nombre')
                ->get();

            $cursosVinculadosIds = $area->cursos->pluck('id')->toArray();

            return response()->json([
                'success' => true,
                'data' => [
                    'todos_los_cursos' => $todosLosCursos,
                    'cursos_vinculados' => $cursosVinculadosIds
                ]
            ]);

        } catch (\Exception $e) {
            Log::error('Error obteniendo cursos por área', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'area_id' => $areaId
            ]);

            return response()->json(['success' => false, 'message' => 'Error al cargar cursos: ' . $e->getMessage()], 500);
        }
    }


    public function desvincularCursoArea(Request $request, $areaId)
    {
        try {
            $user = auth()->user();

            if (!$user->hasRole('administrador')) {
                return response()->json(['success' => false, 'message' => 'No autorizado'], 403);
            }

            $area = Area::find($areaId);

            if (!$area) {
                return response()->json(['success' => false, 'message' => 'Área no encontrada'], 404);
            }

            $validator = Validator::make($request->all(), [
                'curso_id' => 'required|exists:cursos,id'
            ]);

            if ($validator->fails()) {
                return response()->json(['success' => false, 'errors' => $validator->errors()], 422);
            }

            $area->cursos()->detach($request->curso_id);

            return response()->json([
                'success' => true,
                'message' => 'Curso desvinculado de la área exitosamente'
            ]);

        } catch (\Exception $e) {
            Log::error('Error desvinculando curso de área', [
                'error' => $e->getMessage()
            ]);

            return response()->json(['success' => false, 'message' => 'Error al desvincular curso de la área'], 500);
        }
    }


    public function vincularProcesosArea(Request $request, $areaId)
{
    try {
        $user = auth()->user();

        if (!$user->hasRole('administrador')) {
            return response()->json([
                'success' => false,
                'message' => 'No autorizado'
            ], 403);
        }

        $area = Area::find($areaId);

        if (!$area) {
            return response()->json([
                'success' => false,
                'message' => 'Área no encontrada'
            ], 404);
        }

        $validator = Validator::make($request->all(), [
            'procesos'   => 'required|array',
            'procesos.*' => 'required|integer|exists:procesos,id',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors'  => $validator->errors()
            ], 422);
        }

        $area->procesos()->sync($request->procesos);

        $area->load('procesos:id,nombre,tipo_proceso');

        return response()->json([
            'success' => true,
            'message' => 'Procesos vinculados a la área exitosamente',
            'data'    => $area
        ]);

    } catch (\Exception $e) {
        Log::error('Error vinculando procesos a área', [
            'error'    => $e->getMessage(),
            'area_id'  => $areaId,
            'request'  => $request->all(),
        ]);

        return response()->json([
            'success' => false,
            'message' => 'Error al vincular procesos'
        ], 500);
    }
}

public function getProcesosPorArea(Request $request, $areaId)
{
    try {
        $user = auth()->user();

        if (!$user->hasRole('administrador')) {
            return response()->json([
                'success' => false,
                'message' => 'No autorizado'
            ], 403);
        }

        $area = Area::find($areaId);

        if (!$area) {
            return response()->json([
                'success' => false,
                'message' => 'Área no encontrada'
            ], 404);
        }

        $todosLosProcesos = Proceso::select(
                'id',
                'nombre',
                'tipo_proceso',
                'activo'
            )
            ->orderBy('nombre')
            ->get();

        $procesosVinculadosIds = $area
            ->procesos
            ->pluck('id')
            ->toArray();

        return response()->json([
            'success' => true,
            'data' => [
                'todos_los_procesos'   => $todosLosProcesos,
                'procesos_vinculados' => $procesosVinculadosIds
            ]
        ]);

    } catch (\Exception $e) {
        Log::error('Error obteniendo procesos por área', [
            'error'   => $e->getMessage(),
            'area_id'=> $areaId
        ]);

        return response()->json([
            'success' => false,
            'message' => 'Error al cargar procesos'
        ], 500);
    }
}

public function desvincularProcesoArea(Request $request, $areaId)
{
    try {
        $user = auth()->user();

        if (!$user->hasRole('administrador')) {
            return response()->json([
                'success' => false,
                'message' => 'No autorizado'
            ], 403);
        }

        $area = Area::find($areaId);

        if (!$area) {
            return response()->json([
                'success' => false,
                'message' => 'Área no encontrada'
            ], 404);
        }

        $validator = Validator::make($request->all(), [
            'proceso_id' => 'required|exists:procesos,id'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'errors'  => $validator->errors()
            ], 422);
        }

        $area->procesos()->detach($request->proceso_id);

        return response()->json([
            'success' => true,
            'message' => 'Proceso desvinculado de la área exitosamente'
        ]);

    } catch (\Exception $e) {
        Log::error('Error desvinculando proceso de área', [
            'error' => $e->getMessage()
        ]);

        return response()->json([
            'success' => false,
            'message' => 'Error al desvincular proceso'
        ], 500);
    }
}



}
