<?php

namespace Modules\Seo\Controllers;

use App\Utils\CategoryHelper;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Route;
use App\Utils\SlugManager;

class UrlManagerController extends Controller
{
    protected $slugManagerService;

    public function __construct()
    {
        $this->slugManagerService = new SlugManager();
    }

    public function resolve(Request $request)
    {
        $currentPath = $request->path();
        $customizationFolder = 'customization-upload';
        if (strpos($currentPath, $customizationFolder) !== false) {
            $fileName = basename($currentPath);
            $filePath = public_path($customizationFolder . '/' . $fileName);
            if (file_exists($filePath)) {
                $contentType = mime_content_type($filePath);
                ob_clean();
                return response()->file($filePath, [
                    'Content-Type' => $contentType
                ]);
            }
        }
        $params = [];
        try {
            //check page - all sp or designer or category or tag
            $params = $this->buildParams();
            if ($this->isSpecialUrl($request, $params)) {
                return $this->specialUrl($request, $params);
            }
            if (isset($params['page_type']) && $params['page_type'] == 'category') {
                $this->log([
                    'message' => 'redirect category'
                ], 'redirect_category');
                return redirect($this->getUrlCategory($params), 301);
            }
            if (isset($params['page_type']) && $params['page_type'] == 'tag') {
                $this->log([
                    'message' => 'redirect_tag'
                ], 'redirect_tag');
                return redirect(route('tag::explore', [
                    'tagTitle' => $params['slug']
                ]), 301);
            }
            $request->merge($params);
        } catch (\Exception $ex) {
            $message = $ex->getMessage() . " Line: {$ex->getLine()} File: {$ex->getFile()}";
            $this->log(['message' => $message], 'error');
        }
        if (isset($params['page_type']) && $params['page_type'] && !$this->isInvalidPath($params)) {
            return app()->call($this->getFunctionCall($params['page_type']), $this->buildCallFuncParams($request));
        } else {
            $this->log([
                'message' => 'isInvalidPath'
            ], 'isInvalidPath');
            abort(404);
        }
    }

    protected function getUrlCategory($params) {
        $slug = isset($params['category_slug']) ? $params['category_slug'] : $params['dispatches_attrs']['category']['slug'];
        $attrs = [];
        foreach (CategoryHelper::TYPES_ENABLE as $type)  {
            if (isset($params['dispatches_attrs'][$type]['slug'])) {
                $attrs[$type] = $params['dispatches_attrs'][$type]['slug'];
            }
        }
        return CategoryHelper::url($slug, $attrs);
    }

    protected function isInvalidPath($params) {
        $result = false;
        if ($params
            && isset($params['attrs'])
            && isset($params['slugs'])
            && count($params['slugs']) != count($params['attrs'])
        ) {
            $result = true;
        }
        return $result;
    }

    protected function isSpecialUrl($request, $params) {
        $result = false;
        $routeParameters = Route::current()->parameters();
        $slug = $routeParameters['slug'];
        $slug2 = isset($routeParameters['slug2']) ? $routeParameters['slug2'] : '';
        if ($params['page_type'] == 'tag' && \Module::isActive('ZSearch')) {
            if (config('seo::default.redirect_old_tag_url')
                && ($request->has('category') || $request->has('size_variant_id'))) {
                $result = true;
            }
        }
        /*  else if ("/$slug" == trans('routes.frontend.shop')) {
            $result = true;
        } */
        else if ("/$slug" == trans('routes.frontend.brand')) {
            //@todo
            //return $this->brand($request, $slug2, $slug3);
        } else if ($slug2 && "/$slug/$slug2" == trans('routes.frontend.product-all')) {
            $result = true;
        } else if ($params['page_type'] == 'delete') {
            $result = true;
        }
        if ($this->logicRedirectTag($params)) {
            $result = true;
        }
        return $result;
    }


    protected function specialUrl($request, $params) {
        $routeParameters = Route::current()->parameters();
        $slug = $routeParameters['slug'];
        $slug2 = isset($routeParameters['slug2']) ? $routeParameters['slug2'] : '';
        if ($params['page_type'] == 'tag' && \Module::isActive('ZSearch')) {
            if (config('seo::default.redirect_old_tag_url')
                && ($request->has('category') || $request->has('size_variant_id'))) {
                return $this->redirectOldTagUrl($request, $routeParameters['slug']);
            }
        }
        /* if ("/$slug" == trans('routes.frontend.shop')) {
            if ($slug2) {
                return redirect()->route('categoryOrTag', [
                    'slug' => $slug2
                ], 301);
            } else {
                return app()->call('App\Http\Controllers\Frontend\ProductController@sellerList',
                    ['request' => $request]);
            }

        }else  */
        if ("/$slug" == trans('routes.frontend.brand')) {
            //@todo
            //return $this->brand($request, $slug2, $slug3);
        } else if ($slug2 && "/$slug/$slug2" == trans('routes.frontend.product-all')) {
            return redirect()->route('categoryOrTag', [
                'slug' => 's'
            ], 301);
        } else if ($params['page_type'] == 'delete') {
            return redirect('/', 301);
        }

        if ($this->logicRedirectTag($params)) {
            return redirect()->route('categoryOrTag', [
                'slug' =>  $params['attrs'][1]->slug,
                'slug1' =>  $params['attrs'][0]->slug,
            ], 301);
        }
    }

    protected function logicRedirectTag($params) {
        return isset($params['page_type'])
            && $params['page_type'] ==  'tag'
            && isset($params['attrs'])
            && count($params['attrs']) > 1
            && isset($params['attrs'][0]->type)
            && isset($params['attrs'][1]->type)
            && $params['attrs'][0]->type  == 'tag'
            && $params['attrs'][1]->type  == 'category';
    }

    protected function log($data = [], $type = 'redirect') {
        $data['url'] = request()->fullUrl();
        DB::table('log')->insert([
            'target_type' => 'seo-resolve-url',
            'event_type' => $type,
            'target_id' => 0,
            'data' => json_encode($data),
            'created_at' => new \DateTime()
        ]);
    }

    protected function handleRedirect($routeParameters) {
        $slug = $routeParameters['slug'];
        if ("/$slug" == trans('routes.frontend.shop')) {
            return redirect()->route('categoryOrTag', [
                'slug' => $routeParameters['slug2']
            ], 301);
        }
    }

    protected function buildParams()
    {
        $attrs = $this->slugManagerService->getAttrs($this->requestAll());
        $pageType = $this->getPageType($attrs);
        $params = $this->slugManagerService->buildRequestParams($attrs);
        return array_merge($params, [
            'dispatches_attrs' => $this->buildDispatchesAttrs($attrs),
            'page_type' => $pageType,
            'current_route_name' => $pageType,
            'attrs' => $attrs,
            'is_tag_page' => $pageType == 'tag' ? 1 : 0,
            'slugs' => $this->requestAll()
        ]);
    }

    protected function buildCallFuncParams($request)
    {
        $params = $request->all();
        $pageType = $request->input('page_type');
        $result = [
            'request' => $request,
            'paramSlug' => null,
            'paramId' => null,
        ];
        if ($pageType == 'category') {
            $result = array_merge($result, [
                'paramSlug' => $params['category_slug'],
                'paramId' => $params['category_id'],
            ]);
        } else if ($pageType == 'seller') {
            $result['id'] = $params['user_id'];
        } else if ($pageType == 'tag') {
            if (\Module::isActive('ZSearch')) {
                $result['tagTitle'] = $params['slug'];
            } else {
                $result = array_merge($result, [
                    'paramSlug' => $params['slug'],
                    'paramId' => $params['id']
                ]);
            }
        } else if ($pageType == 'season_event') {
            $result = [
                'request' => $request,
                'slug' => $params['slug'],
                'id' => $params['id'],
            ];
        }
        return $result;
    }

    protected function getFunctionCall($pageType)
    {
        $result = 'App\Http\Controllers\Frontend\ProductController@search';
        if ($pageType == 'seller') {
            // $result = 'App\Http\Controllers\Frontend\ProductController@listBySeller';
            $result = 'App\Http\Controllers\Frontend\ProductController@getPageBySeller';
        } else if ($pageType == 'tag') {
            if (\Module::isActive('ZSearch')) {
                $result = '\Modules\ZSearch\Controllers\HomeController@index';
            } else {
                $result = 'App\Http\Controllers\Frontend\ProductController@listByTag';
            }
        } else if ($pageType == 'season_event') {
            if (\Module::isActive('SeasonEvent')) {
                $result = '\Modules\SeasonEvent\Controllers\HomeController@listByEvent';
            }
        }
        return $result;
    }

    protected function buildDispatchesAttrs($attrs)
    {
        $result = [];
        foreach ($attrs as $attr) {
            $result[$attr->type] = (array)$attr;
        }
        return $result;
    }

    public function getPageType($attrs)
    {
        $result = '';
        if (isset($attrs[0])) {
            $result = $attrs[0]->type;
            $secondSegment = isset($attrs[1]) && $attrs[1]->type ? $attrs[1]->type : '';
            if (!in_array($result, ['s', SlugManager::TYPE_SELLER]) && $secondSegment == SlugManager::TYPE_TAG) {
                $result = SlugManager::TYPE_TAG;
            } else if ($result == SlugManager::TYPE_TAG && $secondSegment == SlugManager::TYPE_SELLER) {
                $result = SlugManager::TYPE_SELLER;
            }
        }
        return $result;

    }

    protected function requestAll()
    {
        $result = [];
        $params = Route::current()->parameters();
        foreach ($params as $key => $param) {
            if (str_contains($key, 'slug')) {
                $result[] = $param;
            }
        }
        return $result;
    }

    private function redirectOldTagUrl($request, $slug)
    {
        $urlQueryParams = $request->all();
        if ($request->has('size_variant_id') && $request->has('category')) {
            $variantOptions = DB::table('product_variant_option')->where('id', $request->get('size_variant_id'))->first(['slug']);
            $categorySlug = DB::table('category')->where('id', '=', $request->get('category'))->select('id', 'name', 'slug')->first();
            if (!empty($categorySlug) && !empty($variantOptions)) {
                unset($urlQueryParams['size_variant_id']);
                unset($urlQueryParams['category']);
                $urlQueryParams['slug'] = $slug;
                $urlQueryParams['slug2'] = $categorySlug->slug;
                $urlQueryParams['slug3'] = $variantOptions->slug;
            }
        } else if ($request->has('size_variant_id')) {
            $variantOptions = DB::table('product_variant_option')->where('id', $request->get('size_variant_id'))->first(['slug']);
            if (!empty($variantOptions)) {
                unset($urlQueryParams['size_variant_id']);
                $urlQueryParams['slug'] = $slug;
                $urlQueryParams['slug2'] = $variantOptions->slug;
            }
        } else if ($request->has('category')) {
            $categorySlug = DB::table('category')->where('id', '=', $request->get('category'))->select('id', 'name', 'slug')->first();
            if (!empty($categorySlug)) {
                unset($urlQueryParams['category']);
                $urlQueryParams['slug'] = $slug;
                $urlQueryParams['slug2'] = $categorySlug->slug;
            }
        }
        return redirect()->route('categoryOrTag', $urlQueryParams, 301);
    }


}