<?php

namespace App\Http\Requests\Admin;

use App\Models\Product;
use App\Models\StockAdjustment;
use App\Services\LocationInventoryService;
use Illuminate\Foundation\Http\FormRequest;

class StoreManualAdjustmentRequest extends FormRequest
{
    public static function reasonOptions(): array
    {
        return [
            'Damaged' => 'Damaged',
            'Found' => 'Found',
            'Correction' => 'Correction',
            'Return' => 'Return',
            'Stock audit' => 'Stock audit',
            'Other' => 'Other',
        ];
    }

    public function authorize(): bool
    {
        return auth()->user()?->can('stock-adjustments.manage') ?? false;
    }

    protected function prepareForValidation(): void
    {
        $selector = $this->input('product_selector');
        if (! is_string($selector) || $selector === '') {
            return;
        }

        if (str_starts_with($selector, 'single:')) {
            $id = (int) substr($selector, strlen('single:'));
            if ($id > 0) {
                $this->merge(['product_id' => $id, 'variant_id' => null]);
            }

            return;
        }

        if (str_starts_with($selector, 'parent:')) {
            $id = (int) substr($selector, strlen('parent:'));
            if ($id > 0) {
                $this->merge(['product_id' => $id]);
            }

            return;
        }

        if (str_starts_with($selector, 'variant:')) {
            $variantId = (int) substr($selector, strlen('variant:'));
            if ($variantId <= 0) {
                return;
            }
            $variant = Product::query()->find($variantId);
            if ($variant && $variant->parent_id) {
                $this->merge([
                    'product_id' => (int) $variant->parent_id,
                    'variant_id' => $variantId,
                ]);
            }
        }
    }

    public function rules(): array
    {
        $productId = $this->input('product_id');
        $product = $productId ? Product::find($productId) : null;
        $variantRequired = $product && $product->isVariantParent();
        $locationInventory = app(LocationInventoryService::class);
        $locationRule = $locationInventory->useLocationInventory()
            ? ['required', 'exists:locations,id']
            : ['nullable', 'exists:locations,id'];

        return [
            'product_id' => ['required', 'exists:products,id'],
            'variant_id' => $variantRequired ? ['required', 'exists:products,id'] : ['nullable', 'exists:products,id'],
            'location_id' => $locationRule,
            'adjustment_type' => ['required', 'in:addition,subtraction'],
            'quantity' => ['required', 'numeric', 'min:0.01'],
            'reason' => ['required', 'string', 'in:' . implode(',', array_keys(self::reasonOptions()))],
            'remarks' => ['required', 'string', 'min:10'],
        ];
    }

    public function withValidator($validator): void
    {
        $validator->after(function ($validator) {
            if ($this->adjustment_type !== StockAdjustment::TYPE_SUBTRACTION) {
                return;
            }
            $productId = $this->variant_id ?? $this->product_id;
            $locationInventory = app(LocationInventoryService::class);
            if ($locationInventory->useLocationInventory() && $this->location_id) {
                $available = $locationInventory->getOnHand((int) $productId, (int) $this->location_id);
                if ($available < (float) $this->quantity) {
                    $validator->errors()->add('quantity', 'Subtraction cannot exceed on-hand at location (' . $available . ').');
                }
                return;
            }
            $product = Product::find($productId);
            if ($product && $product->current_stock < (float) $this->quantity) {
                $validator->errors()->add('quantity', 'Subtraction cannot exceed current stock (' . $product->current_stock . ').');
            }
        });
    }
}
