<?php

use Carbon\Carbon;
use Hilco\Models\Order;
use Hilco\Models\Promotion;
use Hilco\Models\SalesOrderLine;
use Hilco\Models\WebAsset;
use Hilco\Models\WebCart;
use Hilco\Models\WebCategory;
use Hilco\Models\WebCollection;
use Hilco\Models\WebFamily;
use Hilco\Models\WebGroup;
use Hilco\Models\WebLandingPage;
use Hilco\Models\WebPart;

if (! function_exists('createAssetAccessToken')) {
    function createAssetAccessToken() {
        $salt = config('hilco.assets.tokenSalt');
        $timestamp = Carbon::now()->getTimestamp();
        return ['timestamp' => $timestamp, 'token' => md5($salt . $timestamp . $salt . $timestamp . $salt)];
    }
}

if (! function_exists('validateAssetAccessToken')) {
    function validateAssetAccessToken($token, $timestamp) {
        $salt = config('hilco.assets.tokenSalt');
        $now = Carbon::now();
        $then = Carbon::createFromTimestamp($timestamp);
        if ($now->subMinutes(5) > $then) return false;
        return $token == md5($salt . $timestamp . $salt . $timestamp . $salt);
    }
}

if (! function_exists('webAssetUrl')) {
    function webAssetUrl($options) {
        return WebAsset::urlHelper($options);
    }
}

if (! function_exists('webLinkUrl')) {
    function webLinkUrl($options, $alternateLogId = false) {
        $url = '';
        if (is_array($options)){
            switch (\Illuminate\Support\Arr::get($options, 'type', 'url')) {
                case 'url':
                    $url = \Illuminate\Support\Arr::get($options, 'target', '');
                    break;
                case 'webLandingPage':
                    $url = route('landingpage.slug', [\Illuminate\Support\Arr::get($options, 'target')]);
                    break;
                case 'webAsset':
                    $url = WebAsset::urlHelper(['id' => $options['target'], 'download' => true, 'token' => true]);
                    break;
            }
        } else {
            $url = $options;
        }

        if ($alternateLogId !== false){
            if (str_contains($url, '?')) {
                $url .= "&e=pli&e2=$alternateLogId";
            } else {
                $url .= "?e=pli&e2=$alternateLogId";
            }
        }
        return $url;
    }
}

if (! function_exists('webLinkTitle')) {
    function webLinkTitle($options) {
        $target = \Illuminate\Support\Arr::get($options, 'target', '');
        switch (\Illuminate\Support\Arr::get($options, 'type', 'url')) {
            case 'url':
                return $target;
            case 'webLandingPage':
                $webLandingPage = WebLandingPage::whereSlug($target)->first();
                return $webLandingPage ? $webLandingPage->name : '';
            case 'webAsset':
                $webAsset = WebAsset::find($target);
                return $webAsset ? $webAsset->name : '';
        }
    }
}

if (!function_exists('productLink')) {
    function productLink($type, $id) {
        switch ($type) {
            case 'webFamily':
            case 'Family':
                return '/f/' . WebFamily::find($id)->slug;
            case 'webCollection':
            case 'Collection':
                return '/l/' . WebCollection::find($id)->slug;
            case 'webCategory':
            case 'Category':
                return '/c/' . WebCategory::find($id)->slug;
            case 'webGroup':
            case 'Group':
                return '/g/' . WebGroup::find($id)->slug;
        }
        return false;
    }
}

if (!function_exists('productModel')) {
    function productModel($type, $id) {
        switch ($type) {
            case 'webFamily':
            case 'Family':
                return WebFamily::with('assets')->find($id);
            case 'webCollection':
            case 'Collection':
                return WebCollection::with('assets')->find($id);
            case 'webCategory':
            case 'Category':
                return WebCategory::with('assets')->find($id);
            case 'webGroup':
            case 'Group':
                return WebGroup::with('assets')->find($id);
        }
        return null;
    }
}

if (!function_exists('b2bLink')) {
    function b2bLink($model) {
        $url = config('hilco.b2b.url', false);
        if (!$url) return false;
        switch (get_class($model)) {
            case WebPart::class:
                return $url . '/p/' . $model->id;
            case WebFamily::class:
                return $url . '/f/' . $model->slug;
            case WebCollection::class:
                return $url . '/l/' . $model->slug;
            case WebCategory::class:
                return $url . '/c/' . $model->slug;
            case WebGroup::class:
                return $url . '/g/' . $model->slug;
            case WebLandingPage::class:
                return $url . '/lp/' . $model->slug;
        }
        return false;
    }
}

if (!function_exists('canUser')) {
    function canUser($permission) {
        $user = Auth::user();
        if (is_null($user)) return false;
        return $user->can($permission);
    }
}

if (!function_exists('rewards')) {
    function rewards() {
        return app('rewards');
    }
}

if (!function_exists('transDefault')) {
    function transDefault($id = null, $default = null, $parameters = [], $domain = 'messages', $locale = null) {
        $value = trans($id, $parameters, $domain, $locale);
        return ($value == $id) ? $default : $value;
    }
}

if (!function_exists('generateUUID')) {
    function generateUUID() {
        return DB::select(DB::raw('SELECT UuidToBin(uuid()) as uuid;')->getValue(DB::connection('hilco-live')->getQueryGrammar()))[0]->uuid;
    }
}

if (!function_exists('b2b')) {
    /**
     * @return \Hilco\B2BHelper
     */
    function b2b() {
        return app('b2b');
    }
}

if (!function_exists('m3')) {
    /**
     * @return \Hilco\M3Helper
     */
    function m3() {
        return app('m3');
    }
}

if (!function_exists('array_increment')) {
    function array_increment(&$array, $key, $incrementBy = 1) {
        return \Illuminate\Support\Arr::set($array, $key, \Illuminate\Support\Arr::get($array, $key, 0) + $incrementBy);
    }
}

if (!function_exists('normalizeProductType')) {
    function normalizeProductType($type) {
        switch ($type) {
            case 'Group':
            case 'webGroup':
                return 'webGroup';
            case 'Category':
            case 'webCategory':
                return 'webCategory';
            case 'Collection':
            case 'webCollection':
                return 'webCollection';
            case 'Family':
            case 'webFamily':
                return 'webFamily';
            case 'Part':
            case 'webPart':
                return 'webPart';
        }

        return $type;
    }
}

if (!function_exists('croakies')) {
    /**
     * @return \Hilco\CroakiesHelper
     */
    function croakies() {
        return app('croakies');
    }
}

if (!function_exists('fileSafeName')) {
    function fileSafeName($str) {
        return str_replace(['"','\\',' ',':','?','<','>','&','|','/','.'], '_', $str);
    }
}

if (!function_exists('extractLinks')) {
    function extractLinks($bladeArgs){
        $res = [];
        if (is_array($bladeArgs)){
            foreach($bladeArgs as $key=>$arg){
                if ($key === 'link'){
                    if (is_array($arg)) {
                        $res[] = json_encode($arg);
                    }else{
                        $res[] = $arg;
                    }
                }else{
                    $res = array_merge($res, extractLinks($arg));
                }
            }
        }
        return $res;
    }
}
if (!function_exists('inDateRange')) {
    function inDateRange($visibleDates) {
        $startDate = Arr::get($visibleDates, 'startDate', '');
        $endDate = Arr::get($visibleDates, 'endDate', '');

        if (preg_match('/\d\d\/\d\d\/\d\d\d\d/', $startDate) === 1){
            $startDateCarbon = Carbon::createFromFormat('m/d/Y', $startDate)->startOfDay();
        } else if (preg_match('/\d\d\d\d-\d\d-\d\d/', $startDate)) {
            $startDateCarbon = Carbon::createFromFormat('Y-m-d', $startDate)->startOfDay();
        } else {
            $startDateCarbon = Carbon::minValue();
        }


        if (preg_match('/\d\d\/\d\d\/\d\d\d\d/', $endDate) === 1){
            $endDateCarbon = Carbon::createFromFormat('m/d/Y', $endDate)->endOfDay();
        } else if (preg_match('/\d\d\d\d-\d\d-\d\d/', $endDate)) {
            $endDateCarbon = Carbon::createFromFormat('Y-m-d', $endDate)->endOfDay();
        } else {
            $endDateCarbon = Carbon::maxValue();
        }

        return Carbon::now()->between($startDateCarbon, $endDateCarbon);
    }
}

if (!function_exists('customerIsTargeted')) {
    function customerIsTargeted($targetCustomers, $customer = false) {
        $result = false;

        if ($customer === false){
            $customer = b2b()->activeCustomer();            
        }
        if ($customer) {
            if (Arr::get($targetCustomers, 'allUsers', 0)){
                $result = 'allUsers';
            }
            if ($result === false && in_array($customer->bill_state, Arr::get($targetCustomers, 'billingState' ,[]))){
                $result = 'billingState';
            }

            $targetedRewardsOptions = Arr::get($targetCustomers, 'rewardsTiers', []); // todo "rewardsTiers" is deprecated terminology
            if ($result === false && count($targetedRewardsOptions) > 0){
                $rewardsPromotion = Promotion::find(config('hilco.rewardsPromotionId'));
                if (isset($rewardsPromotion)) {
                    $klaviyoListId = "";
                    foreach ($rewardsPromotion->triggers as $trigger) {
                        if ($trigger->trigger_type == 'klaviyoListTrigger') {
                            $klaviyoListId = $trigger->details->klaviyo_list;
                            break;
                        }
                    }
                    $isRewardsQualifying = $customer->isRewardsQualifying($rewardsPromotion, auth()->user());
                    $isRewardsEnrolled = $customer->isRewardsEnrolled($klaviyoListId);
                    // See definition of variable array rewardsTier in b2b-shared blade ...components/targetCustomer/viewFunctions
                    if ($isRewardsQualifying && $isRewardsEnrolled) {
                        $rewardsValue = "0";
                    } else if ($isRewardsQualifying && !$isRewardsEnrolled) {
                        $rewardsValue = "1";
                    } else if (!$isRewardsQualifying && $isRewardsEnrolled) {
                        $rewardsValue = "2";
                    } else {
                        $rewardsValue = "3";
                    }
                    if (in_array($rewardsValue, $targetedRewardsOptions)) {
                        $result = 'rewardsTiers';
                    }
                }
            }

            if ($result === false && in_array($customer->overrideCustomerCategory->cust_category, Arr::get($targetCustomers, 'customerCategories', []))){
                $result = 'customerCategories';
            }
            if ($result === false && auth()->user()->webUserPersonas->filter(function ($webUserPersona) use ($targetCustomers){
                    $viewPersonas = collect(Arr::get($targetCustomers, 'userPersonas' ,[]));
                    return $viewPersonas->contains($webUserPersona->slug);
                })->count() > 0){
                $result = 'userPersonas';
            }

            $productsInCart = Arr::get($targetCustomers, 'productsInCart', []);
            if (!$result && count($productsInCart)){
                $webGroups = [];
                $webCategories = [];
                $webCollections = [];
                $webFamilies = [];
                $webParts = [];
                foreach ($productsInCart as $productInCart){
                    switch (Arr::get($productInCart, 'table_type', '')) {
                        case 'webGroup':
                            $webGroups[] = Arr::get($productInCart, 'id', '');
                            break;
                        case 'webCategory':
                            $webCategories[] = Arr::get($productInCart, 'id', '');
                            break;
                        case 'webCollection':
                            $webCollections[] = Arr::get($productInCart, 'id', '');
                            break;
                        case 'webFamily':
                            $webFamilies[] = Arr::get($productInCart, 'id', '');
                            break;
                        case 'webPart':
                            $webParts[] = Arr::get($productInCart, 'id', '');
                            break;
                    }
                }

                if ($result === false && WebCart::getWebCartItems()->filter(function ($webCartItem) use ($webGroups, $webCategories, $webCollections, $webFamilies, $webParts){
                    return in_array($webCartItem->webPart->id, $webParts) || $webCartItem->webPart->webFamilies->filter(function ($webFamily) use ($webGroups, $webCategories, $webCollections, $webFamilies){
                        return in_array($webFamily->id, $webFamilies) || $webFamily->webCollections->filter(function ($webCollection) use ($webGroups, $webCategories, $webCollections){
                            return in_array($webCollection->id, $webCollections) || $webCollection->webCategories->filter(function ($webCategory) use ($webGroups, $webCategories){
                                return in_array($webCategory->id, $webCategories) || $webCategory->webGroups->filter(function ($webGroup) use ($webGroups){
                                    return in_array($webGroup->id, $webGroups);
                                })->count() > 0;
                            })->count() > 0;
                        })->count() > 0;
                    })->count() > 0;
                })->count() > 0){
                    $result = 'productsInCart';
                }
            }


            $productsInHistory = Arr::get($targetCustomers, 'productsInHistory', []);
            if (!$result && count($productsInHistory)) {
                $webGroups = [];
                $webCategories = [];
                $webCollections = [];
                $webFamilies = [];
                $webParts = [];
                foreach ($productsInHistory as $productInHistory) {
                    switch (Arr::get($productInHistory, 'table_type', '')) {
                        case 'webGroup':
                            $webGroups[] = Arr::get($productInHistory, 'id', '');
                            break;
                        case 'webCategory':
                            $webCategories[] = Arr::get($productInHistory, 'id', '');
                            break;
                        case 'webCollection':
                            $webCollections[] = Arr::get($productInHistory, 'id', '');
                            break;
                        case 'webFamily':
                            $webFamilies[] = Arr::get($productInHistory, 'id', '');
                            break;
                        case 'webPart':
                            $webParts[] = Arr::get($productInHistory, 'id', '');
                            break;
                    }
                }

                if ($result === false && (count($webParts) && DB::select(DB::raw("SELECT EXISTS(
    SELECT 1 FROM SalesOrders WHERE
        SalesOrders.soldto_customer_id = ?
        AND SalesOrders.deleted_at=0
        AND EXISTS( 
            SELECT 1 FROM SalesOrderLines WHERE 
                SalesOrderLines.salesorder_id = SalesOrders.id
                AND SalesOrderLines.deleted_at=0
                AND (
                    EXISTS (
                        SELECT 1 FROM WebParts, Parts 
                        	WHERE WebParts.part_id = Parts.id 
                        	AND Parts.deleted_at=0 
                            AND Parts.id = SalesOrderLines.part_id 
                            AND WebParts.deleted_at=0
                            AND WebParts.id IN (".implode('?', array_fill(0, count($webParts), '?')).")
                    )
                )
        )
) as `exists`")->getValue(DB::connection('hilco-live')->getQueryGrammar()), array_merge([$customer->id], $webParts))[0]->exists)){
                    $result = 'productsInHistory';
                }

                if ($result === false && (count($webFamilies) && DB::select(DB::raw("SELECT EXISTS(
    SELECT 1 FROM SalesOrders WHERE
        SalesOrders.soldto_customer_id = ?
        AND SalesOrders.deleted_at=0
        AND EXISTS( 
            SELECT 1 FROM SalesOrderLines WHERE 
                SalesOrderLines.salesorder_id = SalesOrders.id
                AND SalesOrderLines.deleted_at=0
                AND (
                    EXISTS (
                        SELECT 1 FROM WebParts, Parts 
                        	WHERE WebParts.part_id = Parts.id 
                        	AND Parts.deleted_at=0 
                            AND Parts.id = SalesOrderLines.part_id 
                            AND WebParts.deleted_at=0
                            AND EXISTS (
                                SELECT 1 FROM WebFamilies, WebPart_WebFamily 
                                	WHERE WebPart_WebFamily.webpart_id=WebParts.id 
                                	AND WebPart_WebFamily.deleted_at=0
                                    AND WebFamilies.id = WebPart_WebFamily.webfamily_id  
                                    AND WebFamilies.deleted_at=0
                                    AND WebFamilies.id IN (".implode('?', array_fill(0, count($webFamilies), '?')).")
                            )
                    )
                )
        )
) as `exists`")->getValue(DB::connection('hilco-live')->getQueryGrammar()), array_merge([$customer->id], $webFamilies))[0]->exists)){
                    $result = 'productsInHistory';
                }

                if ($result === false && (count($webCollections) && DB::select(DB::raw("SELECT EXISTS(
    SELECT 1 FROM SalesOrders WHERE
        SalesOrders.soldto_customer_id = ?
        AND SalesOrders.deleted_at=0
        AND EXISTS( 
            SELECT 1 FROM SalesOrderLines WHERE 
                SalesOrderLines.salesorder_id = SalesOrders.id
                AND SalesOrderLines.deleted_at=0
                AND (
                    EXISTS (
                        SELECT 1 FROM WebParts, Parts 
                        	WHERE WebParts.part_id = Parts.id 
                        	AND Parts.deleted_at=0 
                            AND Parts.id = SalesOrderLines.part_id 
                            AND WebParts.deleted_at=0
                            AND EXISTS (
                                SELECT 1 FROM WebFamilies, WebPart_WebFamily 
                                	WHERE WebPart_WebFamily.webpart_id=WebParts.id 
                                	AND WebPart_WebFamily.deleted_at=0
                                    AND WebFamilies.id = WebPart_WebFamily.webfamily_id  
                                    AND WebFamilies.deleted_at=0
                                    AND EXISTS (
                                        SELECT 1 FROM WebCollections, WebFamily_WebCollection
                                            WHERE WebFamily_WebCollection.webfamily_id=WebFamilies.id 
                                            AND WebFamily_WebCollection.deleted_at=0
                                            AND WebCollections.id = WebFamily_WebCollection.webcollection_id 
                                            AND WebCollections.deleted_at=0
                                            AND WebCollections.id IN (".implode('?', array_fill(0, count($webCollections), '?')).")
                                    )
                            )
                    )
                )
        )
) as `exists`")->getValue(DB::connection('hilco-live')->getQueryGrammar()), array_merge([$customer->id], $webCollections))[0]->exists)){
                    $result = 'productsInHistory';
                }

                if ($result === false && (count($webCategories) && DB::select(DB::raw("SELECT EXISTS(
    SELECT 1 FROM SalesOrders WHERE
        SalesOrders.soldto_customer_id = ?
        AND SalesOrders.deleted_at=0
        AND EXISTS( 
            SELECT 1 FROM SalesOrderLines WHERE 
                SalesOrderLines.salesorder_id = SalesOrders.id
                AND SalesOrderLines.deleted_at=0
                AND (
                    EXISTS (
                        SELECT 1 FROM WebParts, Parts 
                        	WHERE WebParts.part_id = Parts.id 
                        	AND Parts.deleted_at=0 
                            AND Parts.id = SalesOrderLines.part_id 
                            AND WebParts.deleted_at=0
                            AND EXISTS (
                                SELECT 1 FROM WebFamilies, WebPart_WebFamily 
                                	WHERE WebPart_WebFamily.webpart_id=WebParts.id 
                                	AND WebPart_WebFamily.deleted_at=0
                                    AND WebFamilies.id = WebPart_WebFamily.webfamily_id  
                                    AND WebFamilies.deleted_at=0
                                    AND EXISTS (
                                        SELECT 1 FROM WebCollections, WebFamily_WebCollection
                                            WHERE WebFamily_WebCollection.webfamily_id=WebFamilies.id 
                                            AND WebFamily_WebCollection.deleted_at=0
                                            AND WebCollections.id = WebFamily_WebCollection.webcollection_id 
                                            AND WebCollections.deleted_at=0
                                            AND EXISTS (
                                                SELECT 1 FROM WebCategories, WebCollection_WebCategory
                                                    WHERE WebCollection_WebCategory.webcollection_id=WebCollections.id
                                                    AND WebCollection_WebCategory.deleted_at=0
                                                    AND WebCategories.id = WebCollection_WebCategory.webcategory_id 
                                                    AND WebCategories.deleted_at=0
                                                    AND WebCategories.id IN (".implode('?', array_fill(0, count($webCategories), '?')).")
                                            )
                                    )
                            )
                    )
                )
        )
) as `exists`")->getValue(DB::connection('hilco-live')->getQueryGrammar()), array_merge([$customer->id], $webCategories))[0]->exists)){
                    $result = 'productsInHistory';
                }

                if ($result === false && (count($webGroups) && DB::select(DB::raw("SELECT EXISTS(
    SELECT 1 FROM SalesOrders WHERE
        SalesOrders.soldto_customer_id = ?
        AND SalesOrders.deleted_at=0
        AND EXISTS( 
            SELECT 1 FROM SalesOrderLines WHERE 
                SalesOrderLines.salesorder_id = SalesOrders.id
                AND SalesOrderLines.deleted_at=0
                AND (
                    EXISTS (
                        SELECT 1 FROM WebParts, Parts 
                        	WHERE WebParts.part_id = Parts.id 
                        	AND Parts.deleted_at=0 
                            AND Parts.id = SalesOrderLines.part_id 
                            AND WebParts.deleted_at=0
                            AND EXISTS (
                                SELECT 1 FROM WebFamilies, WebPart_WebFamily 
                                	WHERE WebPart_WebFamily.webpart_id=WebParts.id 
                                	AND WebPart_WebFamily.deleted_at=0
                                    AND WebFamilies.id = WebPart_WebFamily.webfamily_id  
                                    AND WebFamilies.deleted_at=0
                                    AND EXISTS (
                                        SELECT 1 FROM WebCollections, WebFamily_WebCollection
                                            WHERE WebFamily_WebCollection.webfamily_id=WebFamilies.id 
                                            AND WebFamily_WebCollection.deleted_at=0
                                            AND WebCollections.id = WebFamily_WebCollection.webcollection_id 
                                            AND WebCollections.deleted_at=0
                                            AND EXISTS (
                                                SELECT 1 FROM WebCategories, WebCollection_WebCategory
                                                    WHERE WebCollection_WebCategory.webcollection_id=WebCollections.id
                                                    AND WebCollection_WebCategory.deleted_at=0
                                                    AND WebCategories.id = WebCollection_WebCategory.webcategory_id  
                                                    AND WebCategories.deleted_at=0
                                                    AND EXISTS (
                                                        SELECT 1 FROM WebGroups, WebCategory_WebGroup
                                                            WHERE WebCategory_WebGroup.webcategory_id=WebCategories.id
                                                            AND WebCategory_WebGroup.deleted_at=0
                                                            AND WebGroups.id = WebCategory_WebGroup.webgroup_id 
                                                            AND WebGroups.deleted_at=0
                                                            AND WebGroups.id IN (".implode('?', array_fill(0, count($webGroups), '?')).")
                                                    )
                                            )
                                    )
                            )
                    )
                )
        )
) as `exists`")->getValue(DB::connection('hilco-live')->getQueryGrammar()), array_merge([$customer->id], $webGroups))[0]->exists)){
                    $result = 'productsInHistory';
                }
            }
        }

        return $result;
    }
}
