<?php

namespace App\Http\Controllers\Main\Products;

use App\Models\Product;
use App\Http\Controllers\Controller;
use App\Models\Color;
use App\Models\ProductFavorite;
use App\Services\Main\Products\ProductsArchiveService;
use App\Services\Main\Products\ProductService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Inertia\Inertia;

class ProductsController extends Controller
{
    /**
     * Display a listing of the products
     */
    public function index(Request $request, ProductsArchiveService $productsArchiveService)
    {
        // add search to history
        $productsArchiveService->addSearchToHistory($request);

        // get products
        $products = $productsArchiveService->getProducts($request);
        $seo = $products['seo'];

        $view = Inertia::render("Main/Products/List", [
            'seo' => fn() => $seo,
            'products' => fn() => $products['products'],
            'filters' => fn() => [
                'brands' => $products['brands'],
                'colors' => Cache::remember('colors', now()->addMonth(), function () {
                    return Color::all();
                }),
                'price' => $products['price'],
                'tags' => $products['tags'],
            ],
            'keywords' => fn() => $products['keywords'],
        ]);

        $view->title($seo['title'])
            ->tag('<link rel="canonical" href="' . str_replace('%', '%%', $seo['canonical'] !== null ? urldecode($seo['canonical']) : urldecode(url()->full())) . '" />');

        if ($seo['description'] != null) {
            $view->description($seo['description']);
        }
        if ($seo['image'] != null) {
            $view->image($seo['image']);
        }
        if ($seo['author'] != null) {
            $view->tag('<meta name="author" content="' . str_replace('%', '%%', $seo['author']) . '" />');
        }

        // og and twitter card
        $view->ogMeta()
            ->ogUrl(urldecode(url()->full()))
            ->ogLocale('fa_IR')
            ->tag('<meta property="og:site_name" content="' . $seo['site_name'] . '" />')
            ->twitterSummaryCard()
            ->twitterSite($request->url())
            ->twitterCreator($seo['site_name'])
            ->tag('<script type="application/ld+json">' . str_replace('%', '%%', $seo['schema']) . '</script>'); // schema

        if ($seo['type'] != null) {
            $view->ogType($seo['type']);
        }

        if (count($products['products']) == 0) {
            $view->tag('<meta name="robots" content="noindex, follow">');
        }

        return $view;
    }

    /**
     * Display the specified product
     */
    public function show(Request $request, Product $product, ProductService $productService)
    {
        // check product status
        if ($product->status != 'publish')
            abort(404);

        // increase view count
        $product->update([
            'view_count' => $product->view_count + 1
        ]);
        $seo = $productService->seo($product);

        // add product to last viewed list
        $productService->addProductTolastViewedList($request, $product);

        $view = Inertia::render('Main/Products/Show', [
            'seo' => $seo,
            'product' => fn() => [
                'id' => $product->id,
                'uuid' => $product->uuid,
                'title' => $product->title,
                'title_en' => $product->title_en,
                'slug' => $product->slug,
                'content' => $product->content,
                'warnings' => $product->warnings != '' ? $product->warnings : null,
                'guide' => $product->guide,
                'get_tabs' => $product->get_tabs,
                'get_all_images' => $product->get_all_images,
                'get_buyer_images' => $product->get_buyer_images,
                'get_images' => $product->get_images,
                'get_videos' => $product->get_videos,
                'model_3d' => $product->model_3d,
                'get_specifications' => $product->get_specifications,
                'is_vip' => $product->is_vip,
                'inventory' => $product->inventory,
                'best_price' => $product->best_price,
                'best_inventory' => $product->best_inventory,
                'in_stock_status' => $product->in_stock_status,
                'get_inquiry_options' => $product->get_inquiry_options,
                'get_affiliate' => $product->get_affiliate,
                'comment_status' => $product->comment_status,
                'comments_info' => $product->comments_info,
                'question_status' => $product->question_status,
                'questions_info' => $product->questions_info,
                'get_attrs' => $product->get_attrs,
                'is_favorite' => $product->is_favorite,
                'is_buyer' => $product->is_buyer,
                'favorites_count' => $product->favorites_count,
                'cart_count' => $product->cart_count,
                'view_count' => $product->view_count,
                'has_inventory_notification' => $product->has_inventory_notification,
                'has_discount' => $product->has_discount,
                'has_discount_notification' => $product->has_discount_notification,
                'status' => $product->status,

                'tags' => $product->productTags()->where('status', 'publish')->get()->map(fn($tag) => [
                    'id' => $tag->id,
                    'title' => $tag->title,
                    'slug' => $tag->slug,
                ]),
                'brand' => $product->brand != null ? [
                    'id' => $product->brand->id,
                    'title' => $product->brand->title,
                    'slug' => $product->brand->slug,
                ] : null,
                'category' => [
                    'id' => $product->productCategory->id,
                    'title' => $product->productCategory->title,
                    'slug' => $product->productCategory->slug,
                ],
            ],
            'productProps' => fn() => $productService->getProductProps($product),
            'inventories' => fn() => $productService->getProductInventories($product),
            'relatedProducts' => fn() => $productService->getRelatedProducts($product),
            'comments' => fn() => $productService->getProductComments($request, $product),
            'questions' => fn() => $productService->getProductQuestions($request, $product),
        ]);

        $view->title($seo['title'])
            ->tag('<link rel="canonical" href="' . str_replace('%', '%%', $seo['canonical'] !== null ? urldecode($seo['canonical']) : urldecode(url()->full())) . '" />');

        if ($seo['description'] != null) {
            $view->description(str_replace('%', '%%', $seo['description']));
        }
        if ($seo['image'] != null) {
            $view->image($seo['image']);
        }
        if ($seo['author'] != null) {
            $view->tag('<meta name="author" content="' . str_replace('%', '%%', $seo['author']) . '" />');
        }

        // og and twitter card
        $view->ogMeta()
            ->ogUrl(urldecode(url()->full()))
            ->ogLocale('fa_IR')
            ->tag('<meta property="og:site_name" content="' . $seo['site_name'] . '" />')
            ->twitterLargeCard()
            ->twitterSite($request->url());

        if ($seo['type'] != null) {
            $view->ogType($seo['type']);
        }
        if ($seo['author'] != null) {
            $view->twitterCreator($seo['author']);
        }
        if ($seo['availability'] != null) {
            $view->tag('<meta property="og:availability" content="' . $seo['availability'] . '" />');
        }

        // schema
        if ($seo['schema'] != null) {
            if (array_key_exists('breadcrumb', $seo['schema'])) {
                $view->tag('<script type="application/ld+json">' . str_replace('%', '%%', $seo['schema']['breadcrumb']) . '</script>');
            }
            if (array_key_exists('product', $seo['schema'])) {
                $view->tag('<script type="application/ld+json">' . str_replace('%', '%%', $seo['schema']['product']) . '</script>');
            }
        }

        // torob meta
        $view->tag('<!-- product data -->');
        $view->tag('<meta name="product_id" content="' . $product->uuid . '">');
        $view->tag('<meta name="product_name" content="' . str_replace('%', '%%', $product->title) . '">');
        if ($product->inventory && $product->in_stock_status) {
            $view->tag('<meta name="product_price" content="' . $product->best_price . '">');
            if ($product->has_discount) {
                $view->tag('<meta name="product_old_price" content="' . $product->best_inventory['price'] . '">');
            }
        }
        $view->tag('<meta name="availability" content="' . ($product->inventory && $product->in_stock_status ? 'instock' : 'outofstock') . '">');
        if ($product->inventory && $product->in_stock_status && array_key_exists('گارانتی', $product->best_inventory['raw_props'])) {
            $view->tag('<meta name="guarantee" content="' . str_replace('%', '%%', $product->best_inventory['raw_props']['گارانتی']) . '">');
        }
        // specs
        if ($product->inventory && $product->in_stock_status && $product->best_inventory != null) {
            $original = $product->best_inventory['original'] ? 'اصل' : 'غیراصل';
            $used = $product->best_inventory['used'] ? 'کارکرده' : 'نو';
            $view->tag(<<<HTML
        <meta name="spec" content="اصالت کالا:{$original}">
            <meta name="spec" content="وضعیت کالا:{$used}">
        HTML);
        }


        return $view;
    }

    /**
     * Display the specified product shortcut
     */
    public function shortcut(Request $request, $uuid, ProductService $productService)
    {
        $product = Product::where('uuid', $uuid)->first();

        if ($product == null) {
            abort(404);
        }

        // proccessing affiliate link
        if ($request->exists('u') && $request->u != null) {
            $productService->addAffiliate($request, $product);
        }

        return redirect()->route('main.products.show', $product->slug);
    }

    /**
     * return the specified product shortcut json
     */
    public function shortcut_json(Request $request, $uuid)
    {
        $product = Product::where('uuid', $uuid)->first();

        if ($product == null) {
            return response()->json([
                'status' => 404,
            ]);
        }

        return response()->json([
            'status' => 200,
            'product' => [
                'id' => $product->id,
                'uuid' => $product->uuid,
                'title' => $product->title,
                'slug' => $product->slug,
                'get_images' => $product->get_images,
                'comments_info' => $product->comments_info,
                'in_stock_status' => $product->in_stock_status,
                'inventory' => $product->inventory,
                'best_normal_price' => $product->best_normal_price,
                'unique_color' => $product->unique_color,
                'best_price' => $product->best_price,
                'has_discount' => $product->has_discount,
                'is_vip' => $product->is_vip,
            ]
        ]);
    }

    /**
     * switch product favorites
     */
    public function favorites(Product $product)
    {
        /** @var \App\Models\User $user */
        $user = auth()->user();

        // check user login
        if ($user == null)
            return redirect()->back()->withErrors([__('messages.login_required')]);

        $favorite = ProductFavorite::where('user_id', $user->id)->where('product_id', $product->id)->first();
        if ($favorite == null) {
            $user->productFavorites()->create([
                'product_id' => $product->id,
            ]);

            return redirect()->back()->with('message', [__('messages.product_favorite_added')]);
        } else {
            $favorite->delete();

            return redirect()->back()->with('message', [__('messages.product_favorite_deleted')]);
        }
    }

    /**
     * turn on/off product notification for user
     */
    public function notification(Request $request, Product $product)
    {
        /** @var \App\Models\User $user */
        $user = auth()->user();

        // check user login
        if ($user == null)
            return redirect()->back()->withErrors([__('messages.login_required')]);

        $request->validate([
            'type' => 'required'
        ]);

        if ($request->type == 'inventory') {
            if (!$product->inventory) {
                $userInventoryNotifications = $user->productNotifications()->where('product_id', $product->id)->where('type', 'inventory')->first();
                if ($userInventoryNotifications == null) {
                    $user->productNotifications()->create([
                        'product_id' => $product->id,
                        'type' => 'inventory'
                    ]);

                    return redirect()->back()->with('message', [__('messages.product_notification_on')]);
                } else {
                    $userInventoryNotifications->delete();
                    return redirect()->back()->with('message', [__('messages.product_notification_off')]);
                }
            }
        } else if ($request->type == 'discount') {
            if (!$product->has_discount) {
                $userDiscountNotifications = $user->productNotifications()->where('product_id', $product->id)->where('type', 'discount')->first();
                if ($userDiscountNotifications == null) {
                    $user->productNotifications()->create([
                        'product_id' => $product->id,
                        'type' => 'discount'
                    ]);

                    return redirect()->back()->with('message', [__('messages.product_notification_on')]);
                } else {
                    $userDiscountNotifications->delete();
                    return redirect()->back()->with('message', [__('messages.product_notification_off')]);
                }
            }
        }

        return redirect()->back()->withErrors([__('messages.unknown_error')]);
    }
}
