<?php

namespace App\Http\Controllers\Admin;

use App\Models\Item;
use App\Models\Purchase;
use Illuminate\Http\Request;
use App\Scopes\StoreScope;
use App\Models\Store;
use Brian2694\Toastr\Facades\Toastr;
use App\Http\Controllers\Controller;
use App\Services\Purchase\PurchaseService;
use Illuminate\Support\Facades\Validator;

class PurchaseController extends Controller
{
    public function __construct(private readonly PurchaseService $purchaseService)
    {
    }

    public function index(Request $request)
    {
        $purchases = Purchase::with(['items.item.store', 'store', 'createdByAdmin'])
            ->when(config('module.current_module_id'), function ($query) {
                $query->where('module_id', config('module.current_module_id'));
            })
            ->when($request->search, function ($query) use ($request) {
                $key = trim($request->search);
                $query->where(function ($subQuery) use ($key) {
                    $subQuery->where('purchase_no', 'like', "%{$key}%")
                        ->orWhere('supplier_name', 'like', "%{$key}%")
                        ->orWhere('invoice_number', 'like', "%{$key}%")
                        ->orWhereHas('items', function ($itemQuery) use ($key) {
                            $itemQuery->where('item_name', 'like', "%{$key}%");
                        });
                });
            })
            ->when($request->filled('from') && $request->filled('to'), function ($query) use ($request) {
                $query->whereBetween('purchase_date', [$request->from, $request->to]);
            })
            ->latest('purchase_date')
            ->latest('id')
            ->paginate(config('default_pagination'))
            ->withQueryString();

        return view('admin-views.purchase.index', compact('purchases'));
    }

    public function create()
    {
        return view('admin-views.purchase.create');
    }

    public function store(Request $request)
    {
        if (! $request->filled('items') && $request->filled('item_id')) {
            $request->merge([
                'items' => [[
                    'item_id' => $request->input('item_id'),
                    'variation_type' => $request->input('variation_type'),
                    'quantity' => $request->input('quantity'),
                    'purchase_price' => $request->input('purchase_price'),
                ]],
            ]);
        }

        Validator::make($request->all(), [
            'items' => 'required|array|min:1',
            'items.*.item_id' => 'required|integer|exists:items,id',
            'items.*.variation_type' => 'nullable|string|max:191',
            'items.*.quantity' => 'required|integer|min:1',
            'items.*.purchase_price' => 'required|numeric|min:0',
            'purchase_date' => 'required|date',
            'supplier_name' => 'nullable|string|max:191',
            'invoice_number' => 'nullable|string|max:191',
            'note' => 'nullable|string',
        ])->validate();

        $this->purchaseService->create($request->all(), auth('admin')->id());

        Toastr::success(translate('Purchase entry saved and stock updated successfully.'));
        return redirect()->route('admin.purchase.index');
    }

    public function searchItems(Request $request)
    {
        $items = Item::withoutGlobalScope(StoreScope::class)
            ->with('store')
            ->when(config('module.current_module_id'), function ($query) {
                $query->where('module_id', config('module.current_module_id'));
            })
            ->when($request->q, function ($query) use ($request) {
                $search = trim($request->q);
                $query->where('name', 'like', "%{$search}%");
            })
            ->latest()
            ->limit(50)
            ->get()
            ->map(function ($item) {
                return [
                    'id' => $item->id,
                    'text' => $item->name . ($item->store ? ' (' . $item->store->name . ')' : ''),
                ];
            })
            ->values();

        return response()->json($items);
    }

    public function itemMeta(Request $request)
    {
        $request->validate([
            'item_id' => 'required|integer|exists:items,id',
        ]);

        $item = Item::withoutGlobalScope(StoreScope::class)->with('store')->findOrFail($request->item_id);
        $variations = is_array($item->variations) ? $item->variations : json_decode($item->variations ?? '[]', true);
        $variations = is_array($variations) ? array_values(array_filter($variations, fn ($variation) => ! blank($variation['type'] ?? null))) : [];

        return response()->json([
            'id' => $item->id,
            'name' => $item->name,
            'current_stock' => (int) ($item->stock ?? 0),
            'store_name' => $item->store?->name,
            'has_variations' => count($variations) > 0,
            'variations' => collect($variations)->map(function ($variation) {
                return [
                    'type' => $variation['type'],
                    'stock' => (int) ($variation['stock'] ?? 0),
                ];
            })->values(),
        ]);
    }
}
