<?php

namespace App\Http\Controllers;

use App\Models\Configuracion;
use App\Models\AuditoriaAdmin;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ConfiguracionController extends Controller
{
    /**
     * Ver todas las configuraciones
     * GET /api/admin/configuracion
     */
    public function ver(Request $request)
    {
        $query = Configuracion::query();

        // Filtrar por grupo si se especifica
        if ($request->has('grupo')) {
            $query->where('grupo', $request->grupo);
        }

        // Solo configuraciones editables si se solicita
        if ($request->has('solo_editables') && $request->solo_editables) {
            $query->where('editable', true);
        }

        $configuraciones = $query->orderBy('grupo')->orderBy('clave')->get();

        // Agrupar por grupo para mejor presentación
        if ($request->has('agrupar') && $request->agrupar) {
            $agrupadas = $configuraciones->groupBy('grupo');
            return response()->json($agrupadas);
        }

        return response()->json($configuraciones);
    }

    /**
     * Ver configuraciones por grupo
     * GET /api/admin/configuracion/grupo/{grupo}
     */
    public function porGrupo($grupo)
    {
        $configuraciones = Configuracion::obtenerGrupo($grupo);

        return response()->json([
            'grupo' => $grupo,
            'configuraciones' => $configuraciones
        ]);
    }

    /**
     * Obtener valor de una configuración específica
     * GET /api/admin/configuracion/{clave}
     */
    public function obtener($clave)
    {
        $configuracion = Configuracion::where('clave', $clave)->first();

        if (!$configuracion) {
            return response()->json([
                'success' => false,
                'message' => 'Configuración no encontrada'
            ], 404);
        }

        return response()->json([
            'clave' => $configuracion->clave,
            'valor' => $configuracion->convertirValor(),
            'tipo' => $configuracion->tipo,
            'grupo' => $configuracion->grupo,
            'descripcion' => $configuracion->descripcion,
            'editable' => $configuracion->editable
        ]);
    }

    /**
     * Actualizar configuración
     * PUT /api/admin/configuracion/{clave}
     */
    public function actualizar(Request $request, $clave)
    {
        $request->validate([
            'valor' => 'required',
            'admin_id' => 'required|exists:usuarios,id'
        ]);

        try {
            $configuracion = Configuracion::where('clave', $clave)->first();

            if (!$configuracion) {
                return response()->json([
                    'success' => false,
                    'message' => 'Configuración no encontrada'
                ], 404);
            }

            // Verificar si es editable
            if (!$configuracion->editable) {
                return response()->json([
                    'success' => false,
                    'message' => 'Esta configuración no es editable'
                ], 403);
            }

            $valorAnterior = $configuracion->valor;

            DB::beginTransaction();

            // Convertir el valor según el tipo
            $valorNuevo = $request->valor;
            
            // Validar y convertir según tipo
            switch ($configuracion->tipo) {
                case 'integer':
                    if (!is_numeric($valorNuevo)) {
                        throw new \Exception('El valor debe ser un número entero');
                    }
                    $valorNuevo = (string)(int)$valorNuevo;
                    break;
                
                case 'float':
                    if (!is_numeric($valorNuevo)) {
                        throw new \Exception('El valor debe ser un número decimal');
                    }
                    $valorNuevo = (string)(float)$valorNuevo;
                    break;
                
                case 'boolean':
                    $valorNuevo = in_array($valorNuevo, [true, 'true', '1', 1], true) ? '1' : '0';
                    break;
                
                case 'json':
                case 'array':
                    if (is_array($valorNuevo)) {
                        $valorNuevo = json_encode($valorNuevo);
                    } elseif (!is_string($valorNuevo) || json_decode($valorNuevo) === null) {
                        throw new \Exception('El valor debe ser un JSON válido');
                    }
                    break;
            }

            $configuracion->valor = $valorNuevo;
            $configuracion->save();

            // Registrar auditoría
            AuditoriaAdmin::registrar(
                $request->admin_id,
                'actualizar_configuracion',
                'configuracion',
                "Configuración '{$clave}' actualizada de '{$valorAnterior}' a '{$valorNuevo}'",
                'Configuracion',
                $configuracion->id,
                ['valor' => $valorAnterior],
                ['valor' => $valorNuevo]
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Configuración actualizada exitosamente',
                'configuracion' => [
                    'clave' => $configuracion->clave,
                    'valor' => $configuracion->convertirValor(),
                    'valor_anterior' => $configuracion->convertirValor($valorAnterior, $configuracion->tipo)
                ]
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Error al actualizar configuración',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Actualizar múltiples configuraciones a la vez
     * PUT /api/admin/configuracion/actualizar-multiple
     */
    public function actualizarMultiple(Request $request)
    {
        $request->validate([
            'configuraciones' => 'required|array',
            'configuraciones.*.clave' => 'required|string',
            'configuraciones.*.valor' => 'required',
            'admin_id' => 'required|exists:usuarios,id'
        ]);

        try {
            DB::beginTransaction();

            $resultados = [];
            $errores = [];

            foreach ($request->configuraciones as $config) {
                try {
                    $configuracion = Configuracion::where('clave', $config['clave'])->first();

                    if (!$configuracion) {
                        $errores[] = "Configuración '{$config['clave']}' no encontrada";
                        continue;
                    }

                    if (!$configuracion->editable) {
                        $errores[] = "Configuración '{$config['clave']}' no es editable";
                        continue;
                    }

                    $valorAnterior = $configuracion->valor;
                    $configuracion->valor = $config['valor'];
                    $configuracion->save();

                    // Registrar auditoría
                    AuditoriaAdmin::registrar(
                        $request->admin_id,
                        'actualizar_configuracion',
                        'configuracion',
                        "Configuración '{$config['clave']}' actualizada",
                        'Configuracion',
                        $configuracion->id,
                        ['valor' => $valorAnterior],
                        ['valor' => $config['valor']]
                    );

                    $resultados[] = [
                        'clave' => $config['clave'],
                        'actualizado' => true
                    ];
                } catch (\Exception $e) {
                    $errores[] = "Error en '{$config['clave']}': {$e->getMessage()}";
                }
            }

            DB::commit();

            return response()->json([
                'success' => count($errores) === 0,
                'message' => count($errores) === 0 
                    ? 'Todas las configuraciones actualizadas exitosamente' 
                    : 'Algunas configuraciones no pudieron actualizarse',
                'resultados' => $resultados,
                'errores' => $errores
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Error al actualizar configuraciones',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Crear nueva configuración
     * POST /api/admin/configuracion
     */
    public function crear(Request $request)
    {
        $request->validate([
            'clave' => 'required|string|unique:configuracion,clave',
            'valor' => 'required|string',
            'tipo' => 'required|in:string,integer,float,boolean,json,array',
            'grupo' => 'required|string',
            'descripcion' => 'nullable|string',
            'editable' => 'boolean',
            'admin_id' => 'required|exists:usuarios,id'
        ]);

        try {
            DB::beginTransaction();

            $configuracion = Configuracion::create([
                'clave' => $request->clave,
                'valor' => $request->valor,
                'tipo' => $request->tipo,
                'grupo' => $request->grupo,
                'descripcion' => $request->descripcion,
                'editable' => $request->editable ?? true
            ]);

            // Registrar auditoría
            AuditoriaAdmin::registrar(
                $request->admin_id,
                'crear_configuracion',
                'configuracion',
                "Nueva configuración creada: {$request->clave}",
                'Configuracion',
                $configuracion->id,
                null,
                $configuracion->toArray()
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Configuración creada exitosamente',
                'configuracion' => $configuracion
            ], 201);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Error al crear configuración',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Eliminar configuración
     * DELETE /api/admin/configuracion/{clave}
     */
    public function eliminar(Request $request, $clave)
    {
        $request->validate([
            'admin_id' => 'required|exists:usuarios,id'
        ]);

        try {
            $configuracion = Configuracion::where('clave', $clave)->first();

            if (!$configuracion) {
                return response()->json([
                    'success' => false,
                    'message' => 'Configuración no encontrada'
                ], 404);
            }

            if (!$configuracion->editable) {
                return response()->json([
                    'success' => false,
                    'message' => 'Esta configuración no puede ser eliminada'
                ], 403);
            }

            DB::beginTransaction();

            $datosConfiguracion = $configuracion->toArray();
            $configuracion->delete();

            // Registrar auditoría
            AuditoriaAdmin::registrar(
                $request->admin_id,
                'eliminar_configuracion',
                'configuracion',
                "Configuración eliminada: {$clave}",
                'Configuracion',
                $configuracion->id,
                $datosConfiguracion,
                null
            );

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Configuración eliminada exitosamente'
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Error al eliminar configuración',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Listar todos los grupos de configuración
     * GET /api/admin/configuracion/grupos
     */
    public function listarGrupos()
    {
        $grupos = Configuracion::select('grupo')
            ->distinct()
            ->orderBy('grupo')
            ->pluck('grupo');

        return response()->json($grupos);
    }
}
