<?php

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

class AIEO_MOI_Provider_Shopflix implements AIEO_MOI_Provider {

    const API_BASE = 'https://merchant.api.shopflix.gr/api';

    public function slug()  { return 'shopflix'; }
    public function label() { return 'Shopflix'; }

    public function credential_fields() {
        return array(
            array(
                'name'        => 'username',
                'label'       => __('Merchant API Username', 'ai-eshop-optimizer'),
                'type'        => 'text',
                'required'    => true,
                'description' => __('From Shopflix merchant dashboard → API credentials.', 'ai-eshop-optimizer'),
            ),
            array(
                'name'        => 'password',
                'label'       => __('Merchant API Password', 'ai-eshop-optimizer'),
                'type'        => 'password',
                'required'    => true,
                'description' => __('Stored in DB; used as HTTP Basic auth on every request.', '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', 'Shopflix is poll-only — no webhook delivery.');
    }

    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, 'PATCH', '/orders/' . rawurlencode((string) $remote_order_id) . '/accept', null);
        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 accepted on Shopflix.', 'ai-eshop-optimizer'),
            'voucher_url' => $voucher_url,
        );
    }

    public function reject_order(array $vendor, $remote_order_id, $reason = '') {
        
        
        $valid = array('damaged', 'out-of-stock', 'wrong-price', 'disabled-product', 'wrong-product');
        $reason_clean = strtolower(trim((string) $reason));
        $reason_clean = str_replace(' ', '-', $reason_clean);
        if (!in_array($reason_clean, $valid, true)) {
            $reason_clean = 'out-of-stock';
        }
        $resp = $this->api_request($vendor, 'PATCH', '/orders/' . rawurlencode((string) $remote_order_id) . '/reject', array(
            'status' => 'D',
            'reason' => $reason_clean,
        ));
        if (is_wp_error($resp)) {
            return array('ok' => false, 'message' => $resp->get_error_message());
        }
        return array('ok' => true, 'message' => __('Order rejected on Shopflix.', '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) {
        $since_iso = gmdate('c', max(0, (int) $since_ts));
        $page = 1;
        $orders_out = array();
        $loop_guard = 0;

        while ($loop_guard++ < 20) {
            $resp = $this->api_request($vendor, 'GET', '/orders?' . http_build_query(array(
                'page'         => $page,
                'itemsPerPage' => 50,
                'dateFrom'     => $since_iso,
            )), null);
            if (is_wp_error($resp) || !is_array($resp)) { break; }
            $list = isset($resp['orders']) && is_array($resp['orders']) ? $resp['orders'] : array();
            if (empty($list)) { break; }

            foreach ($list as $summary) {
                $oid = (string) ($summary['id'] ?? '');
                if ($oid === '') { continue; }
                $full = $this->api_request($vendor, 'GET', '/orders/' . rawurlencode($oid), null);
                if (is_wp_error($full) || !is_array($full)) { continue; }
                $orders_out[] = $this->normalise_order($full);
            }

            $params = isset($resp['params']) && is_array($resp['params']) ? $resp['params'] : array();
            $total  = (int) ($params['totalItems']    ?? 0);
            $per    = (int) ($params['itemsPerPage'] ?? 50);
            if ($per <= 0 || $page * $per >= $total) { break; }
            $page++;
        }
        return $orders_out;
    }

    
    private function normalise_order(array $sf) {
        $addr = isset($sf['addressDetails']) ? $sf['addressDetails'] : array();
        $cust = isset($sf['customer'])       ? $sf['customer']       : array();

        $billing = array(
            'first_name' => (string) ($cust['firstName'] ?? ''),
            'last_name'  => (string) ($cust['lastName']  ?? ''),
            'phone'      => (string) ($cust['phone']     ?? ''),
            'email'      => (string) ($cust['email']     ?? ''),
            'address_1'  => trim((string) ($addr['street'] ?? '') . ' ' . (string) ($addr['streetNumber'] ?? '')),
            'city'       => (string) ($addr['city']     ?? ''),
            'postcode'   => (string) ($addr['postCode'] ?? ''),
            'state'      => (string) ($addr['regionCode'] ?? ''),
            'country'    => (string) ($addr['countryCode'] ?? 'GR'),
        );
        $shipping = $billing;

        $line_items = array();
        foreach ((array) ($sf['lineItems'] ?? array()) as $li) {
            
            
            $remote_id = (string) ($li['merchantSku'] ?? $li['sku'] ?? '');
            $line_items[] = array(
                'remote_id'  => $remote_id,
                'qty'        => (int) ($li['quantity'] ?? 1),
                'unit_price' => (float) ($li['unitPrice'] ?? 0),
                'tax'        => 0.0,
                'title'      => (string) ($li['productName'] ?? ''),
            );
        }

        $carrier         = isset($sf['carrier']) && is_array($sf['carrier']) ? $sf['carrier'] : array();
        $courier_name    = (string) ($carrier['name']         ?? '');
        $delivery_name   = (string) ($carrier['deliveryName'] ?? '');
        $tracking_codes  = array();
        if (!empty($carrier['trackingCodes']) && is_array($carrier['trackingCodes'])) {
            $tracking_codes = array_map('strval', $carrier['trackingCodes']);
        }

        $invoice_payload = null;
        if (!empty($sf['hasInvoice']) && !empty($sf['invoiceDetails']) && is_array($sf['invoiceDetails'])) {
            $inv = $sf['invoiceDetails'];
            $invoice_payload = array(
                'company'    => (string) ($inv['companyName'] ?? $inv['company'] ?? ''),
                'profession' => (string) ($inv['profession']  ?? ''),
                'vat'        => (string) ($inv['vatNumber']   ?? $inv['vat'] ?? ''),
                'doy'        => (string) ($inv['doy']         ?? ''),
                'address_1'  => (string) ($inv['address']     ?? ''),
                'city'       => (string) ($inv['city']        ?? ''),
                'postcode'   => (string) ($inv['postCode']    ?? ''),
                'region'     => (string) ($inv['region']      ?? ''),
            );
        }

        
        
        
        $state_letter = strtoupper((string) ($sf['state'] ?? ''));
        $event_type = 'order_updated';
        if ($state_letter === 'O' || $state_letter === '') { $event_type = 'new_order'; }
        if ($state_letter === 'D')                          { $event_type = 'order_cancelled'; }

        return array(
            'event_type'      => $event_type,
            'remote_order_id' => (string) ($sf['id']         ?? ''),
            'remote_code'     => (string) ($sf['id']         ?? ''),
            'state'           => $state_letter,
            'billing'         => $billing,
            'shipping'        => $shipping,
            'line_items'      => $line_items,
            'totals'          => array(
                'shipping' => 0.0,
                'tax'      => 0.0,
                'fees'     => 0.0,
                'total'    => (float) ($sf['totalItemsAmount'] ?? 0),
            ),
            'courier'         => $courier_name !== '' ? $courier_name : $delivery_name,
            'voucher_url'     => '', 
            'tracking_codes'  => $tracking_codes,
            'invoice'         => $invoice_payload,
            'gift_wrap'       => self::any_gift_wrap_in_lines($sf['lineItems'] ?? array()),
            'raw'             => $sf,
        );
    }

    private static function any_gift_wrap_in_lines($lines) {
        if (!is_array($lines)) { return false; }
        foreach ($lines as $li) {
            if (!empty($li['giftWrap'])) { return true; }
        }
        return false;
    }

    
    private function create_and_store_voucher(array $vendor, $remote_order_id) {
        
        
        $created = $this->api_request($vendor, 'POST', '/shipments/' . rawurlencode($remote_order_id), array(
            'numberOfPackages' => 1,
            'packageComment'   => '',
        ));
        if (is_wp_error($created)) {
            
            
            
        }

        
        $printed = $this->api_request($vendor, 'GET', '/shipments/' . rawurlencode($remote_order_id) . '/print', null);
        if (is_wp_error($printed) || empty($printed['shipments']) || !is_array($printed['shipments'])) {
            return '';
        }
        $shipment = $printed['shipments'][0];
        $content = (string) ($shipment['voucherContent'] ?? '');
        $format  = (string) ($shipment['voucherFormat']  ?? 'pdf');
        if ($content === '') { return ''; }

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

    
    private function api_request(array $vendor, $method, $path, $body) {
        $u = (string) ($vendor['credentials']['username'] ?? '');
        $p = (string) ($vendor['credentials']['password'] ?? '');
        if ($u === '' || $p === '') {
            return new WP_Error('no_credentials', __('Shopflix credentials missing.', 'ai-eshop-optimizer'));
        }
        $args = array(
            'method'  => strtoupper((string) $method),
            'timeout' => 20,
            'headers' => array(
                'Authorization' => 'Basic ' . base64_encode($u . ':' . $p),
                'Accept'        => 'application/json',
                'Content-Type'  => 'application/json',
            ),
        );
        if ($body !== null && $args['method'] !== 'GET') {
            $args['body'] = wp_json_encode($body);
        }
        $resp = wp_remote_request(self::API_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);
        if ($code === 204) { return array(); }
        $json = json_decode($raw, true);
        if ($code >= 400) {
            $msg = is_array($json) && !empty($json['error']['errorMessage'])
                ? (string) $json['error']['errorMessage']
                : ('HTTP ' . $code);
            return new WP_Error('shopflix_api_error', $msg, array('status' => $code, 'body' => $raw));
        }
        return is_array($json) ? $json : array();
    }
}

AIEO_MOI_Provider_Registry::register(new AIEO_MOI_Provider_Shopflix());
