<?php

namespace App\Http\Controllers\Franchise;

use App\Http\Controllers\Controller;
use App\Models\Franchise;
use App\Models\FranchiseStockRequest;
use App\Models\FranchiseStockRequestItem;
use App\Models\Product;
use App\Services\FranchiseStockService;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class StockRequestController extends Controller
{
    public function index(): View
    {
        $franchise = Franchise::query()->where('created_by', auth()->id())->first();
        $requests = FranchiseStockRequest::query()
            ->where('franchise_id', $franchise?->id)
            ->latest('id')
            ->with('items.product')
            ->paginate(15);

        $products = Product::query()->where('is_active', true)->orderBy('name')->get();

        return view('franchise.stock-requests', compact('franchise', 'requests', 'products'));
    }

    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'product_id' => ['required', 'array'],
            'product_id.*' => ['required', 'exists:products,id'],
            'quantity' => ['required', 'array'],
            'quantity.*' => ['required', 'numeric', 'min:0.01'],
            'notes' => ['nullable', 'string', 'max:500'],
        ]);

        $franchise = Franchise::query()->where('created_by', auth()->id())->first();
        if (! $franchise) {
            return back()->withErrors(['franchise' => 'Franchise not found.']);
        }

        $requestNo = 'REQ'.Str::upper(Str::random(8));
        $stockRequest = FranchiseStockRequest::query()->create([
            'franchise_id' => $franchise->id,
            'request_number' => $requestNo,
            'status' => 'pending',
            'requested_at' => now(),
            'notes' => $validated['notes'] ?? null,
        ]);

        foreach ($validated['product_id'] as $index => $productId) {
            FranchiseStockRequestItem::query()->create([
                'request_id' => $stockRequest->id,
                'product_id' => (int) $productId,
                'quantity_requested' => (float) ($validated['quantity'][$index] ?? 0),
                'quantity_delivered' => 0,
            ]);
        }

        return back()->with('status', 'Stock request submitted.');
    }

    public function confirmDelivered(int $requestId, FranchiseStockService $stockService): RedirectResponse
    {
        $franchise = Franchise::query()->where('created_by', auth()->id())->first();
        $stockRequest = FranchiseStockRequest::query()->where('franchise_id', $franchise?->id)->whereKey($requestId)->with('items.product')->first();
        if (! $stockRequest) {
            return back()->withErrors(['request' => 'Request not found.']);
        }
        if ($stockRequest->status === 'delivered') {
            return back()->withErrors(['request' => 'Request already delivered.']);
        }

        $stockRequest->status = 'delivered';
        $stockRequest->delivered_at = now();
        $stockRequest->save();

        $items = [];
        foreach ($stockRequest->items as $item) {
            $items[] = [
                'product_id' => $item->product_id,
                'quantity' => (float) $item->quantity_requested,
                'unit_price' => (float) ($item->product?->dp_price ?? 0),
                'unit_bv' => (float) ($item->product?->bv ?? 0),
            ];
            $item->quantity_delivered = $item->quantity_requested;
            $item->save();
        }

        $stockService->receiveStockRequest($franchise->id, $items, [
            'reference' => $stockRequest->request_number,
            'created_by' => auth()->id(),
        ]);

        return back()->with('status', 'Stock marked as delivered and added to inventory.');
    }
}

