<?php

namespace App\Http\Controllers\Api\V1\Entrepreneur;

use App\Http\Controllers\Api\V1\Entrepreneur\Requests\VendorProductStoreRequest;
use App\Http\Controllers\Api\V1\Entrepreneur\Requests\VendorProductUpdateRequest;
use App\Http\Controllers\Api\V1\Product\Resources\Review\ProductReviewResource;
use App\Http\Controllers\Controller;
use App\Http\Resources\Api\V1\Vendor\Product\VendorProductIndexResource;
use App\Models\Ecommerce\Product\Product\Product;
use App\Models\User;
use App\Repositories\Ecommerce\Product\ProductRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class VendorProductController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $user = auth()->user();
        $channel = $user->channel();

        if (! $channel) {
            return response()->rest([], 400, 'User doest not have a channel');
        }

        return response()->rest_paginate(
            VendorProductIndexResource::collection(
                ProductRepository::make($request)
                    ->queryAsFromResource($channel)
                    ->attachEagerLoadingRelationship([
                        'brand',
                        'media' => function ($query) {
                            $query->orderBy('order_column', 'asc');
                        },
                    ])
                    ->applyFilters()
                    ->applySorting()
                    ->simplePaginate()
            )
        );
    }

    /**
     * Store a newly created resource in storage.
     *
     * @return \Illuminate\Http\Response
     */
    public function store(VendorProductStoreRequest $request)
    {
        $user = auth()->user();
        $channel = $user->channel();
        $tax = productTaxForCategory($request->category_ids ?? []);

        if ($request->brand_id == 0) {
            $request->merge(['brand_id' => null]);
        }

        $this->addProduct($request, $user, $channel, $tax);

        return response()->rest([], 201, 'Created');
    }

    /**
     * Add product
     */
    public function addProduct(Request $request, User $user, mixed $channel, int $tax)
    {
        $product = Product::create([
            'name' => $request->name,
            'description' => $request->description,
            'cost_amount' => $request->cost_amount,
            'price_amount' => ProductRepository::calculatePrice($request->cost_amount, $tax),
            'old_price_amount' => $request->old_price_amount ? ProductRepository::calculatePrice($request->old_price_amount, $tax) : null,
            'sku' => $request->sku,
            'barcode' => $request->barcode,
            'brand_id' => $request->brand_id,
            'stock' => $request->stock,
            'is_visible' => false,
            'options' => json_encode(ProductRepository::shippingAttributes()),
        ]);

        $product->categories()->attach($request->category_ids);
        $product->collections()->attach($request->collection_ids);
        $product->channels()->attach($channel->id);

        $inventory = $channel->inventories()->first() ?: tmpostDefaultInventory();

        $product->inventories()->attach($inventory->id, ['stock' => $request->stock]);

        if ($request->hasFile('files')) {
            $product->addMultipleMediaFromRequest(['files'])
                ->each(function ($fileAdder) {
                    $fileAdder->preservingOriginal()->toMediaCollection('uploads');
                });
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  App\Models\Ecommerce\Product\Product\Product  $product
     * @return \Illuminate\Http\Response
     */
    public function show(Product $product)
    {
        $product->load('media');

        return response()->rest(new VendorProductIndexResource($product));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(VendorProductUpdateRequest $request, Product $product)
    {
        $barcodeCheck = DB::table('products')
            ->where('barcode', $request->barcode)
            ->whereNot('id', $product->id)
            ->exists();

        if ($barcodeCheck) {
            return response()->rest([
                'message' => 'Used barcode',
                'errors' => ['barcode' => ['already taken']],
            ]);
        }

        $user = auth()->user();
        $channel = $user->channel();
        $tax = productTaxForCategory($request->category_ids ?? []);

        $product->update([
            'name' => $request->name,
            'description' => $request->description,
            'cost_amount' => $request->cost_amount,
            'price_amount' => ProductRepository::calculatePrice($request->cost_amount, $tax),
            'old_price_amount' => $request->old_price_amount
                                ? ProductRepository::calculatePrice($request->old_price_amount, $tax)
                                : null,
            'sku' => $request->sku,
            'barcode' => $request->barcode,
            'brand_id' => $request->brand_id,
            'stock' => $request->stock,
        ]);

        $product->categories()->attach($request->category_ids);
        $product->collections()->attach($request->collection_ids);

        $inventory = $channel->inventories()->first() ?: tmpostDefaultInventory();

        $product->inventories()->sync($inventory->id, ['stock' => $request->stock]);

        if ($request->hasFile('files')) {
            $product->addMultipleMediaFromRequest(['files'])
                ->each(function ($fileAdder) {
                    $fileAdder->preservingOriginal()->toMediaCollection('uploads');
                });
        }

        if ($request->filled('deleted_images')) {
            $product->getMedia('uploads')->map(function ($media) use ($request) {
                if (in_array($media->getUrl('thumb'), $request->deleted_images)) {
                    $media->delete();
                }
            });
        }

        if ($request->hasFile('new_imgs')) {
            $product->addMultipleMediaFromRequest(['new_imgs'])
                ->each(function ($fileAdder) {
                    $fileAdder->toMediaCollection('uploads');
                });
        }

        return response()->rest([], 201, 'Updated');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Product $product)
    {
        $product->delete();

        return response()->rest();
    }

    /**
     * Get product reviews
     */
    public function reviews(Product $product)
    {
        return ProductReviewResource::collection($product->reviews()->get());
    }
}
