<?php

namespace Modules\WMSInventoryCore\App\Services;

use App\Services\Settings\ModuleSettingsService;
use Modules\SystemCore\App\Models\CoreProduct;

class WMSInventoryCoreSettingsService
{
    private const MODULE = 'WMSInventoryCore';

    /**
     * Get a module setting value using the ModuleSettingsService
     */
    private static function getSetting(string $key, mixed $default = null): mixed
    {
        return app(ModuleSettingsService::class)->get(self::MODULE, $key, $default);
    }

    /**
     * Product Management Settings
     */
    public static function isAutoGenerateSku(): bool
    {
        return (bool) self::getSetting('auto_generate_sku', true);
    }

    public static function getSkuPrefix(): string
    {
        return (string) self::getSetting('sku_prefix', 'PRD');
    }

    public static function requireProductImages(): bool
    {
        return (bool) self::getSetting('require_product_images', false);
    }

    public static function allowNegativeStock(): bool
    {
        return (bool) self::getSetting('allow_negative_stock', false);
    }

    /**
     * Stock Tracking Settings
     */
    public static function getDefaultStockMethod(): string
    {
        return (string) self::getSetting('default_stock_method', 'fifo');
    }

    public static function enableBatchTracking(): bool
    {
        return (bool) self::getSetting('enable_batch_tracking', false);
    }

    public static function enableSerialTracking(): bool
    {
        return (bool) self::getSetting('enable_serial_tracking', false);
    }

    public static function enableExpiryTracking(): bool
    {
        return (bool) self::getSetting('enable_expiry_tracking', false);
    }

    /**
     * Warehouse Operations Settings
     */
    public static function getDefaultWarehouseId(): ?int
    {
        $id = self::getSetting('default_warehouse_id', null);

        return $id ? (int) $id : null;
    }

    public static function enableMultiLocation(): bool
    {
        return (bool) self::getSetting('enable_multi_location', false);
    }

    public static function requireLocationForStock(): bool
    {
        return (bool) self::getSetting('require_location_for_stock', false);
    }

    public static function autoCreateBins(): bool
    {
        return (bool) self::getSetting('auto_create_bins', true);
    }

    /**
     * Inventory Alerts Settings
     */
    public static function enableLowStockAlerts(): bool
    {
        return (bool) self::getSetting('enable_low_stock_alerts', true);
    }

    public static function enableExpiryAlerts(): bool
    {
        return (bool) self::getSetting('enable_expiry_alerts', true);
    }

    public static function getExpiryAlertDays(): int
    {
        return (int) self::getSetting('expiry_alert_days', 30);
    }

    /**
     * Adjustments Settings
     */
    public static function requireApprovalForAdjustments(): bool
    {
        return (bool) self::getSetting('require_approval_for_adjustments', true);
    }

    public static function requireReasonForAdjustments(): bool
    {
        return (bool) self::getSetting('require_reason_for_adjustments', true);
    }

    /**
     * Transfers Settings
     */
    public static function requireApprovalForTransfers(): bool
    {
        return (bool) self::getSetting('require_approval_for_transfers', false);
    }

    public static function autoReceiveTransfers(): bool
    {
        return (bool) self::getSetting('auto_receive_transfers', false);
    }

    public static function enableInTransitTracking(): bool
    {
        return (bool) self::getSetting('enable_in_transit_tracking', true);
    }

    /**
     * Generate next SKU based on settings
     */
    public static function generateNextSku(): string
    {
        $prefix = self::getSkuPrefix();
        $lastProduct = CoreProduct::where('sku', 'like', $prefix.'%')
            ->orderByRaw('LENGTH(sku) DESC')
            ->orderBy('sku', 'desc')
            ->first();

        if ($lastProduct && preg_match('/^'.preg_quote($prefix).'(\d+)$/', $lastProduct->sku, $matches)) {
            $nextNumber = (int) $matches[1] + 1;
        } else {
            $nextNumber = 1;
        }

        return $prefix.str_pad($nextNumber, 4, '0', STR_PAD_LEFT);
    }
}
