<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Models\ProductStoreMap;
use App\Models\Store;
use App\Models\StoreCategory;
use App\Models\StoreProduct;
use App\Models\StoreProductOptional;
use App\Traits\Upload;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class StoreProductController extends Controller
{
    use Upload;

    public function __construct()
    {
        $this->middleware(['auth']);
        $this->middleware(function ($request, $next) {
            $this->user = auth()->user();
            return $next($request);
        });
        $this->theme = template();
    }

    public function index(Request $request)
    {
        $search = $request->all();
        $dateSearch = Carbon::parse($request->created_at);

        $data['categories'] = StoreCategory::own($this->user->id)->where('status', 1)->orderBy('name', 'asc')->toBase()->get();
        $data['optionalProducts'] = StoreProductOptional::own($this->user->id)->where('status', 1)->orderBy('name', 'asc')->toBase()->get();
        $data['products'] = StoreProduct::own($this->user->id)->with(['category'])->orderBy('id', 'desc')
            ->when(isset($search['name']), function ($query) use ($search) {
                $query->where('name', 'LIKE', '%' . $search['name'] . '%');
            })
            ->when(isset($search['created_at']), function ($query) use ($dateSearch) {
                return $query->whereDate("created_at", $dateSearch);
            })
            ->when(isset($search['sku']), function ($query) use ($search) {
                $query->where('sku', 'LIKE', '%' . $search['sku'] . '%');
            })
            ->when(isset($search['category_id']), function ($query) use ($search) {
                $query->where('category_id', $search['category_id']);
            })
            ->when(isset($search['status']), function ($query) use ($search) {
                $query->where('status', $search['status']);
            })
            ->paginate(basicControl()->paginate);
        return view($this->theme . 'user.store.product.index', $data);
    }

    public function create(Request $request)
    {
        if ($request->method() == 'GET') {
            $data['stores'] = Store::own($this->user->id)->where('status', 1)->orderBy('name', 'asc')->toBase()->get();
            $data['categories'] = StoreCategory::own($this->user->id)->where('status', 1)->orderBy('name', 'asc')->toBase()->get();
            $data['optionalProducts'] = StoreProductOptional::own($this->user->id)->where('status', 1)->orderBy('name', 'asc')->toBase()->get();
            return view($this->theme . 'user.store.product.create', $data);
        }
        if ($request->method() == 'POST') {
            $validator = Validator::make($request->all(), [
                'store' => 'required',
                'category' => 'required',
                'name' => 'required|string|min:2',
                'price' => 'required|numeric|min:0|not_in:0',
                'sku' => 'required|min:1',
                'extra_products.*' => 'nullable',
                'variant_name.*' => 'nullable|string|min:2',
                'variant_price.*' => 'nullable|numeric|min:0|not_in:0',
                'image' => 'required',
            ]);
            if ($validator->fails()) {
                return back()->withErrors($validator)->withInput();
            }
            $variants = [];
            if ($request->variant_price) {
                for ($i = 0; $i < count($request->variant_price); $i++) {
                    $variants[$i]['variant_name'] = $request->variant_name[$i] ?? 'abc';
                    $variants[$i]['variant_price'] = $request->variant_price[$i] ?? 0;
                }
            }

            $category = StoreCategory::where('status', 1)->findOrFail($request['category']);

            DB::beginTransaction();
            try {
                $storeProduct = new StoreProduct();
                $storeProduct->user_id = $this->user->id;
                $storeProduct->category_id = $category->id;
                $storeProduct->name = $request['name'];
                $storeProduct->price = $request['price'];
                $storeProduct->sku = $request['sku'];
                $storeProduct->tag = $request['tag'];
                $storeProduct->status = $request['status'];
                $storeProduct->description = $request['description'];

                if ($request->hasFile('image')) {
                    try {
                        $image = $this->fileUpload($request->image, config('filelocation.product.path'), null, config('filelocation.product.size'), 'webp',99);
                        if ($image) {
                            $storeProduct->image = $image['path'];
                            $storeProduct->driver = $image['driver'];
                        }
                    } catch (\Exception $e) {
                        return back()->with('alert', 'Image could not be uploaded');
                    }
                }

                $storeProduct->extra_products = $request->extra_products ?? [];
                $storeProduct->variants = $variants ?? [];
                $storeProduct->save();

                if ($request->store) {
                    for ($i = 0; $i < count($request->store); $i++) {
                        $productStoreMap = new ProductStoreMap();
                        $productStoreMap->product_id = $storeProduct->id;
                        $productStoreMap->store_id = $request->store[$i];
                        $productStoreMap->save();
                    }
                }
                DB::commit();
                return back()->with('success', 'Menu has been created');
            } catch (\Exception $e) {
                DB::rollBack();
                return back()->with('error', 'something went wrong');
            }
        }
    }

    public function edit($id, Request $request)
    {
        $data['product'] = StoreProduct::own($this->user->id)->with(['productStores.store'])->findOrFail($id);

        if ($request->method() == 'GET') {
            $data['stores'] = Store::own($this->user->id)->where('status', 1)->orderBy('name', 'asc')->toBase()->get();
            $data['categories'] = StoreCategory::own($this->user->id)->where('status', 1)->orderBy('name', 'asc')->toBase()->get();
            $data['optionalProducts'] = StoreProductOptional::own($this->user->id)->where('status', 1)->orderBy('name', 'asc')->toBase()->get();
            return view($this->theme . 'user.store.product.edit', $data);
        }
        if ($request->method() == 'POST') {
            $validator = Validator::make($request->all(), [
                'store' => 'required',
                'category' => 'required|numeric',
                'name' => 'required|string|min:2',
                'price' => 'required|numeric|min:1',
                'sku' => 'required|min:1',
                'extra_products.*' => 'nullable',
                'variant_name.*' => 'nullable|string|min:2',
                'variant_price.*' => 'nullable|numeric|min:0|not_in:0',
                'image' => 'sometimes',
            ]);

            $variants = [];
            if ($request->variant_price) {
                for ($i = 0; $i < count($request->variant_price); $i++) {
                    $variants[$i]['variant_name'] = $request->variant_name[$i] ?? 'abc';
                    $variants[$i]['variant_price'] = $request->variant_price[$i] ?? 0;
                }
            }

            if ($validator->fails()) {
                return back()->withErrors($validator)->withInput();
            }
            $category = StoreCategory::where('status', 1)->findOrFail($request['category']);

            DB::beginTransaction();
            try {
                $data['product']->category_id = $category->id;
                $data['product']->name = $request['name'];
                $data['product']->price = $request['price'];
                $data['product']->sku = $request['sku'];
                $data['product']->tag = $request['tag'];
                $data['product']->status = $request['status'];
                $data['product']->description = $request['description'];
                $data['product']->variants = $variants ?? null;

                if ($request->image) {
                    try {
                        $image = $this->fileUpload($request->image, config('location.product.path'), $data['product']->driver, null, $data['product']->image, $data['product']->driver);
                        if ($image) {
                            $data['product']->image = $image['path'];
                            $data['product']->driver = $image['driver'];
                        }
                    } catch (\Exception $e) {
                        return back()->with('alert', 'Image could not be uploaded');
                    }
                }

                if ($request->extra_products) {
                    $data['product']->extra_products = $request->extra_products;
                }

                $data['product']->save();

                if ($request->store) {
                    ProductStoreMap::where('product_id', $data['product']->id)->get()->map(function ($query) {
                        $query->delete();
                    });
                    for ($i = 0; $i < count($request->store); $i++) {
                        $productStoreMap = new ProductStoreMap();
                        $productStoreMap->product_id = $data['product']->id;
                        $productStoreMap->store_id = $request->store[$i];
                        $productStoreMap->save();
                    }
                }
                DB::commit();
                return back()->with('success', 'Menu Updated Successfully');
            } catch (\Exception $e) {
                DB::rollBack();
                return back()->with('alert', 'Something went wrong');
            }
        }
    }


    public function delete($id)
    {
        $product = StoreProduct::own($this->user->id)->with(['orderDetails'])->findOrFail($id);
        ProductStoreMap::where('product_id', $id)->get()->map(function ($query) {
            $query->delete();
        });

        $this->fileDelete($product->driver, $product->image);
        $product->delete();
        return back()->with('success', 'Menu Delete Successfully');
    }


}
