<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreProduct;
use App\Model\Category;
use App\Model\Product;
use DB;
use Illuminate\Support\Str;


trait Products
{

    public function updateProduct(StoreProduct $request, Product $product)
    {

        if ($request->get('attributes')) {
            // filter out null vars.
            DB::transaction(function () use ($product, $request) {

                // process attributes
                $attributes = collect($request->get('attributes'))
                    ->filter()
                    ->map(function ($item, $attribute_id) {
                        if (is_array($item)) {
                            return collect($item)->map(function ($item) use ($attribute_id) {
                                return [
                                    'attribute_id' => $attribute_id,
                                    'attribute_value_id' => $item,
                                ];
                            });
                        }
                        return [
                            'attribute_id' => $attribute_id,
                            'value' => $item,
                        ];
                    })->reduce(function ($carry, $item) {
                        return $carry->merge(empty($item['attribute_id']) ? $item : [$item]);
                    }, collect());

                // sync em
                $product->attributesPivot()->sync([]); // force delete all
                $product->attributesPivot()->sync($attributes); // this alone doesn't work. the other save will allow duplicates and delete good ones.
                $product->save();

            });

            return redirect()->route('admin.products.edit', [$product, 'tab' => 'attributes']);
//            return back();
        }

        try {
            DB::beginTransaction();

            if ($request->get('categories')) {
                $categories = $request->categories;
                $first_category_without_children = null;

                foreach ($request->categories as $category) {
                    $category = Category::find($category);
                    if (!$category->has_children && !$first_category_without_children) {
                        $first_category_without_children = $category->id;
                    }

                    // check if parent has another parent!
                    while ($category->parentCat) {
                        $categories[] = $category->parentCat->id;
                        $category = $category->parentCat;
                    }
                }
            }

            if ($request->has('category_id')) {
                // check if the current category_id is within picked user categories, if not try to guess the category id.
//            $product->category_id = in_array($request->get('category_id'), $categories) ? $request->get('category_id') : ($first_category_without_children ?? max($categories));
                $product->category_id = $request->get('category_id') ?? ($first_category_without_children ?? max($categories));
            }

            // go save the product first (when new product, we need this for category assoc)
            $is_active = $product->isActive();
            $product->fill($request->except('categories', 'files', 'related', 'bundles', 'variants', 'category_id', 'offer'));

            if ($this->shouldBeModerated && $product->isDirty()) {
                // if by mistake only the form with status pending was sent *meanwhile* being approved by admin.
                if ($is_active && $request->get('status') == 'pending' && count($product->getDirty()) == 1) {
                    $product->status = 'active';
                }
                else if ($product->isActive()) {
                    $product->status = 'pending';
                }
            }

            if ($this->shouldBeModerated) {
                // @quikfix for js stripin'.
                $product->description = preg_replace("/<script.*?\/script>/s", "", $product->description);
            }


            $product->save();

            if ($request->has('categories')) {
               $summary = $product->categories()->sync($categories);

               if ($this->shouldBeModerated && $product->isActive() && collect($summary)->flatten()->isNotEmpty()) {
                   $product->status = 'pending';
                   $product->save();
               }
            }

            DB::commit();
        } catch (\Exception $e) {
            DB::rollback();
            /* Transaction failed. */
            throw new $e;
        }
    }




}
