<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\CopyProductContents;
use App\Http\Requests\Admin\ImportProductImage;
use App\Models\Product;
use App\Models\Order;
use App\SAP\SAPClient;
use Illuminate\Http\Request;
use App\SAP\SAPService;
use App\Shopify\ShopifyService;
use App\Jobs\SAP\CreateSapOrderJob;

/**
 * Controller class that supports Shopify App backoffice manual sync tools
 */
class SyncController extends Controller
{
    /**
     * Makes request to SAP API
     *
     * @var SAPClient
     */
    private $sapClient;

    /**
     * Constructor.
     *
     * @param SAPClient $sapClient
     */
    public function __construct(SAPClient $sapClient)
    {
        $this->sapClient = $sapClient;
    }

    /**
     * Syncs full product data (with prices) from SAP
     *
     * @param SAPService $service
     * @return void
     */
    public function completeSync(SAPService $service)
    {
        $service->syncCatalog();
        return ['success' => true];
    }

    /**
     * Syncs only price data from SAP
     *
     * @param SAPService $service
     * @return void
     */
    public function pricesSync(SAPService $service)
    {
        $service->syncProducts(true);
        return ['success' => true];
    }

    /**
     * Sends pending products updates to shopify in batches of 500 (ShopifyService::PRODUCT_SYNC_CHUNCK_SIZE)
     *
     * @param ShopifyService $shopifyService
     * @return void
     */
    public function shopifyProductsSync(ShopifyService $shopifyService)
    {
        $shopifyService->syncProducts();
        return ['success' => true];
    }

    /**
     * Sends pending product prices / stock updates to shopify in batches of 500 (ShopifyService::PRODUCT_SYNC_CHUNCK_SIZE)
     *
     * @param ShopifyService $shopifyService
     * @return void
     */
    public function shopifyPricesSync(ShopifyService $shopifyService)
    {
        $shopifyService->syncPrices();
        return ['success' => true];
    }

    /**
     * Checks SAP for orders status changes
     *
     * @param SapService $sapService
     * @return array
     */
    public function sapOrdersStatusCheck(SapService $sapService)
    {
        $sapService->checkOrdersStatus();
        return ['success' => true];
    }

    /**
     * Sends (updates) a specific product to Shopify even if not marked to be synced
     *
     * @param Request $request
     * @param ShopifyService $shopifyService
     * @return void
     */
    public function shopifyProductSync(Request $request, ShopifyService $shopifyService)
    {
        $sapId = $request->input('sapId');
        if (!$sapId) {
            return ['success' => false, 'message' => 'Enter product SAP ID first'];
        }
        $sapId = str_pad($sapId, 18, "0", STR_PAD_LEFT);
        $product = Product::where('sap_matnr', $sapId)->first();
        if (!$product) {
            return ['success' => false, 'message' => 'Product not found!'];
        }
        $syncData = $product->price->sync_data;
        $syncData['toSync'] = [
            'price' => true,
            'quant' => true,
            'info' => true,
            'avail' => false
        ];
        $product->price->sync_data = $syncData;
        $success = $shopifyService->syncProduct($product);

        if ($success && !$product->is_parent) {
            $success = $shopifyService->syncPrice($product->price, true);
        } else if ($success && $product->is_parent) {
            foreach ($product->childProducts as $childProduct) {
                $success = $success && $shopifyService->syncPrice($childProduct->price, true);
            }
        }
        if (!$success) {
            return ['success' => false, 'message' => 'Error importing product: check logs'];
        }
        return ['success' => $success];
    }

    /**
     * Syncs collections with Shopify (updates in Shopify) even if not marked for update (force)
     *
     * @param ShopifyService $shopifyService
     * @return void
     */
    public function shopifyCollectionsSync(ShopifyService $shopifyService)
    {
        $shopifyService->syncCollections(true);
        return ['success' => true];
    }

    /**
     * Syncs a specific order current state with shopify (fulfills and refunds)
     *
     * @param Request $request
     * @param ShopifyService $shopifyService
     * @return void
     */
    public function shopifyUpdateOrder(Request $request, ShopifyService $shopifyService)
    {
        $shopifyId = $request->input('shopifyId');
        if (!$shopifyId) {
            return ['success' => false, 'message' => 'Enter order shopify Id first'];
        }
        $order = Order::where('shopify_id', $shopifyId)->first();
        if (!$order) {
            return ['success' => false, 'message' => 'Order not found!'];
        }

        $success = $shopifyService->orderStatusUpdate($order);

        if (!$success) {
            return ['success' => false, 'message' => 'Error Updating order'];
        }
        return ['success' => $success];
    }

    /**
     * Helper endpoint that exposes a given product SAP raw info
     *
     * @param Request $request
     * @param SapService $service
     * @return void
     */
    public function sapCheckProductData(Request $request, SapService $service)
    {
        $sapId = $request->input('sapId');
        if (!$sapId) {
            return ['success' => false, 'message' => 'Enter product SAP ID first'];
        }
        $sapId = str_pad($sapId, 18, "0", STR_PAD_LEFT);

        $productData = $service->getSapProductData($sapId);

        return [
            'message' => $productData
        ];
    }

    /**
     * Syncs a given order from Shopify to the integration system. This can be helpfull if, for some reason,
     * the Shopify webhook for paid order even failed for some reason. In general this is NOT needed
     *
     * @param Request $request
     * @param ShopifyService $service
     * @return void
     */
    public function shopifyOrderSync(Request $request, ShopifyService $service)
    {
        $orderId = $request->input('shopifyId');
        if (!$orderId) {
            return ['success' => false, 'message' => 'Enter an order ID first'];
        }
        try {
            $order = $service->syncShopifyOrder($orderId);

            if (empty($order->sap_order_nr) && $order->financial_status === 'paid') {
                CreateSapOrderJob::dispatch($order);
            }

            return [
                'success' => true,
                'message' => $order
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * Endpoint to support helper tool that updates products images (one by one)
     *
     * @param Request $request
     * @param ShopifyService $service
     * @return void
     */
    public function ShopifyReplaceImages(ImportProductImage $request, ShopifyService $service)
    {
        $baseUrl = $request->input('baseUrl');
        $image = $request->input('image');

        $status = $service->replaceProductImage($image, $baseUrl);

        return [
            'success' => $status
        ];
    }

    /**
     * Endpoint that support product editorial content copy tool
     *
     * @param CopyProductContents $request
     * @param ShopifyService $service
     * @return void
     */
    public function copyProductContents(CopyProductContents $request, ShopifyService $service)
    {
        $source = $request->input('source');
        $target = $request->input('target');

        try {
            $service->copyProductContents($source, $target);
        } catch(\Exception $e) {
            return [
                'success' => false,
                'message' => 'Error: ' . $e->getMessage()
            ];
        }

        return [
            'success' => 'Copy successfull'
        ];
    }
}
