<?php

namespace App\Support;

use App\Models\Area;
use App\Models\Cliente;
use App\Models\ClienteCategoria;
use App\Models\Etapa;
use App\Models\GarmentType;
use App\Models\InventoryProduct;
use App\Models\LaundryPiecePrice;
use App\Models\LaundrySaleCategory;
use App\Models\LaundrySaleProduct;
use App\Models\LaundrySaleProductServicePrice;
use App\Models\OrdenLavanderiaDetalle;
use App\Models\Producto;
use App\Models\TipoServicio;
use App\Models\User;

/**
 * Valida si un registro de catálogo puede eliminarse (sin referencias en uso).
 * Devuelve mensaje de error o null si puede borrarse.
 */
final class CatalogDeletionGuard
{
    public static function laundrySaleCategory(LaundrySaleCategory $category): ?string
    {
        if ($category->products()->exists()) {
            return 'No se puede eliminar: la categoría tiene artículos del catálogo POS asociados.';
        }

        return null;
    }

    public static function laundrySaleProduct(LaundrySaleProduct $product): ?string
    {
        if ($product->ordenLavanderiaDetalles()->exists()) {
            return 'No se puede eliminar: el artículo aparece en órdenes de venta.';
        }

        return null;
    }

    public static function garmentType(GarmentType $garmentType): ?string
    {
        if ($garmentType->ordenLavanderiaDetalles()->exists()) {
            return 'No se puede eliminar: el tipo de prenda aparece en ventas.';
        }
        if (LaundryPiecePrice::query()->where('garment_type_id', $garmentType->id)->exists()) {
            return 'No se puede eliminar: hay precios por pieza configurados para este tipo de prenda.';
        }

        return null;
    }

    public static function area(Area $area): ?string
    {
        if ($area->orderAreaPresences()->exists()) {
            return 'No se puede eliminar: el área tiene presencias de órdenes registradas.';
        }
        if ($area->orderAreaScanEvents()->exists()) {
            return 'No se puede eliminar: el área tiene escaneos registrados.';
        }
        if (User::query()->where('area_id', $area->id)->exists()) {
            return 'No se puede eliminar: hay usuarios asignados a esta área.';
        }

        return null;
    }

    public static function etapa(Etapa $etapa): ?string
    {
        if (OrdenLavanderiaDetalle::query()->where('etapa_id', $etapa->id)->exists()) {
            return 'No se puede eliminar: la etapa aparece en líneas de venta.';
        }
        if (LaundrySaleProduct::query()->where('default_etapa_id', $etapa->id)->exists()) {
            return 'No se puede eliminar: hay artículos POS con esta etapa por defecto.';
        }
        if (LaundrySaleProductServicePrice::query()->where('etapa_id', $etapa->id)->exists()) {
            return 'No se puede eliminar: hay precios por etapa en artículos del catálogo POS.';
        }
        if (LaundryPiecePrice::query()->where('etapa_id', $etapa->id)->exists()) {
            return 'No se puede eliminar: hay precios por pieza asociados a esta etapa.';
        }

        return null;
    }

    public static function tipoServicio(TipoServicio $tipo): ?string
    {
        if ($tipo->ordenesLavanderia()->exists()) {
            return 'No se puede eliminar: el tipo de servicio aparece en órdenes de venta.';
        }
        if (LaundrySaleProduct::query()->where('default_tipo_servicio_id', $tipo->id)->exists()) {
            return 'No se puede eliminar: hay artículos POS con este tipo de servicio por defecto.';
        }

        return null;
    }

    public static function inventoryProduct(InventoryProduct $product): ?string
    {
        if ($product->movements()->exists()) {
            return 'No se puede eliminar: el producto tiene movimientos de inventario.';
        }
        if ($product->inventoryTransferLines()->exists()) {
            return 'No se puede eliminar: el producto aparece en traspasos de inventario.';
        }
        if (LaundrySaleProduct::query()->where('inventory_product_id', $product->id)->exists()) {
            return 'No se puede eliminar: el producto está enlazado al catálogo POS de venta.';
        }

        return null;
    }

    public static function cliente(Cliente $cliente): ?string
    {
        if ($cliente->ordenesLavanderia()->exists()) {
            return 'No se puede eliminar: el cliente tiene órdenes de venta asociadas.';
        }

        return null;
    }

    public static function clienteCategoria(ClienteCategoria $categoria): ?string
    {
        if ($categoria->clientes()->exists()) {
            return 'No se puede eliminar: la clasificación tiene clientes asignados.';
        }

        return null;
    }

    public static function productoLegacy(Producto $producto): ?string
    {
        if ($producto->detallesOrden()->exists()) {
            return 'No se puede eliminar: tiene ventas asociadas.';
        }

        return null;
    }
}
