<?php

namespace App\Http\Controllers\Admin\Branch\Bagging;

use App\Http\Controllers\Controller;
use App\Models\Bag;
use App\Models\BagItem;
use App\Models\Parcel;
use App\Models\Rider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class ManageBaggingController extends Controller
{
    /**
     * Show bagging page.
     */
    public function index(Request $request)
    {
        $bagId = $request->get('bag_id');
        $bags = Bag::withCount('items')->orderByDesc('id')->limit(50)->get();
        $currentBag = $bagId ? Bag::with(['items.parcel', 'rider'])->find($bagId) : Bag::with(['items.parcel', 'rider'])->where('status', 'open')->orderByDesc('id')->first();
        $riders = Rider::orderBy('name')->get();

        return view('admin.branch.bagging.index', [
            'bags' => $bags,
            'currentBag' => $currentBag,
            'riders' => $riders,
        ]);
    }

    /**
     * Create a new bag (optionally assign rider now).
     */
    public function create(Request $request)
    {
        $data = $request->validate([
            'rider_id' => 'nullable|exists:riders,id',
        ]);

        $bag = Bag::create([
            'bag_number' => $this->generateBagNumber(),
            'status' => 'open',
            'rider_id' => $data['rider_id'] ?? null,
        ]);

        return redirect()->route('admin.branch.bagging', ['bag_id' => $bag->id])->with('success', 'Bag created.');
    }

    /**
     * Add a parcel to a bag by tracking id.
     */
    public function addItem(Request $request)
    {
        $data = $request->validate([
            'bag_id' => 'required|exists:bags,id',
            'tracking_id' => 'required|string',
        ]);

        $bag = Bag::findOrFail($data['bag_id']);
        if ($bag->status !== 'open') {
            return back()->withErrors(['bag_id' => 'Bag must be open to add items.']);
        }

        $parcel = Parcel::where('tracking_id', $data['tracking_id'])->first();
        if (!$parcel) {
            return back()->withErrors(['tracking_id' => 'Tracking ID not found.']);
        }

        $exists = BagItem::where('bag_id', $bag->id)->where('parcel_id', $parcel->id)->exists();
        if ($exists) {
            return back()->withErrors(['tracking_id' => 'Parcel already in this bag.']);
        }

        DB::transaction(function () use ($bag, $parcel) {
            BagItem::create([
                'bag_id' => $bag->id,
                'parcel_id' => $parcel->id,
            ]);
            $parcel->update(['status' => 'Bagged', 'is_scanned' => true]);
        });

        return back()->with('success', "Added {$parcel->tracking_id} to bag #{$bag->bag_number}.");
    }

    /**
     * Remove item from bag.
     */
    public function removeItem(Bag $bag, BagItem $item)
    {
        if ($bag->id !== $item->bag_id) {
            abort(404);
        }
        $item->delete();
        return back()->with('success', 'Removed parcel from bag.');
    }

    /**
     * Seal an open bag.
     */
    public function seal(Bag $bag)
    {
        if ($bag->status !== 'open') {
            return back()->withErrors(['bag' => 'Only open bags can be sealed.']);
        }
        $bag->update(['status' => 'sealed']);
        return back()->with('success', 'Bag sealed.');
    }

    /**
     * Print manifest for the bag (reuses branch manifest view).
     */
    public function manifest(Bag $bag)
    {
        $parcels = Parcel::with('rider', 'seller')
            ->whereIn('id', $bag->items()->pluck('parcel_id'))
            ->get();
        return view('admin.branch.manifest', compact('parcels'));
    }

    private function generateBagNumber(): string
    {
        do {
            $num = 'BAG' . mt_rand(100000, 999999);
        } while (Bag::where('bag_number', $num)->exists());
        return $num;
    }
}
