<?php
/**
* @package CembraPay Payment Gateway for WooCommerce
* @author  Adrian Emil Tudorache
* @license GPL-2.0+
* @link    https://www.tudorache.me/
*/

namespace CembraPayWoo;

if ( ! defined( 'ABSPATH' ) ) {
	header( 'Status: 403 Forbidden' );
	header( 'HTTP/1.1 403 Forbidden' );
	exit;
}

class Service {

    public static function get_payment_gateway_settings() {
        
        static $cached_opts = null;

        if ( $cached_opts == null ) {
            $cached_opts = get_option( 'woocommerce_cembrapay_settings', array() );
        }

        return $cached_opts;

    }

    public static function generate_uuid() {
        return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex(random_bytes(16)), 4));
    }

    public static function replace_umlauts($string) {

        $umlauts = array(
            'ä' => 'ae',
            'ö' => 'oe',
            'ü' => 'ue',
            'Ä' => 'Ae',
            'Ö' => 'Oe',
            'Ü' => 'Ue',
            'ß' => 'ss'
        );
    
        foreach( $umlauts as $what => $with ) {
            $string = str_replace($what, $with, $string);
        }
    
        return $string;
    
    }

    public static function get_language() {

        $locale = determine_locale();
		$locale = $locale ? explode( '_', $locale ) : '';
		
        return $locale ? $locale[0] : 'en';

    }

    public static function load_template( $template, $data = array() ) {

        $template = apply_filters( 'cembrapay_template', $template, $data );

        $theme_path = get_stylesheet_directory() . '/woocommerce/cembrapay/';

        if( file_exists( $theme_path . $template . '.php' ) ) {
            include( $theme_path . $template . '.php' );
            return;
        }

        include( CEMBRAPATH . 'templates/' . $template . '.php' );

    }

    public static function get_threatmetrix_session_id(): string {

        if( WC()->session ) {
            $threamtmetrix_session_id = WC()->session->get('cembrapay_threatmetrix_session_id');
            if( $threamtmetrix_session_id ) {
                return $threamtmetrix_session_id;
            }
        }

        $blogname   = Service::replace_umlauts( strtolower( str_replace(' ', '', get_bloginfo('name') ) ) );
		$session_id = md5( $blogname . get_current_user_id() . gmdate('Y-m-d H:i:s') );

        if( WC()->session ) {
            WC()->session->set('cembrapay_threatmetrix_session_id', $session_id);
        }

        return $session_id;

    }
    
    public static function parse_order_addresses( \WC_Order $order ): array {

        $billing_first_name  = $order->get_billing_first_name();
        $billing_last_name   = $order->get_billing_last_name();
        $billing_company     = $order->get_billing_company();
        $billing_address_1   = $order->get_billing_address_1();
        $billing_address_2   = $order->get_billing_address_2();
        $billing_postcode    = $order->get_billing_postcode();
        $billing_city        = $order->get_billing_city();
        $billing_country     = $order->get_billing_country();
        $billing_email       = $order->get_billing_email();
        $billing_phone       = $order->get_billing_phone();

        $shipping_first_name = $order->get_shipping_first_name();
        $shipping_last_name  = $order->get_shipping_last_name();
        $shipping_company    = $order->get_shipping_company();
        $shipping_address_1  = $order->get_shipping_address_1();
        $shipping_address_2  = $order->get_shipping_address_2();
        $shipping_postcode   = $order->get_shipping_postcode();
        $shipping_city       = $order->get_shipping_city();
        $shipping_country    = $order->get_shipping_country();

        $shipping_different  = false;

        if(
            ( $billing_first_name    != $shipping_first_name && ! empty( $shipping_first_name ) )
            || ( $billing_last_name  != $shipping_last_name && ! empty( $shipping_last_name ) )
            || ( $billing_address_1  != $shipping_address_1 && ! empty( $shipping_address_1 ) )
            || ( $billing_address_2  != $shipping_address_2 && ! empty( $shipping_address_2 ) )
            || ( $billing_postcode   != $shipping_postcode && ! empty( $shipping_postcode ) )
            || ( $billing_city       != $shipping_city && ! empty( $shipping_city ) )
            || ( $billing_country    != $shipping_country && ! empty( $shipping_country ) )
        ) {
            $shipping_different = true;
        }

        return array(
            'billing' => array(
                'first_name' => $billing_first_name ? $billing_first_name : '',
                'last_name'  => $billing_last_name ? $billing_last_name : '',
                'company'    => $billing_company ? $billing_company : '',
                'address_1'  => $billing_address_1 ? $billing_address_1 : '',
                'address_2'  => $billing_address_2 ? $billing_address_2 : '',
                'postcode'   => $billing_postcode ? $billing_postcode : '',
                'city'       => $billing_city ? $billing_city : '',
                'country'    => $billing_country ? $billing_country : '',
                'email'      => $billing_email ? $billing_email : '',
                'phone'      => $billing_phone ? $billing_phone : ''
            ),
            'shipping' => array(
                'first_name' => $shipping_first_name ? $shipping_first_name : '',
                'last_name'  => $shipping_last_name ? $shipping_last_name : '',
                'company'    => $shipping_company ? $shipping_company : '',
                'address_1'  => $shipping_address_1 ? $shipping_address_1 : '',
                'address_2'  => $shipping_address_2 ? $shipping_address_2 : '',
                'postcode'   => $shipping_postcode ? $shipping_postcode : '',
                'city'       => $shipping_city ? $shipping_city : '',
                'country'    => $shipping_country ? $shipping_country : '',
                'email'      => $billing_email ? $billing_email : '',
                'phone'      => $billing_phone ? $billing_phone : ''
            ),
            'shipping_different' => $shipping_different
        );

    }

    public static function get_user_ip_address() {
        
        if( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
            return sanitize_text_field( wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ) );
        }
        
        if( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
            
            $ipList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);

            return sanitize_text_field( wp_unslash( trim( $ipList[0] ) ) );

        }
        
        return sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );

    }

    public static function get_field_labels() {

        $labels = array(
            'title',
            'description',
            'instructions',
            'unavailable',
            'invoice_type_intro_text',
            'salutation_field_label',
            'salutation_field_label_female',
            'salutation_field_label_male',
            'salutation_field_label_other',
            'birthdate_field_day_label',
            'birthdate_field_month_label',
            'birthdate_field_year_label',
            'birthdate_field_label',
            'company_reg_field_label',
            'installments_intro_text',
            'cembrapay_invoice_template',
            'installments_full_template',
            'installments_3_template',
            'installments_4_template',
            'installments_6_template',
            'installments_12_template',
            'installments_24_template',
            'installments_36_template',
            'installments_48_template',
            'invoice_via_email',
            'invoice_via_post'
        );

        $translated_labels = array();

        foreach( $labels as $label ) {
            $translated_labels[ $label ] = self::get_field_label( $label );
        }

        return $translated_labels;

    }

    public static function get_field_label( $field, $lang = '' ) {

        $lang = $lang ? $lang : Service::get_language();

        $translations = get_option('cembrapay_field_translations');

        if( 
            isset( $translations[ $field ] ) 
            && isset( $translations[ $field ][ $lang ] )
            && $translations[ $field ][ $lang ]
        ) {
            return $translations[ $field ][ $lang ];
        }

        $cembrapay_settings = self::get_payment_gateway_settings();

        if( isset( $cembrapay_settings[ $field ] ) ) {
            return $cembrapay_settings[ $field ];
        }

        $default_field_labels = self::default_field_labels();

        if( isset( $default_field_labels[ $field ] ) ) {
            return $default_field_labels[ $field ];
        }

        return esc_html__( 'Unable to fetch field label. Please revise settings.', 'cembrapay' );

    }

    public static function default_field_labels() {

        return array(
            'title'                       => 'CembraPay',
            'description'                 => 'Pay by invoice with CembraPay',
            'instructions'                => 'To proceed, please fill all the required fields, including the Salutation and Birthdate fields if required.',
            'unavailable'                 => 'Unfortunately CembraPay is not available for your order. Please select a different payment gateway.',
            'invoice_type_intro_text'     => 'Select invoice type',
            'salutation_field_label'          => 'Salutation',
            'salutation_field_label_female'   => 'Female',
            'salutation_field_label_male'     => 'Male',
            'salutation_field_label_other'    => 'Other',
            'birthdate_field_day_label'   => 'Day',
            'birthdate_field_month_label' => 'Month',
            'birthdate_field_year_label'  => 'Year',
            'birthdate_field_label'       => 'Birthdate',
            'company_reg_field_label'     => 'Company Registration Number',
            'installments_intro_text'     => 'Please choose your payment plan',
            'cembrapay_invoice_template'  => 'CembraPay invoice template',
            'installments_full_template'  => 'Pay in full template',
            'installments_3_template'     => 'Pay in 3 installments template',
            'installments_4_template'     => 'Pay in 4 installments template',
            'installments_6_template'     => 'Pay in 6 installments template',
            'installments_12_template'    => 'Pay in 12 installments template',
            'installments_24_template'    => 'Pay in 24 installments template',
            'installments_36_template'    => 'Pay in 36 installments template',
            'installments_48_template'    => 'Pay in 48 installments template',
            'invoice_via_email'           => 'Invoice sent via e-mail to: {email}',
            'invoice_via_post'            => 'Invoice sent by Post (4.25 CHF per letter) to: {address}'
        );

    }

    public static function convert_date( $date_string ) {

        $date_format_wp = get_option('date_format'); // e.g., 'F j, Y'
        $locale         = get_locale();

        // Map WP format to ICU format for IntlDateFormatter
        $wp_to_icu = [
            'F' => 'MMMM', // full month name
            'M' => 'MMM',  // short month
            'm' => 'MM',   // month number with leading zero
            'j' => 'd',    // day
            'd' => 'dd',   // day with leading zero
            'Y' => 'yyyy', // year,
            ',' => '',
            '.' => ''
        ];
        $icu_format = strtr($date_format_wp, $wp_to_icu);

        $fmt = new \IntlDateFormatter(
            $locale,
            \IntlDateFormatter::NONE,
            \IntlDateFormatter::NONE,
            get_option('timezone_string') ?: 'UTC',
            \IntlDateFormatter::GREGORIAN,
            $icu_format
        );

        $timestamp = $fmt->parse($date_string);
        $timestamp = $timestamp ? $timestamp : strtotime($date_string);

        return date('Y-m-d', $timestamp);

    }

}
?>