<?php

namespace App\Http\Controllers\Mall;

use App\Http\Controllers\Controller;
use App\Models\Mall\MallStorage;
use App\Models\Game\Player\ItemProto;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;

class DistributionController extends Controller
{
    /**
     * Show distribution interface
     *
     * @return View
     */
    public function index(): View
    {
        $user = Auth::user();

        // Get grouped items from storage
        $groupedItems = MallStorage::getGroupedItems($user->id);

        // Manually load item protos since grouped items are partial models
        $vnums = $groupedItems->pluck('vnum')->unique();
        $protos = ItemProto::whereIn('vnum', $vnums)->get()->keyBy('vnum');

        // Attach proto to each item
        foreach ($groupedItems as $item) {
            $item->proto = $protos->get($item->vnum);
        }

        return view('mall/distribution', [
            'groupedItems' => $groupedItems,
            'totalItems' => $groupedItems->count(),
        ]);
    }

    /**
     * Distribute items from mall_storage to item_award
     *
     * @param Request $request
     * @return RedirectResponse
     */
    public function distribute(Request $request): RedirectResponse
    {
        $user = Auth::user();

        // Validate the request
        $validated = $request->validate([
            'distributions' => 'required|array',
            'distributions.*.sample_id' => 'required|integer',
            'distributions.*.quantity' => 'required|integer|min:1',
        ]);

        DB::beginTransaction();

        try {
            $distributedCount = 0;

            foreach ($validated['distributions'] as $distribution) {
                $sampleId = $distribution['sample_id'];
                $quantityToDistribute = $distribution['quantity'];

                // Get all storage items with matching vnum and sockets
                $sampleItem = MallStorage::where('id', $sampleId)
                    ->where('owner_id', $user->id)
                    ->firstOrFail();

                // Find all matching items (same vnum, sockets, attributes)
                $matchingItems = MallStorage::where('owner_id', $user->id)
                    ->where('vnum', $sampleItem->vnum)
                    ->where('socket0', $sampleItem->socket0)
                    ->where('socket1', $sampleItem->socket1)
                    ->where('socket2', $sampleItem->socket2)
                    ->where('socket3', $sampleItem->socket3)
                    ->where('socket4', $sampleItem->socket4)
                    ->where('socket5', $sampleItem->socket5)
                    ->orderBy('id')
                    ->get();

                $remainingToDistribute = $quantityToDistribute;

                foreach ($matchingItems as $item) {
                    if ($remainingToDistribute <= 0) {
                        break;
                    }

                    if ($item->count <= $remainingToDistribute) {
                        // Distribute entire stack
                        $this->createItemAward($user, $item, $item->count);
                        $remainingToDistribute -= $item->count;
                        $distributedCount += $item->count;
                        $item->delete();
                    } else {
                        // Distribute partial stack
                        $this->createItemAward($user, $item, $remainingToDistribute);
                        $item->count -= $remainingToDistribute;
                        $item->save();
                        $distributedCount += $remainingToDistribute;
                        $remainingToDistribute = 0;
                    }
                }

                if ($remainingToDistribute > 0) {
                    DB::rollback();
                    Log::warning("Attempted to distribute more items than available. User ID: {$user->id}, Sample ID: {$sampleId}");
                    return redirect()->route('mall.distribution')->with('error', 'Cannot distribute more items than you have in storage.');
                }
            }

            DB::commit();

            return redirect()->route('mall.distribution')->with('success', "Successfully distributed {$distributedCount} items! They will be delivered to your characters shortly.");

        } catch (\Exception $e) {
            DB::rollback();
            Log::error('Distribution failed: ' . $e->getMessage());
            Log::error('Stack trace: ' . $e->getTraceAsString());

            return redirect()->route('mall.distribution')->with('error', 'Distribution failed. Please try again.');
        }
    }

    /**
     * Create an item_award record
     *
     * @param $user
     * @param MallStorage $storageItem
     * @param int $count
     * @return void
     */
    private function createItemAward($user, MallStorage $storageItem, int $count): void
    {
        DB::connection('player')->table('item_award')->insert([
            'pid' => 0,  // 0 means not assigned to specific character yet
            'login' => $user->login,
            'vnum' => $storageItem->vnum,
            'count' => $count,
            'given_time' => now(),
            'taken_time' => null,
            'item_id' => null,
            'why' => 'Mall purchase distribution',
            'socket0' => $storageItem->socket0,
            'socket1' => $storageItem->socket1,
            'socket2' => $storageItem->socket2,
            'attrtype0' => $storageItem->attrtype0,
            'attrvalue0' => $storageItem->attrvalue0,
            'attrtype1' => $storageItem->attrtype1,
            'attrvalue1' => $storageItem->attrvalue1,
            'attrtype2' => $storageItem->attrtype2,
            'attrvalue2' => $storageItem->attrvalue2,
            'attrtype3' => $storageItem->attrtype3,
            'attrvalue3' => $storageItem->attrvalue3,
            'attrtype4' => $storageItem->attrtype4,
            'attrvalue4' => $storageItem->attrvalue4,
            'attrtype5' => $storageItem->attrtype5,
            'attrvalue5' => $storageItem->attrvalue5,
            'attrtype6' => $storageItem->attrtype6,
            'attrvalue6' => $storageItem->attrvalue6,
            'mall' => 1,  // This is a mall item
        ]);

        Log::info("Created item_award for user {$user->login}: vnum={$storageItem->vnum}, count={$count}");
    }
}
