<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\ApiController;
use App\Http\Requests\FoodItemStoreRequest;
use App\Http\Requests\FoodItemUpdateRequest;
use App\Http\Resources\FoodItemDetailResource;
use App\Http\Resources\FoodItemResource;
use App\Models\FoodItem;
use App\Models\FoodItemAttribute;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class FoodItemController extends ApiController
{

    /**
     * Construct middleware and initiated backups list
     */
    public function __construct()
    {
        $this->middleware('auth:sanctum');
        $this->middleware('demo')->only(['destroy']);
    }

    /**
     * Display a listing of the resource.
     *
     * @return     JsonResponse  The json response.
     */
    public function index(Request $request): JsonResponse
    {
        $sort = $this->sort($request);
        $foodItems = FoodItem::filter($request->all())
            ->orderBy($sort['column'], $sort['order'])
            ->paginate((int) $request->get('perPage', 10));
        return response()->json(
            [
                'items' => FoodItemResource::collection($foodItems->items()),
                'pagination' => $this->pagination($foodItems),
            ]
        );
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param      \App\Http\Requests\FoodItemStoreRequest  $request  The request
     *
     * @return     JsonResponse                            The json response.
     */
    public function store(FoodItemStoreRequest $request): JsonResponse
    {
        $validated = $this->itemValidated($request);
        $validated['uuid'] = Str::orderedUuid();
        $foodItem = FoodItem::create($validated);
        if ($validated['has_variants']) {
            foreach ($validated['variants'] as $variant) {
                $attribute =  FoodItemAttribute::create([
                    'uuid' => Str::orderedUuid(),
                    'food_item_id' => $foodItem->id,
                    'sku' =>  $variant->sku ?? Str::sku($variant->name),
                    'price' => $variant->price,
                    'cost' => $variant->cost,
                    'name' => $variant->name,
                ]);
                $this->syncIngredient($variant->ingredients, $foodItem, $attribute->id);
            }
            \App\Helpers\ActivityLogger::log(__('New food item with variants added successfully'));
        } else {
            \App\Helpers\ActivityLogger::log(__('New food item added successfully'));
            $this->syncIngredient($validated['ingredients'], $foodItem);
        }
        return response()->json([
            'message' => __('Data saved successfully'),
            'item' => $foodItem->uuid,
        ]);
    }

    /**
     *  Display the specified resource.
     *
     * @param      \App\Models\FoodItem  $foodItem  The fooditem
     *
     * @return     JsonResponse         The json response.
     */
    public function show(FoodItem $foodItem): JsonResponse
    {
        return response()->json(new FoodItemDetailResource($foodItem));
    }

    /**
     * Update the specified resource in storage
     *
     * @param      \App\Http\Requests\FoodItemUpdateRequest  $request  The request
     * @param      \App\Models\FoodItem                      $foodItem  The product
     *
     * @return     JsonResponse                             The json response.
     */
    public function update(FoodItemUpdateRequest $request, FoodItem $foodItem): JsonResponse
    {
        $validated = $this->itemValidated($request);
        $foodItem->ingredients()->sync([]);
        if ($validated['has_variants']) {
            foreach ($validated['variants'] as $variant) {
                if ($variant->id) {
                    $attribute =  FoodItemAttribute::where('id', $variant->id)->update([
                        'sku' =>  $variant->sku ?? Str::sku($variant->name),
                        'price' => $variant->price,
                        'cost' => $variant->cost,
                        'name' => $variant->name,
                    ]);
                    $this->syncIngredient($variant->ingredients, $foodItem, $variant->id);
                } else {
                    $attribute =  FoodItemAttribute::create([
                        'uuid' => Str::orderedUuid(),
                        'food_item_id' => $foodItem->id,
                        'sku' =>  $variant->sku ?? Str::sku($variant->name),
                        'price' => $variant->price,
                        'cost' => $variant->cost,
                        'name' => $variant->name,
                    ]);
                    $this->syncIngredient($variant->ingredients, $foodItem, $attribute->id);
                }
            }
            \App\Helpers\ActivityLogger::log(__('Food item with variants updated successfully'));
        } else {
            $this->syncIngredient($validated['ingredients'], $foodItem);
            \App\Helpers\ActivityLogger::log(__('Food item updated successfully'));
        }
        $foodItem->update($validated);
        return response()->json([
            'message' => __('Data updated successfully'),
        ]);
    }

    /**
     * Destroys the given product.
     *
     * @param      \App\Models\FoodItem  $foodItem  The product
     *
     * @return     JsonResponse         The json response.
     */
    public function destroy(FoodItem $foodItem): JsonResponse
    {
        $foodItem->ingredients()->sync([]);
        $foodItem->foodItemAttributes()->delete();
        $foodItem->delete();
        \App\Helpers\ActivityLogger::log(__('Food item removed successfully'));
        return response()->json([
            'message' => __('Data removed successfully'),
        ]);
    }

    public function destroyBatch(Request $request): JsonResponse
    {
        $items = FoodItem::whereIn('uuid', $request->rows)->get();
        foreach ($items as $item) {
            $item->ingredients()->sync([]);
            $item->foodItemAttributes()->delete();
            $item->delete();
            \App\Helpers\ActivityLogger::log(__('Food item removed successfully'));
        }
        return response()->json(['message' => __('Data removed successfully')]);
    }

    /**
     * Food item request validation
     *
     * @param      Object  $request  The request
     *
     * @return     Array   Validated request
     */
    protected function itemValidated($request): array
    {
        $validated = $request->validated();
        $validated['ingredients'] = json_decode($validated['ingredients'], false);
        $validated['variants'] = json_decode($validated['variants'], false);
        $validated['sku'] = $request->sku ?? Str::sku($request->name);
        $validated['is_bar_type'] = $validated['is_bar_type'] == 'true' ? true : false;
        $validated['has_variants'] = $validated['has_variants'] == 'true' ? true : false;
        if ($request->file('image')) {
            $validated['image'] = $request->file('image')
                ->store('food-items', 'public');
        }
        return $validated;
    }

    protected function syncIngredient($ingredients, $foodItem, $attributeId = null)
    {
        if (count($ingredients)) {
            foreach ($ingredients as $ingredient) {
                $foodItem->ingredients()->attach([
                    $ingredient->id => [
                        'quantity' => $ingredient->quantity_using,
                        'food_item_attribute_id' => $attributeId ?? null,
                    ]
                ]);
            }
        }
    }
}
