<?php

if (!defined('ABSPATH')) { exit; }

class AIEO_Efood_Catalog_Source implements AIEO_Catalog_Source {

    const DEFAULT_BASE = 'https://efood.partner.deliveryhero.io';
    const TOKEN_TTL_FALLBACK = 3600;

    public function slug()  { return 'efood'; }
    public function label() { return __('eFood (Delivery Hero)', 'ai-eshop-optimizer'); }

    public function credential_fields() {
        return array(
            array('name' => 'chain_id',      'label' => __('Chain ID', 'ai-eshop-optimizer'),      'type' => 'text',     'required' => true),
            array('name' => 'vendor_id',     'label' => __('Vendor ID', 'ai-eshop-optimizer'),     'type' => 'text',     'required' => true),
            array('name' => 'client_id',     'label' => __('OAuth Client ID', 'ai-eshop-optimizer'),     'type' => 'text',     'required' => true),
            array('name' => 'client_secret', 'label' => __('OAuth Client Secret', 'ai-eshop-optimizer'), 'type' => 'password', 'required' => true),
            array('name' => 'base_url',      'label' => __('API Base URL', 'ai-eshop-optimizer'),  'type' => 'text',     'required' => false, 'description' => __('Leave blank for the eFood production endpoint.', 'ai-eshop-optimizer')),
        );
    }

    public function validate_credentials(array $creds) {
        foreach (array('chain_id', 'vendor_id', 'client_id', 'client_secret') as $k) {
            if (empty($creds[$k])) {
                return new WP_Error('efood_missing_cred', __('Chain ID, Vendor ID, OAuth Client ID and Client Secret are all required.', 'ai-eshop-optimizer'));
            }
        }
        return true;
    }

    
    
    

    private function base(array $creds) {
        $b = isset($creds['base_url']) ? trim((string) $creds['base_url']) : '';
        return $b !== '' ? untrailingslashit($b) : self::DEFAULT_BASE;
    }

    
    private function token(array $creds) {
        $cache_key = 'aieo_efood_cat_tok_' . md5((string) ($creds['client_id'] ?? '') . '|' . $this->base($creds));
        $cached = get_transient($cache_key);
        if (is_string($cached) && $cached !== '') { return $cached; }

        if (!class_exists('AIEO_MOI_OAuth')) {
            return new WP_Error('efood_no_oauth_helper', __('The Marketplace Order Importer OAuth helper is unavailable.', 'ai-eshop-optimizer'));
        }
        $resp = AIEO_MOI_OAuth::token_request($this->base($creds) . '/v2/oauth/token', array(
            'grant_type'    => 'client_credentials',
            'client_id'     => (string) ($creds['client_id'] ?? ''),
            'client_secret' => (string) ($creds['client_secret'] ?? ''),
        ));
        if (is_wp_error($resp)) { return $resp; }
        $token = (string) ($resp['access_token'] ?? '');
        if ($token === '') {
            return new WP_Error('efood_no_token', __('eFood did not return an access token — check the client id/secret.', 'ai-eshop-optimizer'));
        }
        $ttl = (int) ($resp['expires_in'] ?? self::TOKEN_TTL_FALLBACK);
        set_transient($cache_key, $token, max(60, $ttl - 120));
        return $token;
    }

    private function vendor_path(array $creds) {
        return '/v2/chains/' . rawurlencode((string) ($creds['chain_id'] ?? ''))
             . '/vendors/' . rawurlencode((string) ($creds['vendor_id'] ?? ''));
    }

    
    private function api_get(array $creds, $path, array $query = array()) {
        $token = $this->token($creds);
        if (is_wp_error($token)) { return $token; }
        $url = $this->base($creds) . $path;
        if (!empty($query)) { $url = add_query_arg($query, $url); }
        $resp = wp_remote_get($url, array(
            'timeout' => 30,
            'headers' => array(
                'Authorization' => 'Bearer ' . $token,
                'Accept'        => 'application/json',
            ),
        ));
        if (is_wp_error($resp)) { return $resp; }
        $code = (int) wp_remote_retrieve_response_code($resp);
        $body = (string) wp_remote_retrieve_body($resp);
        $json = json_decode($body, true);
        if ($code >= 400) {
            $msg = is_array($json) && !empty($json['message']) ? (string) $json['message'] : ('HTTP ' . $code);
            return new WP_Error('efood_http_' . $code, $msg);
        }
        return is_array($json) ? $json : array();
    }

    
    
    

    public function fetch_categories(array $creds) {
        $res = $this->api_get($creds, $this->vendor_path($creds) . '/categories');
        if (is_wp_error($res)) { return $res; }
        $map = array();
        foreach ((array) ($res['categories'] ?? array()) as $cat) {
            if (!is_array($cat) || empty($cat['global_id'])) { continue; }
            $gid     = (string) $cat['global_id'];
            $details = isset($cat['details']) && is_array($cat['details']) ? $cat['details'] : array();
            $name    = (string) ($details['name'] ?? ($details['title'] ?? $gid));
            $map[$gid] = array(
                'name'   => $name,
                'parent' => (string) ($cat['parent_global_id'] ?? ''),
            );
        }
        return $map;
    }

    public function fetch_page(array $creds, $page, $page_size) {
        $page      = max(1, (int) $page);
        $page_size = max(1, min(200, (int) $page_size));
        $res = $this->api_get($creds, $this->vendor_path($creds) . '/catalog', array(
            'page'      => $page,
            'page_size' => $page_size,
        ));
        if (is_wp_error($res)) { return $res; }
        return array(
            'products'    => (array) ($res['products'] ?? array()),
            'page'        => (int) ($res['page_number'] ?? $page),
            'total_pages' => max(1, (int) ($res['total_pages'] ?? 1)),
            'total'       => (int) ($res['total'] ?? 0),
        );
    }

    
    
    

    public function map_product(array $raw, array $ctx) {
        $cats_map = isset($ctx['categories']) && is_array($ctx['categories']) ? $ctx['categories'] : array();

        $sku     = (string) ($raw['sku'] ?? '');
        $barcode = '';
        if (!empty($raw['barcodes']) && is_array($raw['barcodes'])) {
            $barcode = (string) reset($raw['barcodes']);
        }

        $title = (string) ($raw['title'] ?? '');
        if ($title === '' && !empty($raw['translations']) && is_array($raw['translations'])) {
            
            $first = reset($raw['translations']);
            if (is_array($first)) { $title = (string) ($first['name'] ?? ($first['title'] ?? '')); }
        }

        $active = !isset($raw['active']) || !empty($raw['active']);

        
        
        $imgs = $this->build_images($raw);

        $payload = array(
            'type'        => 'simple',
            'title'       => $title,
            'description' => (string) ($raw['description'] ?? ''),
            'status'      => (isset($ctx['options']['status']) && $ctx['options']['status'] === 'publish') ? 'publish' : 'draft',
            'match'       => array('sku' => $sku, 'barcode' => $barcode),
            'regular_price' => isset($raw['price']) ? (string) $raw['price'] : '',
            'stock'       => array(
                'manage' => false,
                'status' => $active ? 'instock' : 'outofstock',
            ),
            'category_terms' => $this->build_category_terms($raw, $cats_map),
            'images'         => !empty($imgs) ? array($imgs[0]) : array(),
            'gallery'        => count($imgs) > 1 ? array_slice($imgs, 1) : array(),
        );

        
        return array('payload' => $payload, 'option_groups' => array());
    }

    
    private function build_category_terms(array $raw, array $cats_map) {
        $entries = array();
        $seen    = array();

        $add_chain = function ($gid) use (&$entries, &$seen, $cats_map, &$add_chain) {
            $gid = (string) $gid;
            if ($gid === '' || isset($seen[$gid])) { return; }
            $node = isset($cats_map[$gid]) ? $cats_map[$gid] : null;
            $name = $node ? (string) $node['name'] : '';
            if ($name === '') { return; }
            $parent_gid = $node ? (string) $node['parent'] : '';
            
            if ($parent_gid !== '') { $add_chain($parent_gid); }
            $seen[$gid] = true;
            $entries[]  = array(
                'slug'        => sanitize_title($name),
                'name'        => $name,
                'parent_slug' => ($parent_gid !== '' && isset($cats_map[$parent_gid])) ? sanitize_title((string) $cats_map[$parent_gid]['name']) : '',
            );
        };

        foreach ((array) ($raw['categories'] ?? array()) as $cat) {
            
            if (is_array($cat) && !empty($cat['global_id'])) {
                $gid = (string) $cat['global_id'];
                
                if (!isset($cats_map[$gid]) && (!empty($cat['details']['name']) || !empty($cat['details']['title']))) {
                    $cats_map[$gid] = array(
                        'name'   => (string) ($cat['details']['name'] ?? $cat['details']['title']),
                        'parent' => (string) ($cat['parent_global_id'] ?? ''),
                    );
                }
                $add_chain($gid);
            } elseif (is_string($cat) && $cat !== '') {
                $entries[] = array('slug' => sanitize_title($cat), 'name' => $cat, 'parent_slug' => '');
            }
        }
        return $entries;
    }

    
    private function build_images(array $raw) {
        $out = array();
        foreach ((array) ($raw['images'] ?? array()) as $img) {
            $src = '';
            if (is_string($img)) {
                $src = $img;
            } elseif (is_array($img)) {
                $src = (string) ($img['url'] ?? ($img['src'] ?? ($img['image_url'] ?? '')));
            }
            $src = trim($src);
            if ($src !== '') { $out[] = array('src' => $src); }
        }
        return $out;
    }
}
