<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreClienteRequest;
use App\Http\Requests\UpdateClienteRequest;
use App\Models\Cliente;
use App\Models\ClienteCategoria;
use App\Support\CatalogDeletionGuard;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ClienteController extends Controller
{
    /**
     * Catálogo compartido (sin partición por usuario): todos los usuarios con permiso ven los mismos clientes.
     *
     * Cliente por defecto para POS (Cliente mostrador).
     */
    public function mostrador(): JsonResponse
    {
        $this->authorize('viewAny', Cliente::class);

        $cliente = Cliente::mostrador()->first();
        if (! $cliente) {
            return response()->json(['data' => null, 'meta' => null, 'errors' => null], 200);
        }

        return response()->json(['data' => $cliente, 'meta' => null, 'errors' => null], 200);
    }

    /**
     * Listado paginado (búsqueda opcional por nombre, email o teléfono).
     */
    public function index(Request $request): JsonResponse
    {
        $this->authorize('viewAny', Cliente::class);

        $perPage = min(100, max(1, (int) $request->get('per_page', 20)));

        $query = Cliente::query()->with('clienteCategoria:id,code,name,color,sort_order,is_active');
        $busqueda = $request->get('q');
        if ($busqueda && is_string($busqueda)) {
            $term = '%'.trim($busqueda).'%';
            $query->where(function ($q) use ($term): void {
                $q->where('nombre', 'like', $term)
                    ->orWhere('email', 'like', $term)
                    ->orWhere('telefono', 'like', $term);
            });
        }

        $categoriaId = $request->get('categoria_id');
        if ($categoriaId !== null && $categoriaId !== '') {
            $query->where('cliente_categoria_id', (int) $categoriaId);
        }

        return response()->json([
            'data' => $query->orderBy('nombre')->paginate($perPage),
            'meta' => [
                'categorias' => ClienteCategoria::query()
                    ->where('is_active', true)
                    ->orderBy('sort_order')
                    ->orderBy('name')
                    ->get(['id', 'code', 'name', 'color', 'sort_order']),
            ],
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    /**
     * Registro rápido de cliente (para POS).
     */
    public function store(StoreClienteRequest $request): JsonResponse
    {
        $cliente = Cliente::create($request->validated());
        $cliente->load('clienteCategoria:id,code,name,color,sort_order,is_active');

        return response()->json([
            'data' => $cliente,
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_CREATED);
    }

    /**
     * Detalle de un cliente.
     */
    public function show(Cliente $cliente): JsonResponse
    {
        $this->authorize('view', $cliente);
        $cliente->load('clienteCategoria:id,code,name,color,sort_order,is_active');

        return response()->json([
            'data' => $cliente,
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    /**
     * Actualizar cliente. El cliente mostrador no se puede editar.
     */
    public function update(UpdateClienteRequest $request, Cliente $cliente): JsonResponse
    {
        if ($cliente->isMostrador()) {
            return response()->json([
                'message' => 'El cliente mostrador no se puede editar.',
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        $data = $request->validated();
        unset($data['es_mostrador']);
        $cliente->update($data);

        return response()->json([
            'data' => $cliente->fresh()->load('clienteCategoria:id,code,name,color,sort_order,is_active'),
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    /**
     * Eliminar cliente. El cliente mostrador no se puede eliminar.
     */
    public function destroy(Cliente $cliente): JsonResponse
    {
        $this->authorize('delete', $cliente);

        if ($cliente->isMostrador()) {
            return response()->json([
                'message' => 'El cliente mostrador no se puede eliminar.',
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        $block = CatalogDeletionGuard::cliente($cliente);
        if ($block !== null) {
            return response()->json([
                'message' => $block,
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        $cliente->delete();

        return response()->json([
            'message' => 'Cliente eliminado correctamente.',
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }
}
