<?php

namespace App\Http\Controllers\Admin;

use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Keyword;
use App\KeywordDetail;
use App\ProductBrandDetail;
use App\ProductCategoryDetail;
use App\ProductColorDetail;
use App\ProductImage;
use App\ProductSizeDetail;
use App\Seo;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Product;
use App\Http\Resources\Admin\ProductResource;
use Validator;

/**
 * Class ProductController
 *
 * @package App\Http\Controllers
 */
class ProductController extends Controller
{
    const ITEM_PER_PAGE = 100;

    public function index(Request $request)
    {
        $searchParams = $request->all();
        $list = Product::notDeleted();
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        $keyword = Arr::get($searchParams, 'keyword', '');
        $status = Arr::get($searchParams, 'status', '');

        if (!empty($keyword)) {
            $list->where('name', 'LIKE', '%' . $keyword . '%');
        }
        if ($status != '') {
            $list->where('is_activated', $status);
        }
        $list->orderBy('id');

        return ProductResource::collection($list->paginate($limit));
    }

    public function all(Request $request)
    {
        $searchParams = $request->all();
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        $list = Product::select('id', 'name', 'slug')->notDeleted()->orderBy('id');

        return ProductResource::collection($list->paginate($limit));
    }

    public function available()
    {
        $list = Product::select('id', 'name')->notDeleted()->isPublished()->orderBy('id');

        return ProductResource::collection($list->get());
    }


    public function show($id = 0)
    {
        $product = Product::notDeleted()->where('id', $id)->first();
        if (!isset($product)) return response()->json(['errors' => 'Product is not valid'], 403);

        return new ProductResource($product);
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name'         => ['required'],
            'slug'         => ['required'],
            'sku'          => ['required'],
            'price'        => ['required'],
            'is_activated' => ['required']
        ]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $params = $request->all();

        $params['slug'] = Helper::slug($params['slug']);
        if ($params['slug'] == null || $params['slug'] == "") $params['slug'] = Helper::slug($params['name']);

        $previewCode = md5(date('Y-m-d H:i:s') . rand(1, 99999999));
        $publishAt = date('Y-m-d H:i:s');
        if (trim($params['publish_at']) != null && trim($params['publish_at']) != "") {
            $publishAt = date('Y-m-d H:i:s', strtotime(trim($params['publish_at'])));
        }

        $product = Product::create([
            'name'              => $params['name'],
            'slug'              => $params['slug'],
            'sku'               => $params['sku'],
            'price'             => $params['price'],
            'discount_amount'   => $params['discount_amount'],
            'discount_price'    => $params['discount_price'],
            'thumbnail'         => $params['thumbnail'],
            'weight'            => $params['weight'],
            'dimensions'        => $params['dimensions'],
            'in_stock'          => $params['in_stock'],
            'rating_avg'        => $params['rating_avg'],
            'information'       => $params['information'],
            'short_description' => $params['short_description'],
            'description'       => $params['description'],
            'preview'           => $previewCode,
            'publish_at'        => $publishAt,
            'is_activated'      => ($params['is_activated'] === true) ? 1 : 0,
            'created_at'        => date('Y-m-d H:i:s'),
            'updated_at'        => date('Y-m-d H:i:s')
        ]);

        //Slider
        $sliderData = [];
        foreach ($params['slider'] as $img) {
            $sliderData[] = [
                'product_id' => $product->id,
                'file_name'  => $img,
                'name'       => $img,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ];
        }
        if (count($sliderData) > 0) ProductImage::insert($sliderData);

        //Category
        $categoryData = [];
        foreach ($params['category'] as $cateId) {
            $categoryData[] = [
                'product_id'          => $product->id,
                'product_category_id' => $cateId,
                'created_at'          => date('Y-m-d H:i:s'),
                'updated_at'          => date('Y-m-d H:i:s')
            ];
        }
        if (count($categoryData) > 0) ProductCategoryDetail::insert($categoryData);

        //Brand
        $brandData = [];
        foreach ($params['brand'] as $brandId) {
            $brandData[] = [
                'product_id'       => $product->id,
                'product_brand_id' => $brandId,
                'created_at'       => date('Y-m-d H:i:s'),
                'updated_at'       => date('Y-m-d H:i:s')
            ];
        }
        if (count($brandData) > 0) ProductBrandDetail::insert($brandData);

        //Size
        $sizeData = [];
        foreach ($params['size'] as $sizeId) {
            $sizeData[] = [
                'product_id'      => $product->id,
                'product_size_id' => $sizeId,
                'created_at'      => date('Y-m-d H:i:s'),
                'updated_at'      => date('Y-m-d H:i:s')
            ];
        }
        if (count($sizeData) > 0) ProductSizeDetail::insert($sizeData);

        //Color
        $colorData = [];
        foreach ($params['color'] as $colorId) {
            $colorData[] = [
                'product_id'       => $product->id,
                'product_color_id' => $colorId,
                'created_at'       => date('Y-m-d H:i:s'),
                'updated_at'       => date('Y-m-d H:i:s')
            ];
        }
        if (count($colorData) > 0) ProductColorDetail::insert($colorData);

        //Keyword
        if (isset($params['keyword']) && is_array($params['keyword'])) {
            $keywords = [];
            foreach ($params['keyword'] as $item) {
                $tag = trim($item['text']);
                $checkKeyword = Keyword::where('is_deleted', 0)
                    ->where(function ($query) use ($tag) {
                        $query->where('name', $tag)
                            ->orWhere('name', strtolower($tag))
                            ->orWhere('name', strtoupper($tag))
                            ->orWhere('name', ucfirst($tag));
                    })->first();
                if (!isset($checkKeyword) || $checkKeyword->id == null) {
                    $checkKeyword = Keyword::create([
                        'name'         => $tag,
                        'is_activated' => true,
                        'is_deleted'   => false,
                        'created_at'   => date('Y-m-d H:i:s'),
                        'updated_at'   => date('Y-m-d H:i:s'),
                    ]);
                }
                $keywords[] = [
                    'keyword_id' => $checkKeyword->id,
                    'ref_id'     => $product->id,
                    'type'       => 'product',
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];
            }
            if (count($keywords) > 0) KeywordDetail::insert($keywords);
        }

        //Seo Meta
        $seoTitle = trim($params['seo']['title']);
        if ($seoTitle == "" || $seoTitle == null) $seoTitle = $product->name;
        Seo::create([
            'uri'         => "/product/" . $product->slug,
            'title'       => $seoTitle,
            'keywords'    => $params['seo']['keywords'],
            'description' => $params['seo']['description'],
            //'image'       => '',
            'type'        => 'product',
            'post_id'     => $product->id,
            'created_at'  => date('Y-m-d H:i:s'),
            'updated_at'  => date('Y-m-d H:i:s'),
        ]);

        return new ProductResource($product);
    }

    public function update($id = 0, Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name'         => ['required'],
            'slug'         => ['required'],
            'sku'          => ['required'],
            'price'        => ['required'],
            'is_activated' => ['required']
        ]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $product = Product::notDeleted()->where('id', $id)->first();
        if (!isset($product)) return response()->json(['errors' => 'Product is not valid'], 403);
        $params = $request->all();
        $oldSlug = $product->slug;

        $params['slug'] = Helper::slug($params['slug']);
        if ($params['slug'] == null || $params['slug'] == "") $params['slug'] = Helper::slug($params['name']);

        $publishAt = date('Y-m-d H:i:s');
        if (trim($params['publish_at']) != null && trim($params['publish_at']) != "") {
            $publishAt = date('Y-m-d H:i:s', strtotime(trim($params['publish_at'])));
        }

        $product->update([
            'name'              => $params['name'],
            'slug'              => $params['slug'],
            'sku'               => $params['sku'],
            'price'             => $params['price'],
            'discount_amount'   => $params['discount_amount'],
            'discount_price'    => $params['discount_price'],
            'thumbnail'         => $params['thumbnail'],
            'weight'            => $params['weight'],
            'dimensions'        => $params['dimensions'],
            'in_stock'          => $params['in_stock'],
            'rating_avg'        => $params['rating_avg'],
            'information'       => $params['information'],
            'short_description' => $params['short_description'],
            'description'       => $params['description'],
            'publish_at'        => $publishAt,
            'is_activated' => ($params['is_activated'] === true) ? 1 : 0,
            'updated_at'   => date('Y-m-d H:i:s')
        ]);

        //Slider
        $sliderData = [];
        ProductImage::where('product_id', $product->id)->delete();
        foreach ($params['slider'] as $img) {
            $sliderData[] = [
                'product_id' => $product->id,
                'file_name'  => $img,
                'name'       => $img,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ];
        }
        if (count($sliderData) > 0) ProductImage::insert($sliderData);

        //Category
        $categoryData = [];
        ProductCategoryDetail::where('product_id', $product->id)->delete();
        foreach ($params['category'] as $cateId) {
            $categoryData[] = [
                'product_id'          => $product->id,
                'product_category_id' => $cateId,
                'created_at'          => date('Y-m-d H:i:s'),
                'updated_at'          => date('Y-m-d H:i:s')
            ];
        }
        if (count($categoryData) > 0) ProductCategoryDetail::insert($categoryData);

        //Brand
        $brandData = [];
        ProductBrandDetail::where('product_id', $product->id)->delete();
        foreach ($params['brand'] as $brandId) {
            $brandData[] = [
                'product_id'       => $product->id,
                'product_brand_id' => $brandId,
                'created_at'       => date('Y-m-d H:i:s'),
                'updated_at'       => date('Y-m-d H:i:s')
            ];
        }
        if (count($brandData) > 0) ProductBrandDetail::insert($brandData);

        //Size
        $sizeData = [];
        ProductSizeDetail::where('product_id', $product->id)->delete();
        foreach ($params['size'] as $sizeId) {
            $sizeData[] = [
                'product_id'      => $product->id,
                'product_size_id' => $sizeId,
                'created_at'      => date('Y-m-d H:i:s'),
                'updated_at'      => date('Y-m-d H:i:s')
            ];
        }
        if (count($sizeData) > 0) ProductSizeDetail::insert($sizeData);

        //Color
        $colorData = [];
        ProductColorDetail::where('product_id', $product->id)->delete();
        foreach ($params['color'] as $colorId) {
            $colorData[] = [
                'product_id'       => $product->id,
                'product_color_id' => $colorId,
                'created_at'       => date('Y-m-d H:i:s'),
                'updated_at'       => date('Y-m-d H:i:s')
            ];
        }
        if (count($colorData) > 0) ProductColorDetail::insert($colorData);

        //Keyword
        KeywordDetail::where('type', 'product')->where('ref_id', $product->id)->delete();
        if (isset($params['keyword']) && is_array($params['keyword'])) {
            $keywords = [];
            foreach ($params['keyword'] as $item) {
                $tag = trim($item['text']);
                $checkKeyword = Keyword::where('is_deleted', 0)
                    ->where(function ($query) use ($tag) {
                        $query->where('name', $tag)
                            ->orWhere('name', strtolower($tag))
                            ->orWhere('name', strtoupper($tag))
                            ->orWhere('name', ucfirst($tag));
                    })->first();
                if (!isset($checkKeyword) || $checkKeyword->id == null) {
                    $checkKeyword = Keyword::create([
                        'name'         => $tag,
                        'is_activated' => true,
                        'is_deleted'   => false,
                        'created_at'   => date('Y-m-d H:i:s'),
                        'updated_at'   => date('Y-m-d H:i:s'),
                    ]);
                }
                $keywords[] = [
                    'keyword_id' => $checkKeyword->id,
                    'ref_id'     => $product->id,
                    'type'       => 'product',
                    'created_at' => date('Y-m-d H:i:s'),
                    'updated_at' => date('Y-m-d H:i:s'),
                ];
            }
            if (count($keywords) > 0) KeywordDetail::insert($keywords);
        }

        //Seo Meta
        $seoTitle = trim($params['seo']['title']);
        if ($seoTitle == "" || $seoTitle == null) $seoTitle = $product->name;
        $seoData = [
            'uri'         => "/product/" . $product->slug,
            'title'       => $seoTitle,
            'keywords'    => $params['seo']['keywords'],
            'description' => $params['seo']['description'],
            'updated_at'  => date('Y-m-d H:i:s'),
        ];
        $seo = Seo::where('type', 'product')
            ->where(function ($query) use ($product, $oldSlug) {
                $query->where('post_id', $product->id)->orWhere('uri', "/product/" . $oldSlug);
            })
            ->first();
        if (!isset($seo)) {
            $seoData['type'] = 'product';
            $seoData['post_id'] = $product->id;
            $seoData['created_at'] = date('Y-m-d H:i:s');
            Seo::create($seoData);
        } else {
            $seo->update($seoData);
        }

        return response()->json(null, 204);
    }

    public function destroy($id = 0)
    {
        $product = Product::notDeleted()->where('id', $id)->first();
        if (!isset($product)) response()->json(['error' => 'Ehhh! Can not delete this product'], 403);

        try {
            $product->update(['is_deleted' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    public function destroyMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $categories = Product::notDeleted()->whereIn('id', $listIds)->get();
        if ($categories->count() <= 0) response()->json(['error' => 'Product is not valid.'], 403);
        try {
            Product::notDeleted()->whereIn('id', $listIds)->update(['is_deleted' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    public function activateMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $categories = Product::notDeleted()->whereIn('id', $listIds)->get();
        if ($categories->count() <= 0) response()->json(['error' => 'Product is not valid.'], 403);
        try {
            Product::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    public function deactivateMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $categories = Product::notDeleted()->whereIn('id', $listIds)->get();
        if ($categories->count() <= 0) response()->json(['error' => 'Product is not valid.'], 403);
        try {
            Product::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => false]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }
}
