<?php
/**
 * @author Daniel Knudsen <d.knudsen@spawntree.de>
 * @date 11.07.22
 */

require_once('Product.php');

class ApiExact
{
    const API_URL = "https://start.exactonline.de/api";
    const CLIENT_ID = "5a04d118-349c-4750-aac3-fa3a386999c6";
    const CLIENT_SECRET = "E7Wuqcsp4Lih";
    const ACCESS_TOKEN_VALID_DURATION = 600 - 50;

    const DIVISION = '58687';
    const ITEM_GROUP_UUID = 'df17bdaf-2af7-4e9f-8d60-326e36b57764';
    const PRODUCT_CODE_PREFIX = "WR";

    public function getAccessToken()
    {
        $tokenData = json_decode(file_get_contents('./tokenData', true));
        if (!property_exists($tokenData, 'expiry_time') || (int)$tokenData->expiry_time < time()) {
            $postData = array(
                'grant_type' => 'refresh_token',
                'refresh_token' => $tokenData->refresh_token,
                'client_id' => self::CLIENT_ID,
                'client_secret' => self::CLIENT_SECRET
            );

            $ch = curl_init();
            curl_setopt_array($ch, array(
                CURLOPT_URL => self::API_URL . '/oauth2/token',
                CURLOPT_RETURNTRANSFER => TRUE,
                CURLOPT_HTTPHEADER => array('Content-Type: application/x-www-form-urlencoded'),
                CURLOPT_POSTFIELDS => http_build_query($postData)
            ));

            $response = curl_exec($ch);
            curl_close($ch);

            $jsonResult = json_decode($response);

            if (property_exists($jsonResult, 'error')) {
                $msg = $jsonResult->error;
                throw new Exception($msg);
            }


            $jsonResult->expiry_time = time() + self::ACCESS_TOKEN_VALID_DURATION;
            file_put_contents('./tokenData', json_encode($jsonResult));

            $tokenData = json_decode(file_get_contents('./tokenData', true));
        }
        return $tokenData->access_token;
    }

    public function getProducts()
    {
        $baseUrl = self::API_URL . '/v1/' . self::DIVISION . "/bulk/Logistics/Items?";
        $fields = [
            'ID',
            'StandardSalesPrice',
            'SalesVatCode',
            'SalesVatCodeDescription',
            'Description',
            'ExtraDescription',
            'IsWebshopItem',
            'ItemGroup',
            'ItemGroupCode',
            'Stock',
            'NetWeight',
            'GrossWeight',
            'Code'
        ];
        $filter = "\$filter=ItemGroup eq guid'".self::ITEM_GROUP_UUID."'";
        $select = "&\$select=".$this->getFieldString($fields);
        $requestUrl = $baseUrl . $filter . $select;
        $response = $this->getApiData($requestUrl);
        $responseArr = json_decode($response, 1)['d']['results'];

        $res = [];
        foreach ($responseArr as $productItem) {
            if (
                array_key_exists('IsWebshopItem', $productItem) &&
                $productItem['IsWebshopItem'] === 1 &&
                array_key_exists('Code', $productItem) &&
                stripos(strtoupper($productItem['Code']), self::PRODUCT_CODE_PREFIX) === 0
            ) {
                $res[] = Product::createProductFromApiItem($productItem);
            }
        }
        return $res;
    }

    private function getApiData($url)
    {
        $ch = curl_init();
        curl_setopt_array($ch, array(
            CURLOPT_URL => $url,
            CURLOPT_HTTPHEADER => array('Accept: application/json' , "Authorization: Bearer " . $this->getAccessToken() ),
            CURLOPT_RETURNTRANSFER => TRUE,
        ));
        return curl_exec($ch);
    }

    private function getFieldString($fields)
    {
        $res = '';
        $cnt = count($fields);
        $i = 1;
        foreach ($fields as $field) {
            $res .= $cnt !== $i ? $field . ',' : $field;
            $i++;
        }
        return $res;
    }

}