<?php

namespace Modules\PrintSuppliers\Controllers\Build;

use DB;
use Illuminate\Http\Request;
use Modules\PrintSuppliers\Controllers\Controller;

class PrinfityVariantStatusController extends Controller
{
    public function build(Request $request) {
        $blueprintIds = $request->get('blueprint_ids');
        $retVal = [
            'status' => 'fail',
        ];
        if (!$blueprintIds) {
            $retVal['message'] = 'blueprint_ids is required';
            return $retVal;
        }

        $templateId = $request->get('template_id');

        if (!$templateId) {
            $retVal['message'] = 'template_id is required';
            return $retVal;
        }

        $inStockSlugs = [];
        foreach (explode(",", $blueprintIds) as $blueprintId) {
            $baseUrl = "https://api.printify.com/v1/catalog/blueprints/" . $blueprintId . "/print_providers";
            $res = $this->sendRequest($baseUrl . ".json");
            if ($res && is_array($res)) {
                foreach ($res as $provider) {
                    $url = $baseUrl . "/" . $provider['id'] . "/variants.json?show-out-of-stock=0";
                    $result = $this->sendRequest($url);
                    if ($result && !empty($result['variants'])) {
                        $slugs = $this->getVariantSlug($result['variants'], $this->getBlueprintMapVariant($blueprintId));
                        foreach ($slugs as $slug) {
                            $inStockSlugs[$slug] = 1;
                        }
                    }
                }
            }
        }

        $skues = DB::table('product_template_sku')->where('template_id', $templateId)->get(['id', 'status'])->keyBy('id');

        $skuBySlug = $this->getSkuBySlug($skues);

        $updateData = [];
        foreach ($skuBySlug as $slug => $skuId) {
            $sku = $skues[$skuId];
            if (isset($inStockSlugs[$slug]) && $sku->status != "ACTIVE") {
                $updateData[] = [
                    'id' => $skuId,
                    'slug' => $slug,
                    'status' => 'ACTIVE'
                ];
            } else if (!isset($inStockSlugs[$slug]) && $sku->status == "ACTIVE") {
                $updateData[] = [
                    'id' => $skuId,
                    'slug' => $slug,
                    'status' => 'PENDING'
                ];
            }
        }
        foreach ($updateData as $item) {
            DB::table('product_template_sku')->where('id', $item['id'])->update([
                'status' => $item['status']
            ]);

            DB::table('product_sku')->where('id', $item['id'])->update([
                'status' => $item['status']
            ]);
        }

        return [
            'status' => 'successful',
            'result' => [
                'updateData' => $updateData,
                'skuBySlug' => $skuBySlug,
                'inStockSlugs' => $inStockSlugs,
            ]
        ];
    }

    private function getBlueprintMapVariant($blueprintId) {
        switch ($blueprintId) {
            case 1135:
            case 1136:
            case 33:
            case 561:
            case 568:
            case 569:
            case 1011:
            case 1045:
                return [
                    "style" => 'short-sleeve-onesie'
                ];
                break;
            case 31:
            case 974:
                return [
                    "style" => 'long-sleeve-onesie'
                ];
                break;
            
            default:
                return [];
                break;
        }
    }

    private function getSkuBySlug($skues) {
        $skuValues = DB::table('product_template_sku_value')->whereIn('sku_id', $skues->pluck('id'))->get();
        $optionById = DB::table('product_variant_option')->whereIn('id', array_unique($skuValues->pluck('variant_option_id')->toArray()))->get(['id', 'variant_id', 'slug'])->keyBy('id');
        $variantById = DB::table('product_variant')->whereIn('id', array_unique($skuValues->pluck('variant_id')->toArray()))->get(['id', 'slug'])->keyBy('id');
        $optionBySkus = [];
        foreach ($skuValues as $item) {
            if (!isset($optionBySkus[$item->sku_id])) {
                $optionBySkus[$item->sku_id] = [];
            }
            $option = $optionById[$item->variant_option_id];
            $variant = $variantById[$option->variant_id];
            $optionBySkus[$item->sku_id][$variant->slug] = $option->slug;
        }
        $skuBySlug = [];
        foreach ($optionBySkus as $skuId => $options) {
            uksort($options, function ($a, $b) {
                return $a < $b ? -1 : ($a > $b ? 1 : 0);
            });
            $slugs = [];
            foreach ($options as $variantSlug => $optionSlug) {
                $slugs[] = $variantSlug . '_' . $optionSlug;
            }
            $skuBySlug[implode("|", $slugs)] = $skuId;
        }

        return $skuBySlug;
    }

    private function getVariantSlug($variants, $addionOptions = []) {
        $retVal = [];
        foreach ($variants as $item) {
            $item['options'] = array_merge($item['options'], $addionOptions);
            uksort($item['options'], function ($a, $b) {
                return $a < $b ? -1 : ($a > $b ? 1 : 0);
            });
            $slugs = [];
            foreach ($item['options'] as $variantSlug => $option) {
                $optionSlug = $this->slugify($option);
                $optionSlug = $this->mapOptionSlug($optionSlug);
                $slugs[] = $variantSlug . '_' . $optionSlug;
            }
            $retVal[] = implode("|", $slugs);
        }

        return $retVal;
    }

    public function slugify($text, string $divider = '-') {
        // replace non letter or digits by divider
        $text = preg_replace('~[^\pL\d]+~u', $divider, $text);

        // transliterate
        $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);

        // remove unwanted characters
        $text = preg_replace('~[^-\w]+~', '', $text);

        // trim
        $text = trim($text, $divider);

        // remove duplicate divider
        $text = preg_replace('~-+~', $divider, $text);

        // lowercase
        $text = strtolower($text);

        if (empty($text)) {
            return 'n-a';
        }

        return $text;
    }

    private function mapOptionSlug($optionSlug) {
        $retVal = $optionSlug;

        $slugMap = [
            '18-23m' => '18m',
            '1-12-18m' => '12m',
            '12-18m' => '12m',
            '6-12m' => '6m',
            '6-9m' => '6m',
            '3-6m' => '6m',
            '0-6-12m' => '6m',
            '00-3-6m' => '6m',
            '000-0-3m' => 'nb-0-3m',
            '0-3m' => 'nb-0-3m',
        ];

        if (isset($slugMap[$optionSlug])) {
            $retVal = $slugMap[$optionSlug];
        }

        return $retVal;
    }

    private function sendRequest($url, $method = "GET", $params = []) {
        $apiToken = config('print-suppliers::token.printify');
        return $this->triggerSyncRequest($url, $method, $params, [
            'Authorization: Bearer ' . $apiToken
        ]);
    }
}
