<?php

namespace App\Http\Controllers\Admin;

use App\CategoryManufacturer;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Resources\Admin\ProductDetailResource;
use App\Http\Resources\Admin\ProductOptionResource;
use App\Http\Resources\Admin\ProductResourceDetail;
use App\Http\Resources\Admin\ProductRuleResource;
use App\Jobs\ProcessProductDetail;
use App\Jobs\ProcessProductRule;
use App\PricingRule;
use App\PricingRuleDetail;
use App\PricingRuleDetailItem;
use App\PricingRuleOption;
use App\ProductCategory;
use App\ProductColor;
use App\ProductImage;
use App\ProductPurchaseMethod;
use App\ProductSchedule;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Http\Resources\Admin\ProductResource;
use App\Http\Resources\Admin\ProductListResource;
use App\Product;
use App\Keyword;
use App\ProductDetail;
use App\ProductDetailOptionDetail;
use App\ProductKeyword;
use App\ProductOption;
use App\ProductOptionDetail;
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);
        $type = Arr::get($searchParams, 'type', '');
        $keyword = Arr::get($searchParams, 'keyword', '');
        $status = Arr::get($searchParams, 'status', '');

        if (!empty($keyword)) {
            $list->where(function ($query) use ($keyword) {
                $query->where('name', 'LIKE', '%' . $keyword . '%')
                    ->orWhere('id', '=', $keyword)
                    ->orWhere('sku', 'LIKE', '%' . $keyword . '%')
                    ->orWhere('slug', 'LIKE', '%' . $keyword . '%')
                    ->orWhere('price_from', 'LIKE', '%' . $keyword . '%')
                    ->orWhere('price_to', 'LIKE', '%' . $keyword . '%')
                    ->orWhere('discount', 'LIKE', '%' . $keyword . '%');
            });
        }

        if ($type != '') {
            $list->where('type', $type);
        }

        if ($status != '') {
            $list->where('is_activated', $status);
        }
        $list->orderBy('id', 'DESC');

        return ProductListResource::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('position')->orderBy('id');

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

    public function available()
    {
        $list = Product::select('id', 'name')->notDeleted()->activated()->orderBy('position')->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 ProductResourceDetail($product);
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name'               => [ 'required' ],
            'type'               => [ 'required' ],
            'default_price'      => [ 'required' ], //'regular_price_from' => [ 'required' ],
            'category'           => [ 'required' ], //'material'           => [ 'required' ],
            'rank'               => [ 'required' ],
            'color'              => [ 'required' ],
            'size'               => [ 'required' ],
            'hip'                => [ 'required' ],
            'is_activated'       => [ 'required' ]
        ]);
        if ($validator->fails()) return response()->json([ 'errors' => $validator->errors() ], 403);
        $params = $request->all();

        $thumb = (isset($params['image']) && $params['image'] != '') ? $params['image'] : 'no-image.png';
        if ($thumb == 'no-image.png' && isset($params['sliders'][0])) {
            $thumb = $params['sliders'][0];
        }

        $previewCode = null;
        if ($params['is_activated'] != true || $params['is_activated'] != "true" || $params['is_activated'] != 1) $previewCode = md5(rand(0, 1000) . date('Y-m-dH:i:s'));

        $product = Product::create([
            'name'                  => trim($params['name']),
            'sku'                   => $this->generateSku(),
            'slug'                  => Helper::slug(trim($params['slug'])),
            'type'                  => $params['type'],
            'default_price'         => $params['default_price'],
            'regular_price_from'    => 2000,
            'discount'              => (isset($params['discount']) && $params['discount'] != "") ? $params['discount'] : null,
            'discount_type'         => (isset($params['discount_type']) && $params['discount_type'] === 1) ? 1 : 0,
            'image'                 => $thumb,
            'gender'                => $params['gender'],
            'material'              => $params['material'],
            'rank'                  => $params['rank'],
            'size'                  => $params['size'],
            'height'                => $params['height'],
            'sleeve'                => $params['sleeve'],
            'sleeve_length'         => $params['sleeve_length'],
            'hip'                   => $params['hip'],
            'primary_width'         => $params['front_width'],
            'second_width'          => $params['rear_width'],
            'storage_date'          => date('Y-m-d'), //$params['storage_date'],
            'scene_id'              => $params['scene_id'],
            'undergarment_length'   => $params['undergarment_length'],
            'description'           => $params['description'],
            'note'                  => $params['note'],
            'preview'               => $previewCode,
            'is_cleaning_service'   => ($params['is_cleaning_service'] == 1) ? 1 : 0,
            'is_storage_period'     => ($params['is_storage_period'] == 1) ? 1 : 0,
            'is_available_in_stock' => ($params['is_available_in_stock'] === true) ? 1 : 0,
            'is_allow_faceswap'     => ($params['is_allow_faceswap'] === true) ? 1 : 0,
            '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')
        ]);

        //Images
        foreach ($params['sliders'] as $item) {
            ProductImage::create([
                'product_id' => $product->id,
                'name'       => $item,
                'file_name'  => $item,
                'position'   => 0,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }

        //Category
        foreach ($params['category'] as $item) {
            ProductCategory::create([
                'product_id'  => $product->id,
                'category_id' => $item,
                'created_at'  => date('Y-m-d H:i:s'),
                'updated_at'  => date('Y-m-d H:i:s')
            ]);
        }

        //Color
        foreach ($params['color'] as $item) {
            ProductColor::create([
                'product_id' => $product->id,
                'color_id'   => $item,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }

        //Schedule
        foreach ($params['schedule'] as $item) {
            ProductSchedule::create([
                'product_id' => $product->id,
                'short_date' => $item['id'],
                'full_date'  => $item['date'],
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }

        //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 (!$checkKeyword) {
                $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,
                'product_id' => $product->id,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ];
        }
        if (count($keywords) > 0) ProductKeyword::insert($keywords);

        return response()->json([
            'status'  => 'success',
            'id'      => $product->id,
            'preview' => $previewCode,
        ], 200);
    }

    public function update(Request $request, $id = 0)
    {
        $validator = Validator::make($request->all(), [
            'name'               => [ 'required' ],
            'type'               => [ 'required' ],
            'default_price'      => [ 'required' ], //'regular_price_from' => [ 'required' ],
            'category'           => [ 'required' ], //'material'           => [ 'required' ],
            'rank'               => [ 'required' ],
            'color'              => [ 'required' ],
            'size'               => [ 'required' ],
            'hip'                => [ '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();

        $thumb = (isset($params['image']) && $params['image'] != '') ? $params['image'] : 'no-image.png';
        if ($thumb == 'no-image.png' && isset($params['sliders'][0])) {
            $thumb = $params['sliders'][0];
        }

        $previewCode = $product->preview;
        if ($params['is_activated'] != true || $params['is_activated'] != "true" || $params['is_activated'] != 1) {
            if ($previewCode == null || $previewCode == "") $previewCode = md5(rand(0, 1000) . date('Y-m-dH:i:s'));
        }

        $storageDateDefault = Carbon::parse($product->created_at)->format('Y-m-d');

        $product->update([
            'name'                  => trim($params['name']),
            'slug'                  => Helper::slug(trim($params['slug'])),
            'type'                  => $params['type'],
            'default_price'         => $params['default_price'],
            'regular_price_from'    => 2000,
            'discount'              => (isset($params['discount']) && $params['discount'] != "") ? $params['discount'] : null,
            'discount_type'         => (isset($params['discount_type']) && $params['discount_type'] === 1) ? 1 : 0,
            'image'                 => $thumb,
            'gender'                => $params['gender'],
            'material'              => $params['material'],
            'rank'                  => $params['rank'],
            'size'                  => $params['size'],
            'height'                => $params['height'],
            'sleeve'                => $params['sleeve'],
            'sleeve_length'         => $params['sleeve_length'],
            'hip'                   => $params['hip'],
            'primary_width'         => $params['front_width'],
            'second_width'          => $params['rear_width'],
            'storage_date'          => (isset($params['storage_date']) && $params['storage_date'] != null && $params['storage_date'] != "") ? $params['storage_date'] : $storageDateDefault,
            'scene_id'              => $params['scene_id'],
            'undergarment_length'   => $params['undergarment_length'],
            'description'           => $params['description'],
            'note'                  => $params['note'],
            'preview'               => $previewCode,
            'is_cleaning_service'   => ($params['is_cleaning_service'] == 1) ? 1 : 0,
            'is_storage_period'     => ($params['is_storage_period'] == 1) ? 1 : 0,
            'is_available_in_stock' => ($params['is_available_in_stock'] === true) ? 1 : 0,
            'is_allow_faceswap'     => ($params['is_allow_faceswap'] === true) ? 1 : 0,
            'is_activated'          => ($params['is_activated'] === true) ? 1 : 0,
            'updated_at'            => date('Y-m-d H:i:s')
        ]);

        //Images
        ProductImage::where('product_id', $product->id)->delete();
        foreach ($params['sliders'] as $item) {
            ProductImage::create([
                'product_id' => $product->id,
                'name'       => $item,
                'file_name'  => $item,
                'position'   => 0,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }

        //Category
        ProductCategory::where('product_id', $product->id)->delete();
        foreach ($params['category'] as $item) {
            ProductCategory::create([
                'product_id'  => $product->id,
                'category_id' => $item,
                'created_at'  => date('Y-m-d H:i:s'),
                'updated_at'  => date('Y-m-d H:i:s')
            ]);
        }

        //Color
        ProductColor::where('product_id', $product->id)->delete();
        foreach ($params['color'] as $item) {
            ProductColor::create([
                'product_id' => $product->id,
                'color_id'   => $item,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }

        //Schedule
        ProductSchedule::where('product_id', $product->id)->delete();
        foreach ($params['schedule'] as $item) {
            ProductSchedule::create([
                'product_id' => $product->id,
                'short_date' => $item['id'],
                'full_date'  => $item['date'],
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);
        }

        //Keyword
        $keywords = [];
        ProductKeyword::where('product_id', $product->id)->delete();
        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 (!$checkKeyword) {
                $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,
                'product_id' => $product->id,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s'),
            ];
        }
        if (count($keywords) > 0) ProductKeyword::insert($keywords);

        return response()->json([
            'status'  => 'success',
            'id'      => $product->id,
            'preview' => $previewCode,
        ], 200);
    }

    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', []);
        $products = Product::notDeleted()->whereIn('id', $listIds)->get();
        if ($products->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', []);
        $products = Product::notDeleted()->whereIn('id', $listIds)->get();
        if ($products->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', []);
        $products = Product::notDeleted()->whereIn('id', $listIds)->get();
        if ($products->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);
    }

    private function generateSku($length = 8)
    {
        $characters = '0123456789abcdefghijklmnopqrs092u3tuvwxyzaskdhfhf9882323ABCDEFGHIJKLMNksadf9044OPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        }

        return $randomString;
    }
}
