<?php
/**
 * Widgets module data service.
 *
 * @package Noesia_Smart_Waiter
 */

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

if ( ! class_exists( 'Noesia_SWA_Widgets_Data' ) ) {
    class Noesia_SWA_Widgets_Data {

        const RATES_TRANSIENT = 'noesia_swa_widgets_rates_v1';
        const RATES_TTL       = 21600;

        public function get_context() {
            $rates = $this->get_currency_rates();

            return array(
                'rates_payload' => array(
                    'base'         => isset( $rates['base'] ) ? (string) $rates['base'] : 'EUR',
                    'rates'        => isset( $rates['rates'] ) && is_array( $rates['rates'] ) ? $rates['rates'] : array( 'EUR' => 1 ),
                    'updated_at'   => isset( $rates['updated_at'] ) ? (string) $rates['updated_at'] : '',
                    'is_cached'    => ! empty( $rates['is_cached'] ),
                    'source_label' => __( 'European Central Bank daily reference feed', 'noesia-smart-waiter' ),
                    'favorites'    => array( 'EUR', 'USD', 'GBP', 'CHF', 'AED', 'CAD', 'AUD', 'JPY' ),
                ),
                'site_locale'   => function_exists( 'determine_locale' ) ? determine_locale() : get_locale(),
            );
        }

        public function get_currency_rates( $force_refresh = false ) {
            if ( ! $force_refresh ) {
                $cached = get_transient( self::RATES_TRANSIENT );
                if ( is_array( $cached ) && ! empty( $cached['rates'] ) ) {
                    $cached['is_cached'] = true;
                    return $cached;
                }
            }

            $fresh = $this->fetch_ecb_rates();
            if ( is_array( $fresh ) && ! empty( $fresh['rates'] ) ) {
                set_transient( self::RATES_TRANSIENT, $fresh, self::RATES_TTL );
                $fresh['is_cached'] = false;
                return $fresh;
            }

            $cached = get_transient( self::RATES_TRANSIENT );
            if ( is_array( $cached ) && ! empty( $cached['rates'] ) ) {
                $cached['is_cached'] = true;
                return $cached;
            }

            return array(
                'base'       => 'EUR',
                'rates'      => array(
                    'EUR' => 1,
                    'USD' => 1.09,
                    'GBP' => 0.85,
                    'CHF' => 0.96,
                ),
                'updated_at' => '',
                'is_cached'  => true,
            );
        }

        private function fetch_ecb_rates() {
            $url = apply_filters( 'noesia_swa_widgets_currency_provider_url', 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml', $this );
            $response = wp_safe_remote_get(
                esc_url_raw( $url ),
                array(
                    'timeout'   => 12,
                    'sslverify' => true,
                    'user-agent'=> 'NoesiaSmartWaiter/' . ( defined( 'NOESIA_SWA_VERSION' ) ? NOESIA_SWA_VERSION : '1.0' ),
                )
            );

            if ( is_wp_error( $response ) ) {
                return array();
            }

            $code = (int) wp_remote_retrieve_response_code( $response );
            if ( 200 !== $code ) {
                return array();
            }

            $body = wp_remote_retrieve_body( $response );
            if ( ! is_string( $body ) || '' === trim( $body ) || ! function_exists( 'simplexml_load_string' ) ) {
                return array();
            }

            libxml_use_internal_errors( true );
            $xml = simplexml_load_string( $body );
            if ( false === $xml ) {
                return array();
            }

            $nodes = $xml->xpath('//*[local-name()="Cube" and @currency and @rate]');
            $date_nodes = $xml->xpath('//*[local-name()="Cube" and @time]');

            $rates = array( 'EUR' => 1.0 );
            if ( is_array( $nodes ) ) {
                foreach ( $nodes as $node ) {
                    $currency = isset( $node['currency'] ) ? strtoupper( sanitize_text_field( (string) $node['currency'] ) ) : '';
                    $rate     = isset( $node['rate'] ) ? (float) $node['rate'] : 0;
                    if ( '' !== $currency && $rate > 0 ) {
                        $rates[ $currency ] = $rate;
                    }
                }
            }

            if ( empty( $rates ) ) {
                return array();
            }

            $updated_at = '';
            if ( is_array( $date_nodes ) && ! empty( $date_nodes[0]['time'] ) ) {
                $updated_at = sanitize_text_field( (string) $date_nodes[0]['time'] );
            }

            ksort( $rates );

            return array(
                'base'       => 'EUR',
                'rates'      => $rates,
                'updated_at' => $updated_at,
            );
        }

    }
}
