<?php

namespace Modules\PrintSuppliers\Controllers\Services;

use Exception;
use Modules\PrintSuppliers\Controllers\Controller;
use GuzzleHttp\Client;

class PrintifyExpressService extends Controller
{
    private $shopId, $apiToken, $client;

    /* 
        https://printify.com/app/products/6/gildan/unisex-heavy-cotton-tee
        https://printify.com/app/products/12/bellacanvas/unisex-jersey-short-sleeve-tee
    */
    protected $blueprintExpress = [6, 12];

    public function __construct()
    {
        $this->setShopId();
    }

    public function setShopId($shopId = null)
    {
        list($this->shopId, $this->apiToken) = $this->getCredential($shopId);
        $this->client = new Client([
            'headers' => [
                'Authorization' => 'Bearer ' . $this->apiToken,
                'Content-Type' => 'application/json'
            ]
        ]);
    }

    public function canExpressFulfill($orderDetail, $lineItems)
    {
        // return true; // test condition

        $isValidshippingMethod = isset($orderDetail['shipping_type']) && in_array($orderDetail['shipping_type'], ['express', 'premium']) ? true : false;
    
        if (!$isValidshippingMethod) return [
            'status' => false,
            'reason' => $orderDetail['shipping_type']
        ];

        for ($i = 0; $i < count($lineItems); $i++) {

            $lineItem = $lineItems[$i];

            if (!in_array($lineItem['blueprint_id'], $this->blueprintExpress)) {
                return [
                    'status' => false,
                    'reason' => $lineItem['blueprint_id']
                ];
            }

            if (!isset($lineItem['print_areas']['front']) || count($lineItem['print_areas']) > 1) {
                return [
                    'status' => false,
                    'reason' => $lineItem['print_areas'] ?? 'print_areas'
                ];
            }

        }

        return true;
    }

    public function fulfill($orderSchema)
    {
        $endPoint = 'https://api.printify.com/v1/shops/' . $this->shopId . '/orders/express.json';

        $httpResponse = $this->client->post($endPoint, [
            'json' => $orderSchema
        ]);

        return json_decode($httpResponse->getBody(), true);
    }

    public function getExpressLineItems($lineItems) 
    {
        $expressLineItems = [];

        for ($i = 0; $i < count($lineItems); $i++) {

            $lineItem = $lineItems[$i];
            $product = $this->createPrintifyProduct($lineItem);

            if (!empty($product['id'])) {
                $expressLineItems[] = [
                    "product_id" => $product['id'],
                    "variant_id" => $lineItem['variant_id'],
                    "quantity" => $lineItem['quantity']
                ];
            } else {
                throw new Exception('Error! CreatePrintifyProduct fail. | ' . json_encode($lineItem));
            }

        }

        return $expressLineItems;
    }

    private function createPrintifyProduct($item) 
    {
        $data = [
            "title" => "Product " . $item['variant_id'] . "_ATFF_" . time(),
            "description" => "Product for auto fulfill express delivery",
            "blueprint_id" => intval($item['blueprint_id']),
            "print_provider_id" => intval($item['print_provider_id']),
            "variants" => [
                [
                    "id" => intval($item['variant_id']),
                    "is_enabled" => true,
                    "price" => floatval(1),
                ]
            ],
            "print_areas" => [
                [
                    "variant_ids" => [intval($item['variant_id'])],
                    "placeholders" => []
                ]
            ]
        ];
    
        // make design placeholders
        // $designUrl = null;
        $designUrl = $item['print_areas']['front'] ?? null;

        // in task order, auto fulfill must create product with only front print
        if (!$designUrl) throw new Exception('Front print area not found!! | ' . json_encode($item));

        $imageResponse = $this->uploadPrintifyImage($designUrl);

        // create placeholder
        $data['print_areas'][0]['placeholders'] = [
            [
                "position" => "front",
                "images" => [
                    [
                        "id" => $imageResponse['id'], 
                        "x" => 0.5, 
                        "y" => 0.5, 
                        "scale" => 1,
                        "angle" => 0
                    ]
                ]
            ]
        ];

        // post create product
        $httpResponse = $this->client->post("https://api.printify.com/v1/shops/{$this->shopId}/products.json", [
            'json' => $data
        ]);

        return json_decode($httpResponse->getBody(), true);

    }

    private function getFileNameFromUrlRegex($url) {
        if (preg_match("/[^\/]+$/", $url, $matches)) {
            return $matches[0];  // Return the matched file name
        }
        return null;  // Return null if no file name is found
    }

    private function uploadPrintifyImage($designUrl)
    {
        $httpResponse = $this->client->post("https://api.printify.com/v1/uploads/images.json", [
            'json' => [
                "file_name" => $this->getFileNameFromUrlRegex($designUrl),
                "url" => $designUrl
            ]
        ]);

        return json_decode($httpResponse->getBody(), true);
    }
}