<?php

namespace App\Http\Controllers;

use App\Models\DireccionEntrega;
use App\Models\Cliente; // Asegúrate de importar el modelo Cliente
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\DB; // Para usar transacciones

class DireccionEntregaController extends Controller
{
    /**
     * Muestra una lista de las direcciones de entrega para un cliente específico.
     * Se puede pasar cliente_id como parámetro en la query string.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function index(Cliente $cliente): JsonResponse
    {
        $direcciones = DireccionEntrega::where('cliente_id', $cliente->id)
            ->orderBy('es_principal', 'desc')
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json(['data' => $direcciones]);
    }

    /**
     * Almacena una nueva dirección de entrega en la base de datos.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function store(Request $request): JsonResponse
    {
        $validatedData = $request->validate([
            'cliente_id' => ['required', 'integer', Rule::exists('clientes', 'id')],
            'nombre' => ['nullable', 'string', 'max:255'],
            'calle' => ['required', 'string', 'max:255'],
            'numero_exterior' => ['required', 'string', 'max:255'],
            'numero_interior' => ['nullable', 'string', 'max:255'],
            'colonia' => ['required', 'string', 'max:255'],
            'codigo_postal' => ['required', 'string', 'max:10'],
            'ciudad' => ['required', 'string', 'max:255'],
            'estado' => ['required', 'string', 'max:255'],
            'pais' => ['sometimes', 'string', 'max:255'],
            'referencia' => ['nullable', 'string'],
            'es_principal' => ['required', Rule::in(['si', 'no'])],
        ], [
            'cliente_id.required' => 'El cliente es requerido',
            'cliente_id.exists' => 'El cliente seleccionado no existe',
            'calle.required' => 'La calle es requerida',
            'numero_exterior.required' => 'El número exterior es requerido',
            'colonia.required' => 'La colonia es requerida',
            'codigo_postal.required' => 'El código postal es requerido',
            'ciudad.required' => 'La ciudad es requerida',
            'estado.required' => 'El estado es requerido',
            'es_principal.required' => 'Debe especificar si es dirección principal',
            'es_principal.in' => 'El valor debe ser si o no',
        ]);

        try {
            DB::beginTransaction();

            if ($validatedData['es_principal'] === 'si') {
                DireccionEntrega::where('cliente_id', $validatedData['cliente_id'])
                    ->where('es_principal', 'si')
                    ->update(['es_principal' => 'no']);
            }

            $direccion = DireccionEntrega::create($validatedData);

            DB::commit();

            return response()->json([
                'data' => $direccion,
                'message' => 'Dirección creada exitosamente.'
            ], JsonResponse::HTTP_CREATED);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'message' => 'Error al crear la dirección.',
                'error' => $e->getMessage()
            ], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * Muestra la dirección de entrega especificada.
     *
     * @param  \App\Models\DireccionEntrega  $direccionEntrega
     * @return \Illuminate\Http\JsonResponse
     */
    public function show(DireccionEntrega $direccionEntrega): JsonResponse
    {
        // Opcional: Añadir autorización para verificar si el usuario puede ver esta dirección
        // if (auth()->user()->cannot('view', $direccionEntrega)) {
        //     return response()->json(['message' => 'No autorizado'], JsonResponse::HTTP_FORBIDDEN);
        // }

        return response()->json(['data' => $direccionEntrega]);
    }

    /**
     * Actualiza la dirección de entrega especificada en la base de datos.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\DireccionEntrega  $direccionEntrega
     * @return \Illuminate\Http\JsonResponse
     */
    public function update(Request $request, DireccionEntrega $direccionEntrega): JsonResponse
    {
         // Opcional: Añadir autorización
        // if (auth()->user()->cannot('update', $direccionEntrega)) {
        //     return response()->json(['message' => 'No autorizado'], JsonResponse::HTTP_FORBIDDEN);
        // }

        $validatedData = $request->validate([
            'nombre' => ['sometimes', 'nullable', 'string', 'max:255'],
            'calle' => ['sometimes', 'required', 'string', 'max:255'],
            'numero_exterior' => ['sometimes', 'required', 'string', 'max:255'],
            'numero_interior' => ['sometimes', 'nullable', 'string', 'max:255'],
            'colonia' => ['sometimes', 'required', 'string', 'max:255'],
            'codigo_postal' => ['sometimes', 'required', 'string', 'max:10'],
            'ciudad' => ['sometimes', 'required', 'string', 'max:255'],
            'estado' => ['sometimes', 'required', 'string', 'max:255'],
            'pais' => ['sometimes', 'string', 'max:255'],
            'referencia' => ['sometimes', 'nullable', 'string'],
            'es_principal' => ['sometimes', 'required', Rule::in(['si', 'no'])],
            'estatus' => ['sometimes', 'required', Rule::in(['activo', 'inactivo'])],
        ], [
            'calle.required' => 'La calle es requerida',
            'numero_exterior.required' => 'El número exterior es requerido',
            'colonia.required' => 'La colonia es requerida',
            'codigo_postal.required' => 'El código postal es requerido',
            'ciudad.required' => 'La ciudad es requerida',
            'estado.required' => 'El estado es requerido',
            'es_principal.in' => 'El valor debe ser si o no',
            'estatus.in' => 'El estatus debe ser activo o inactivo',
        ]);

        try {
            DB::beginTransaction();

            if (isset($validatedData['es_principal']) && $validatedData['es_principal'] === 'si') {
                DireccionEntrega::where('cliente_id', $direccionEntrega->cliente_id)
                    ->where('id', '!=', $direccionEntrega->id)
                    ->where('es_principal', 'si')
                    ->update(['es_principal' => 'no']);
            }

            $direccionEntrega->update($validatedData);

            DB::commit();

            return response()->json([
                'data' => $direccionEntrega,
                'message' => 'Dirección actualizada exitosamente.'
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'message' => 'Error al actualizar la dirección.',
                'error' => $e->getMessage()
            ], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * Elimina la dirección de entrega especificada de la base de datos.
     *
     * @param  \App\Models\DireccionEntrega  $direccionEntrega
     * @return \Illuminate\Http\JsonResponse
     */
    public function destroy(DireccionEntrega $direccionEntrega): JsonResponse
    {
        // Prevenir eliminar la dirección principal si es la única activa
        if ($direccionEntrega->es_principal === 'si') {
            $otrasActivas = DireccionEntrega::where('cliente_id', $direccionEntrega->cliente_id)
                                           ->where('id', '!=', $direccionEntrega->id)
                                           ->where('estatus', 'activo')
                                           ->count();
            if ($otrasActivas === 0) {
                return response()->json(['message' => 'No se puede eliminar la única dirección principal activa.'], JsonResponse::HTTP_BAD_REQUEST);
            }
        }

        try {
            DB::beginTransaction();
            
            // Actualizar el estatus a inactivo
            $direccionEntrega->update(['estatus' => 'inactivo']);
            
            // Realizar el soft delete
            $direccionEntrega->delete();
            
            DB::commit();
            return response()->json(null, JsonResponse::HTTP_NO_CONTENT);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['message' => 'Error al eliminar la dirección.', 'error' => $e->getMessage()], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    public function getForSelect(Cliente $cliente): JsonResponse
    {
        $direcciones = DireccionEntrega::where('cliente_id', $cliente->id)
            ->where('estatus', 'activo')
            ->orderBy('es_principal', 'desc')
            ->get();
        return response()->json(['data' => $direcciones]);
    }
}