<?php

class FactoService
{
    private $baseUrl;
    private $clientId;
    private $clientSecret;
    private $username;
    private $password;
    private $accessToken = null;

    public function __construct()
    {
        $this->baseUrl = FACTO_API_BASE_URL;
        $this->clientId = FACTO_CLIENT_ID;
        $this->clientSecret = FACTO_CLIENT_SECRET;
        $this->username = FACTO_USERNAME;
        $this->password = FACTO_PASSWORD;
    }

    /**
     * Obtiene el token de autenticación
     */
    private function authenticate()
    {
        if ($this->accessToken !== null) {
            return $this->accessToken;
        }

        $ch = curl_init($this->baseUrl . '/auth'); 
        
        $payload = json_encode(array(
            'grant_type'    => 'password',
            'client_id'     => $this->clientId,
            'client_secret' => $this->clientSecret,
            'username'      => $this->username,
            'password'      => $this->password
        ));

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Accept: application/json'
        ));

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 200) {
            $data = json_decode($response, true);
            $this->accessToken = $data['access_token'] ?? null;
            return $this->accessToken;
        }

        return null;
    }

    /**
     * Obtiene TODOS los productos del catálogo (Sincronización Masiva Koywe)
     */
    public function getProducts()
    {
        $token = $this->authenticate();
        if (!$token) {
            throw new Exception("Error de autenticación con FACTO.");
        }

        $allProducts = array();
        $page = 1;
        $totalPages = 1;
        
        do {
            $url = $this->baseUrl . '/products?page=' . $page;
            
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Authorization: Bearer ' . $token,
                'Accept: application/json'
            ));

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            if ($httpCode === 200) {
                $data = json_decode($response, true);
                
                // Extraemos los productos de la envoltura _embedded
                if (isset($data['_embedded']['products']) && is_array($data['_embedded']['products'])) {
                    $allProducts = array_merge($allProducts, $data['_embedded']['products']);
                }
                
                // Leemos cuántas páginas hay en total
                $totalPages = $data['page_count'] ?? 1;
                $page++;
                
            } else {
                throw new Exception("La API respondió con código: " . $httpCode);
            }
            
        } while ($page <= $totalPages);

        return $allProducts;
    }

    /**
     * Busca productos (Retorna el listado base sin precios)
     */
    public function searchProducts($query)
    {
        $token = $this->authenticate();
        if (!$token) {
            return array();
        }

        $url = $this->baseUrl . '/products?name=' . urlencode($query) . '&limit=10';
        
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Authorization: Bearer ' . $token,
            'Accept: application/json'
        ));

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 200) {
            return json_decode($response, true) ?? array();
        }

        return array();
    }

    /**
     * Obtiene los detalles completos de un producto específico (Incluye Precios e IVA)
     */
    public function getProductDetails($productId)
    {
        $token = $this->authenticate();
        if (!$token) {
            return null;
        }

        // Endpoint individual por ID
        $url = $this->baseUrl . '/products/' . $productId;
        
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Authorization: Bearer ' . $token,
            'Accept: application/json'
        ));

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 200) {
            return json_decode($response, true);
        }

        return null;
    }
    /**
     * Obtiene las categorías de productos desde FACTO
     */
    public function getCategories() {
        $token = $this->authenticate();
        if (!$token) return [];

        $ch = curl_init($this->baseUrl . '/product_categories');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $token, 'Accept: application/json'));

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 200) {
            $data = json_decode($response, true);
            return $data ?? [];
        }
        return [];
    }

    /**
     * Crea un producto directamente en FACTO
     */
    public function createProduct($payload) {
        $token = $this->authenticate();
        if (!$token) throw new Exception("No hay token para crear producto en FACTO");

        $ch = curl_init($this->baseUrl . '/products');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Authorization: Bearer ' . $token,
            'Content-Type: application/json',
            'Accept: application/json'
        ));

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 201 || $httpCode === 200) {
            return json_decode($response, true);
        }
        throw new Exception("Error al crear en FACTO (HTTP $httpCode): " . $response);
    }

    /**
     * Actualiza un producto en FACTO (FACTO OpenAPI restringe la edición vía API a Nombre y SKU)
     */
    public function updateProduct($factoId, $payload) {
        $token = $this->authenticate();
        if (!$token) return false;

        $ch = curl_init($this->baseUrl . '/products/' . $factoId);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $token, 'Content-Type: application/json'));

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return ($httpCode === 200 || $httpCode === 204);
    }
    /**
     * Crea una categoría de producto directamente en FACTO
     */
    public function createCategory($name, $parentId = null) {
        $token = $this->authenticate();
        if (!$token) throw new Exception("Error de autenticación con FACTO.");

        $payload = array('name' => $name);
        if ($parentId) {
            $payload['parent_product_category_id'] = $parentId;
        }

        $ch = curl_init($this->baseUrl . '/product_categories');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Authorization: Bearer ' . $token,
            'Content-Type: application/json',
            'Accept: application/json'
        ));

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 200 || $httpCode === 201) {
            return json_decode($response, true);
        }
        
        throw new Exception("Error al crear categoría en FACTO (HTTP $httpCode): " . $response);
    }
    /**
     * Elimina un producto en FACTO
     */
    public function deleteProduct($factoId) {
        $token = $this->authenticate();
        if (!$token) return false;

        $ch = curl_init($this->baseUrl . '/products/' . $factoId);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $token, 'Accept: application/json'));

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        return ($httpCode === 204 || $httpCode === 200);
    }
}