<?php

namespace App\Http\Controllers\Admin;

use App\Enums\BasicUnitEnum;
use App\Enums\ProductUnitEnum;
use App\Http\Controllers\Controller;
use App\Models\Producer;
use App\Models\Product;
use App\Models\ProductGroup;
use App\Models\ProfitCenter;
use App\Models\Supplier;
use App\Services\ProductService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class ProductController extends Controller
{
    protected ProductService $service;

    private bool $testMode = false;

    public function __construct(ProductService $service)
    {
        $this->service = $service;
    }

    /**
     * Display a listing of the resource.
     */
    public function index(): View
    {

        $suppliers = Supplier::orderBy('name')->get(['id', 'name'])->toArray();
        $profitCenters = ProfitCenter::orderBy('name')->get(['id', 'name'])->toArray();
        $productGroups = ProductGroup::orderBy('name')->get(['id', 'name'])->toArray();
        $producer = Producer::orderBy('name')->get(['id', 'name'])->toArray();
        DB::statement("SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));");
        $hooreycaNames = Product::orderBy('buyerProductName')->where('buyerProductName', '!=', '')->groupBy('buyerProductName')->get(['id', 'buyerProductName as name'])->toArray();
        DB::statement("SET sql_mode=(SELECT CONCAT(@@sql_mode, ',ONLY_FULL_GROUP_BY'));");
        // dd($hooreycaNames);
        // dd(json_encode($service->getAvailableFilters()));

        return view('admin.product.index')->with(
            [
                'suppliers' => $suppliers,
                'profitCenters' => $profitCenters,
                'productGroups' => $productGroups,
                'producer' => $producer,
                'hooreycaNames' => $hooreycaNames,
                'testMode' => $this->testMode,
                'init' => (bool) \request()->get('init', true),
                //                'formUUID'=>\Str::uuid(),
                //                'availableFilters'=>json_encode(['Product'=>['suppliers','date','dateFrom','dateTo','productGroups','products','hooreycaNames','producers']]),
                'availableFilters'=>json_encode(['Product'=>['suppliers','productGroups','products','hooreycaNames','producers','specialOffer']]),
            ]

        );
        $retData = [];
        // $retData['testMode']=($this->testMode)?'true':'false';
        $retData['testMode'] = $this->testMode;
        $retData['init'] = (bool) \request()->get('init', true);

        return view('admin.product.index')->with($retData);
        /*
        $ProductGroup=new \App\Models\ProductGroup();
        $productGroupArray=$ProductGroup->allWithParents(2);

        return view('admin.product.edit')->with(
            ['productGroup'=>$productGroupArray,
            'productUnit'=>ProductUnitEnum::getValues(),
             'producer'=>[
                 ['id'=>11,'name'=>'Voyagex'],
                 ['id'=>12,'name'=>'Győri előre'],
                 ['id'=>13,'name'=>'Elmar'],
                 ['id'=>14,'name'=>'Gramellini'],
             ]
            ]);
        */
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create(): Response|JsonResponse
    {
        return response()->noContent();
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request): Response|JsonResponse
    {
        $ret = ['status' => 'ok', 'message' => 'Product save successfully!'];

        return \response()->json($ret);
        // return \response(json_encode(['status'=>'ok','message'=>'Product save successfully!']),200);
    }

    /**
     * Display the specified resource.
     */
    public function show(int $ProductId): Response|JsonResponse
    {
        return response('ez show');
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $ProductId
     */
    public function prof_flag($str)
    {
        global $prof_timing, $prof_names;
        $prof_timing[] = microtime(true);
        $prof_names[] = $str;
    }

    // Call this when you're done and want to see the results
    public function prof_print()
    {
        global $prof_timing, $prof_names;
        $size = count($prof_timing);
        if ($size == 0) {
            return;
        }
        for ($i = 0; $i < $size - 1; $i++) {
            echo "<b>{$prof_names[$i]}</b><br>";
            echo sprintf('&nbsp;&nbsp;&nbsp;%f<br>', $prof_timing[$i + 1] - $prof_timing[$i]);
        }
        echo "<b>{$prof_names[$size - 1]}</b><br>";
    }

    public function edit(int $ProductId): View
    {
        // $this->prof_flag('Start');
        $ProductGroup = new \App\Models\ProductGroup;
        // @todo:too slow, change other methode
        $productGroupArray = $ProductGroup->allWithParents(3);

        $Product = Product::with(['Supplier', 'Producer', 'ProductGroup', 'picture', 'specification'])->find($ProductId);
        $Product->setAttributePrice();
        // $this->prof_flag(__LINE__);
        $Producer = [];
        foreach (Producer::orderBy('name')->get() as $producer) {
            $Producer[] = ['id' => $producer->id, 'name' => $producer->name];
        }
        // $this->prof_flag(__LINE__);
        if (! \request()->ajax()) {
            // $this->prof_print();
            dd($productGroupArray, $Product, $Product->toArray());
        }
        //

        return view('admin.product.edit')->with(
            ['Product' => $Product,
                'productGroup' => $productGroupArray,
                'productUnit' => BasicUnitEnum::getValues(),
                'sellerUnit' => ProductUnitEnum::getValues(),
                // 'productUnit'=>ProductUnitEnum::getValues(),
                'producer' => $Producer,
            ]);

    }

    /**
     * Update the specified resource in storage.
     *
     */
    public function update(Request $request, int $ProductId): Response|JsonResponse
    {
        // $Product=Product::with(['Supplier','Producer','ProductGroup','picture','specification'])->find($ProductId);
        // dd($request->all(),$ProductId);
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'supplierId' => 'required|integer|exists:suppliers,id',
            'producer' => 'required|exists:producers,id',
            'packaging' => 'required|numeric|min:0',
            'unitValue' => 'required|numeric|min:0',
            'productUnit' => 'required|string|in:'.implode(',', BasicUnitEnum::getValues()),
            'sellerUnit' => 'required|string|in:'.implode(',', ProductUnitEnum::getValues()),
            'unitMultiplier' => 'required|numeric|min:0',
            'amountUnit' => 'required|string|in:'.implode(',', ProductUnitEnum::getValues()),
            'vat' => 'required|numeric|min:0',
            'supplierProductNumber' => 'nullable|string|max:255',
            'buyerProductName'=>'required|string|max:255',
            'productGroup' => 'required|exists:product_groups,id',
            'hooreycaId' => 'nullable|string|max:255',
            'HooreycaUnit' => 'nullable|string|max:255',
            'HooreycaMultiplier' => 'nullable|numeric|min:0',
            'note' => 'nullable|string',
            'canSee' => 'boolean',
            'krel' => 'boolean',
            'specialOffer' => 'boolean',
            'price' => 'required|numeric|min:0',
        ]);
        // $request->merge(['canSee'=>$request->has('canSee')]);
        // $request->merge(['krel'=>$request->has('krel')]);
        // $request->merge(['specialOffer'=>$request->has('specialOffer')]);
        $validated['producer_id'] = $validated['producer'][0];
        unset($validated['producer']);
        $validated['product_group_id'] = $validated['productGroup'][0];
        unset($validated['productGroup']);
        $validated['note'] = str_replace("\r\n", "\n", $validated['note']);
        // dd($validated,$request->all());
        $ret = [];
        if (! $this->service->update($ProductId, $validated)) {
            if ($this->service->hasError()) {
                $ret['success'] = false;
                $ret['errors'] = $this->service->getError();
            }

            return \response()->json($ret)->setStatusCode(422);
        }

        if (! $this->service->updatePrice($ProductId, $validated['price'])) {
            if ($this->service->hasError()) {
                $ret['success'] = false;
                $ret['errors'] = $this->service->getError();
            }

            return \response()->json($ret)->setStatusCode(422);
        }

        /**@todo: save picture, specification, price
         *  save picture
         *  save specification
        */

        $ret = ['status' => 'ok', 'message' => 'Product save successfully!'];
        $ret['success'] = true;

        return \response()->json($ret);

    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(int $ProductId): Response|JsonResponse
    {
        //
        return response()->noContent();
    }

    public function getDataTableContent(Request $request): JsonResponse
    {

        $searchParameter = json_decode($request->input('ajaxData'), true);

        $Product = Product::with(['Supplier', 'Producer', 'ProductGroup']);
        if ($request->input('search.value')) {
            $Product->where('name', 'like', '%'.$request->input('search.value').'%');

        }

        if (isset($searchParameter['products[]'])) {
            if (! is_array($searchParameter['products[]'])) {
                $searchParameter['products[]'] = [$searchParameter['products[]']];
            }

            $Product->whereIn('name', $searchParameter['products[]']);
        }

        if (isset($searchParameter['hooreycaNames[]'])) {
            if (! is_array($searchParameter['hooreycaNames[]'])) {
                $searchParameter['hooreycaNames[]'] = [$searchParameter['hooreycaNames[]']];
            }

            $Product->whereIn('buyerProductName', $searchParameter['hooreycaNames[]']);
        }

        if (isset($searchParameter['producers[]'])) {
            if (! is_array($searchParameter['producers[]'])) {
                $searchParameter['producers[]'] = [$searchParameter['producers[]']];
            }

            $Product->whereIn('producer_id', $searchParameter['producers[]']);
        }

        if (isset($searchParameter['suppliers[]'])) {
            if (! is_array($searchParameter['suppliers[]'])) {
                $searchParameter['suppliers[]'] = [$searchParameter['suppliers[]']];
            }
            $Product->whereIn('supplier_id', $searchParameter['suppliers[]']);
        }
        if (isset($searchParameter['productGroups[]'])) {
            if (! is_array($searchParameter['productGroups[]'])) {
                $searchParameter['productGroups[]'] = [$searchParameter['productGroups[]']];
            }
            foreach ($searchParameter['productGroups[]'] as $productGroupId) {
                $productGroup = ProductGroup::find($productGroupId);
                // $children=$productGroup->getChildNodesArray($productGroup);

                $nodeDepth = ProductGroup::where('id', $productGroupId)->withDepth()->first()->depth;
                if ($nodeDepth == 2) {
                    $childrenId = $productGroup->descendants()->withDepth()->having('depth', '=', $nodeDepth + 1)->get()->pluck('id');
                    // $searchParameter['productGroups[]']=array_merge($searchParameter['productGroups[]'],$childrenId->toArray());
                }

                // dd($productGroupId,$nodeDepth,$children);
            }
            $Product->whereIn('product_group_id', $searchParameter['productGroups[]']);
        }

        // Akciós szűrő (specialOffer): '1' = Igen, '0' = Nem, '' vagy hiányzik = Mindegy
        if(isset($searchParameter['specialOffer']) && $searchParameter['specialOffer'] !== ''){
            $val = $searchParameter['specialOffer'] == '1' ? 1 : 0;
            $Product->where('specialOffer', $val);
        }
        if (! $request->ajax()) {

            // dd($searchParameter,$Product->toSql(), $request->input());
        }

        //        dd($request->input('order.0.dir'));
        if ($request->input('order.0')) {
            //            dd($request->input('order.0'));
            $pointer = $request->input('order.0.column');
            $orderName = $request->input('columns')[$pointer]['data'];
            $orderDirection = $request->input('order.0.dir');
            $Product->orderBy($orderName, $orderDirection);
        }

        // if($request->get('search.value'))

        $count = $Product->count('id');
        $Product->limit($request->get('length'));
        $Product->offset($request->get('start'));

        $ProductDD = $Product->toSql();
        //      dd($request->all(),$ProductDD);
        // $ProductDD=$Product->get()->first()->LastPrice;
        $ret = [
            'draw' => $request->get('draw'),
            'recordsTotal' => Product::count(),
            'recordsFiltered' => $count,
            'data' => [],
        ];
        if (! $request->ajax()) {
            // dd($Product->get()->toArray()   );
        }
        foreach ($Product->get() as $item) {
            $data['id'] = $item->id;
            $data['name'] = $item->name;
            $data['hooreycaId'] = $item->hooreycaId;
            $data['productGroup'] = $item->ProductGroup->name;
            if (isset($item->Supplier->name)) {
                $data['supplierName'] = $item->Supplier->name;
            } else {
                $data['supplierName'] = '-';
            }
            if (is_numeric($item->Price())) {
                $data['price'] = $item->Price();
            } else {
                $data['price'] = '-';
            }

            $data['created_at'] = formatterDateTime($item->created_at);
            $ret['data'][] = $data;
        }

        $ProductDD = $ret['data'];
        if (! $request->ajax()) {
            dd($searchParameter, getSql($Product), $request->input(), $ret['data']);
        }

        return \response()->json($ret);
        dd($request->all(), $ProductDD);

    }
}
