<?php

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

class AIEO_MOI_Provider_Emag implements AIEO_MOI_Provider {

    const DEFAULT_API_BASE = 'https://marketplace-api.emag.ro/api-3';

    public function slug()  { return 'emag'; }
    public function label() { return 'eMag'; }

    public function info_text() {
        return '<strong>' . esc_html__('eMag Marketplace API', 'ai-eshop-optimizer') . '</strong><br>'
             . sprintf(
                 
                 __('Default endpoint: %s (override per-vendor in the API base field below)', 'ai-eshop-optimizer'),
                 '<code>' . esc_html(self::DEFAULT_API_BASE) . '</code>'
             ) . '<br>'
             . esc_html__('Auth: HTTP Basic — username + password issued by eMag.', 'ai-eshop-optimizer') . '<br>'
             . esc_html__('Delivery: Pull (polling — no webhooks). Per-country endpoints exist (.ro / .bg / .hu); change the API base field accordingly.', 'ai-eshop-optimizer');
    }

    public function credential_fields() {
        return array(
            array(
                'name'        => 'username',
                'label'       => __('eMag Marketplace Username', 'ai-eshop-optimizer'),
                'type'        => 'text',
                'required'    => true,
                'description' => __('From eMag merchant dashboard → API access.', 'ai-eshop-optimizer'),
            ),
            array(
                'name'        => 'password',
                'label'       => __('eMag Marketplace Password', 'ai-eshop-optimizer'),
                'type'        => 'password',
                'required'    => true,
                'description' => __('Stored in DB; used as HTTP Basic auth on every request.', 'ai-eshop-optimizer'),
            ),
            array(
                'name'        => 'api_base',
                'label'       => __('API Base URL', 'ai-eshop-optimizer'),
                'type'        => 'text',
                'required'    => false,
                'description' => __('Country-specific endpoint. Defaults to the Romanian marketplace. For Bulgaria use marketplace-api.emag.bg/api-3, Hungary .hu/api-3, Poland .pl/api-3.', 'ai-eshop-optimizer'),
            ),
        );
    }

    public function validate_credentials(array $credentials) {
        return !empty($credentials['username']) && !empty($credentials['password']);
    }

    public function verify_webhook($request, array $vendor) {
        return new WP_Error('no_webhooks', __('eMag is poll-only — no webhook delivery.', 'ai-eshop-optimizer'));
    }

    public function parse_webhook_payload(array $body) {
        return array();
    }

    public function accept_order(array $vendor, $remote_order_id, array $opts = array()) {
        
        $resp = $this->api_request($vendor, '/order/save', array(
            array(
                'id'     => (int) $remote_order_id,
                'status' => 2,
            ),
        ));
        if (is_wp_error($resp)) {
            return array('ok' => false, 'message' => $resp->get_error_message());
        }
        
        
        
        $voucher_url = $this->create_and_store_voucher($vendor, (string) $remote_order_id);
        return array(
            'ok'          => true,
            'message'     => __('Order acknowledged on eMag.', 'ai-eshop-optimizer'),
            'voucher_url' => $voucher_url,
        );
    }

    public function reject_order(array $vendor, $remote_order_id, $reason = '') {
        
        
        $payload = array(
            array(
                'id'     => (int) $remote_order_id,
                'status' => 0,
            ),
        );
        if ($reason !== '') {
            $payload[0]['observations'] = sanitize_text_field((string) $reason);
        }
        $resp = $this->api_request($vendor, '/order/save', $payload);
        if (is_wp_error($resp)) {
            return array('ok' => false, 'message' => $resp->get_error_message());
        }
        return array('ok' => true, 'message' => __('Order canceled on eMag.', 'ai-eshop-optimizer'));
    }

    public function fetch_voucher(array $vendor, $remote_order_id) {
        return (string) $this->create_and_store_voucher($vendor, (string) $remote_order_id);
    }

    
    public function poll_orders(array $vendor, $since_ts) {
        return $this->fetch_window($vendor, (int) $since_ts, 0);
    }

    
    public function backfill_orders(array $vendor, $since_ts, $until_ts) {
        
        
        
        
        
        $result = $this->fetch_window($vendor, (int) $since_ts, (int) $until_ts);
        if (is_wp_error($result)) {
            
            throw new \RuntimeException('eMag API: ' . $result->get_error_message());
        }
        return $result;
    }

    
    private function fetch_window(array $vendor, $since_ts, $until_ts) {
        $modified_after = gmdate('Y-m-d H:i:s', max(0, (int) $since_ts));
        $modified_before = (int) $until_ts > 0 ? gmdate('Y-m-d H:i:s', (int) $until_ts) : '';
        $page = 1;
        $orders_out = array();
        $loop_guard = 0;

        while ($loop_guard++ < 40) {
            $payload = array(
                'currentPage'   => $page,
                'itemsPerPage'  => 100,
                'modifiedAfter' => $modified_after,
            );
            if ($modified_before !== '') {
                $payload['modifiedBefore'] = $modified_before;
            }

            $resp = $this->api_request($vendor, '/order/read', array('data' => $payload));
            if (is_wp_error($resp)) {
                
                
                
                
                if ($page === 1) { return $resp; }
                break;
            }
            $results = isset($resp['results']) && is_array($resp['results']) ? $resp['results'] : array();
            if (empty($results)) { break; }

            foreach ($results as $order) {
                if (!is_array($order)) { continue; }
                $orders_out[] = $this->normalise_order($order);
            }

            if (count($results) < 100) { break; }
            $page++;
        }
        return $orders_out;
    }

    
    private function normalise_order(array $em) {
        $cust  = isset($em['customer']) ? $em['customer'] : array();
        $bill  = isset($em['billing'])  ? $em['billing']  : array();
        $ship  = isset($em['shipping']) ? $em['shipping'] : (isset($em['shipping_address']) ? $em['shipping_address'] : $bill);

        
        
        $billing = array(
            'first_name' => (string) ($cust['name']    ?? ($bill['name']    ?? '')),
            'last_name'  => (string) ($cust['surname'] ?? ($bill['surname'] ?? '')),
            'company'    => (string) ($cust['company'] ?? ($bill['company'] ?? '')),
            'address_1'  => trim((string) ($bill['street'] ?? '') . ' ' . (string) ($bill['street_no'] ?? '')),
            'city'       => (string) ($bill['locality'] ?? $bill['city'] ?? ''),
            'state'      => (string) ($bill['county']    ?? ''),
            'postcode'   => (string) ($bill['postal_code'] ?? $bill['zipcode'] ?? ''),
            'country'    => (string) ($bill['country']   ?? 'RO'),
            'phone'      => (string) ($cust['phone_1']   ?? $cust['phone'] ?? ''),
            'email'      => (string) ($cust['email']     ?? ''),
        );
        $shipping = array(
            'first_name' => (string) ($ship['name']    ?? $billing['first_name']),
            'last_name'  => (string) ($ship['surname'] ?? $billing['last_name']),
            'company'    => (string) ($ship['company'] ?? ''),
            'address_1'  => trim((string) ($ship['street'] ?? '') . ' ' . (string) ($ship['street_no'] ?? '')),
            'city'       => (string) ($ship['locality'] ?? $ship['city'] ?? ''),
            'state'      => (string) ($ship['county']    ?? ''),
            'postcode'   => (string) ($ship['postal_code'] ?? $ship['zipcode'] ?? ''),
            'country'    => (string) ($ship['country']   ?? $billing['country']),
            'phone'      => (string) ($ship['phone_1']   ?? $billing['phone']),
            'email'      => $billing['email'],
        );

        $line_items = array();
        foreach ((array) ($em['products'] ?? array()) as $p) {
            
            
            
            $remote_id = (string) ($p['part_number'] ?? $p['ean'] ?? $p['product_id'] ?? '');
            $line_items[] = array(
                'remote_id'  => $remote_id,
                'qty'        => (int) ($p['quantity'] ?? 1),
                'unit_price' => (float) ($p['sale_price'] ?? 0),
                'tax'        => 0.0,
                'title'      => (string) ($p['name'] ?? $p['product_name'] ?? ''),
            );
        }

        $tracking_codes = array();
        if (!empty($em['awb_number'])) { $tracking_codes[] = (string) $em['awb_number']; }
        if (!empty($em['awb']) && is_array($em['awb'])) {
            foreach ($em['awb'] as $awb_row) {
                if (!empty($awb_row['number'])) { $tracking_codes[] = (string) $awb_row['number']; }
            }
        }

        $invoice_payload = null;
        $invoice_required = !empty($bill['is_company']) || !empty($em['type']) && (int) $em['type'] === 3;
        if ($invoice_required) {
            $invoice_payload = array(
                'company'    => (string) ($bill['company']     ?? ''),
                'profession' => '',
                'vat'        => (string) ($bill['vat_id']      ?? ($bill['cif'] ?? '')),
                'doy'        => '',
                'address_1'  => trim((string) ($bill['street'] ?? '') . ' ' . (string) ($bill['street_no'] ?? '')),
                'city'       => (string) ($bill['locality']    ?? ''),
                'postcode'   => (string) ($bill['postal_code'] ?? ''),
                'region'     => (string) ($bill['county']      ?? ''),
            );
        }

        $status_int = (int) ($em['status'] ?? 1);
        $event_type = ($status_int === 1) ? 'new_order' : 'order_updated';
        if ($status_int === 0) { $event_type = 'order_cancelled'; }

        return array(
            'event_type'      => $event_type,
            'remote_order_id' => (string) ($em['id']     ?? ''),
            'remote_code'     => (string) ($em['vendor_name'] ?? ($em['id'] ?? '')),
            'state'           => self::state_label($status_int),
            'billing'         => $billing,
            'shipping'        => $shipping,
            'line_items'      => $line_items,
            'totals'          => array(
                'shipping' => (float) ($em['shipping_tax'] ?? 0),
                'tax'      => 0.0,
                'fees'     => (float) ($em['cashed_co'] ?? 0),
                'total'    => (float) ($em['cashed_co'] ?? 0),
            ),
            'courier'         => (string) ($em['locker_id'] ?? ''),
            'voucher_url'     => '',
            'tracking_codes'  => $tracking_codes,
            'invoice'         => $invoice_payload,
            'gift_wrap'       => false,
            'raw'             => $em,
        );
    }

    private static function state_label($status_int) {
        switch ((int) $status_int) {
            case 0: return 'canceled';
            case 1: return 'new';
            case 2: return 'in_progress';
            case 3: return 'prepared';
            case 4: return 'finalized';
            case 5: return 'returned';
        }
        return 'unknown_' . $status_int;
    }

    
    private function create_and_store_voucher(array $vendor, $remote_order_id) {
        
        
        $this->api_request($vendor, '/awb/save', array(
            array('order_id' => (int) $remote_order_id),
        )); 

        $printed = $this->api_request($vendor, '/awb/read_pdf', array(
            array('order_id' => (int) $remote_order_id),
        ));
        if (is_wp_error($printed) || empty($printed['results']) || !is_array($printed['results'])) {
            return '';
        }
        $row = $printed['results'][0];
        
        
        $content = (string) ($row['pdf'] ?? '');
        if (strpos($content, ',') !== false) {
            $content = (string) explode(',', $content, 2)[1];
        }
        if ($content === '') { return ''; }

        return AIEO_MOI_Voucher_Store::save(
            (string) $vendor['slug'],
            (string) $remote_order_id,
            $content,
            'pdf'
        );
    }

    
    private function api_request(array $vendor, $path, $body = null) {
        $u = (string) ($vendor['credentials']['username'] ?? '');
        $p = (string) ($vendor['credentials']['password'] ?? '');
        if ($u === '' || $p === '') {
            return new WP_Error('no_credentials', __('eMag credentials missing.', 'ai-eshop-optimizer'));
        }
        $base = (string) ($vendor['credentials']['api_base'] ?? '');
        if ($base === '') { $base = self::DEFAULT_API_BASE; }
        $base = rtrim($base, '/');

        $args = array(
            'method'  => 'POST',
            'timeout' => 25,
            'headers' => array(
                'Authorization' => 'Basic ' . base64_encode($u . ':' . $p),
                'Accept'        => 'application/json',
                'Content-Type'  => 'application/json',
            ),
            'body'    => $body !== null ? wp_json_encode($body) : '',
        );

        $resp = wp_remote_request($base . $path, $args);
        if (is_wp_error($resp)) { return $resp; }
        $code = (int) wp_remote_retrieve_response_code($resp);
        $raw  = (string) wp_remote_retrieve_body($resp);
        $json = json_decode($raw, true);
        if ($code >= 400) {
            $msg = is_array($json) && !empty($json['messages'][0])
                ? (string) $json['messages'][0]
                
                : sprintf(__('HTTP %d', 'ai-eshop-optimizer'), $code);
            return new WP_Error('emag_api_error', $msg, array('status' => $code, 'body' => $raw));
        }
        if (!is_array($json)) {
            return new WP_Error('emag_bad_json', __('Non-JSON response', 'ai-eshop-optimizer'), array('body' => $raw));
        }
        
        
        if (!empty($json['isError'])) {
            $msg = is_array($json['messages'] ?? null)
                ? implode('; ', array_map('strval', $json['messages']))
                : __('eMag application error', 'ai-eshop-optimizer');
            return new WP_Error('emag_app_error', $msg, array('body' => $raw));
        }
        return $json;
    }
}

AIEO_MOI_Provider_Registry::register(new AIEO_MOI_Provider_Emag());
