<?php

namespace App\Http\Controllers;

use App\Models\ProductVariant;
use App\Models\StockCode;
use App\Services\StockCodeInventoryService;
use Illuminate\Http\Request;
use RuntimeException;

class AdminStockCodeController extends Controller
{
    public function index(Request $request)
    {
        $status = $request->query('status', 'available');
        $productId = $request->integer('product');
        $query = trim((string) $request->query('q', ''));

        return view('admin.stock-codes.index', [
            'codes' => StockCode::query()
                ->with(['productVariant.game', 'importer'])
                ->when($status !== 'all', fn ($builder) => $builder->where('status', $status))
                ->when($productId > 0, fn ($builder) => $builder->where('product_variant_id', $productId))
                ->when($query !== '', fn ($builder) => $builder->where(function ($search) use ($query) {
                    $search->where('batch_reference', 'like', "%{$query}%")
                        ->orWhere('serial_number', 'like', "%{$query}%")
                        ->orWhereHas('productVariant', fn ($product) => $product
                            ->where('sku', 'like', "%{$query}%")
                            ->orWhere('name_ar', 'like', "%{$query}%"));
                }))
                ->latest()
                ->paginate(20)
                ->withQueryString(),
            'metrics' => [
                'available' => StockCode::where('status', 'available')->count(),
                'reserved' => StockCode::where('status', 'reserved')->count(),
                'sold' => StockCode::where('status', 'sold')->count(),
                'voided' => StockCode::where('status', 'voided')->count(),
                'expiringSoon' => StockCode::where('status', 'available')->whereNotNull('expires_at')->whereDate('expires_at', '<=', now()->addDays(14))->count(),
                'batches' => StockCode::whereNotNull('batch_reference')->distinct('batch_reference')->count('batch_reference'),
                'providerLinked' => StockCode::whereNotNull('provider_id')->count(),
                'availableCost' => StockCode::where('status', 'available')->sum('cost_minor'),
            ],
            'products' => ProductVariant::whereIn('delivery_method', ['stored_code', 'api', 'hybrid'])->orderBy('name_ar')->get(),
            'batchSummary' => StockCode::query()
                ->selectRaw("coalesce(batch_reference, 'بدون باتش') as batch, status, count(*) as total, sum(cost_minor) as cost_minor")
                ->groupBy('batch', 'status')
                ->orderByDesc('total')
                ->limit(18)
                ->get(),
            'status' => $status,
            'productId' => $productId,
            'query' => $query,
        ]);
    }

    public function create()
    {
        return view('admin.stock-codes.create', [
            'products' => ProductVariant::whereIn('delivery_method', ['stored_code', 'api', 'hybrid'])->orderBy('name_ar')->get(),
        ]);
    }

    public function store(Request $request, StockCodeInventoryService $inventory)
    {
        $data = $request->validate([
            'product_variant_id' => ['required', 'exists:product_variants,id'],
            'codes' => ['required', 'string'],
            'batch_reference' => ['nullable', 'string', 'max:120'],
            'serial_prefix' => ['nullable', 'string', 'max:80'],
            'cost_minor' => ['nullable', 'integer', 'min:0'],
            'currency_code' => ['required', 'string', 'size:3'],
            'expires_at' => ['nullable', 'date'],
            'import_note' => ['nullable', 'string', 'max:1000'],
        ]);

        $product = ProductVariant::findOrFail($data['product_variant_id']);

        try {
            $summary = $inventory->importCodes($product, $data['codes'], $data, $request->user());
        } catch (RuntimeException $exception) {
            return back()->withInput()->withErrors(['codes' => $exception->getMessage()]);
        }

        return redirect()
            ->route('admin.stock-codes.index', ['product' => $product->id])
            ->with('status', "تم استيراد {$summary['imported']} كود. تكرار داخل الملف: {$summary['duplicate_input']}، تكرار موجود: {$summary['duplicate_existing']}.");
    }

    public function show(StockCode $stockCode)
    {
        return view('admin.stock-codes.show', [
            'code' => $stockCode->load(['productVariant.game', 'reservedOrder', 'soldOrderItem', 'importer']),
        ]);
    }

    public function destroy(Request $request, StockCode $stockCode, StockCodeInventoryService $inventory)
    {
        $data = $request->validate([
            'note' => ['nullable', 'string', 'max:500'],
        ]);

        try {
            $inventory->void($stockCode, $request->user(), $data['note'] ?? null);
        } catch (RuntimeException $exception) {
            return back()->withErrors(['stock_code' => $exception->getMessage()]);
        }

        return back()->with('status', 'تم إلغاء الكود من المخزون المتاح.');
    }
}
