<?php

function formatToInt64($amount)
{
  $formattedAmount = number_format($amount, 2, '.', '');
  $formattedAmount = round($formattedAmount * 100);
  return $formattedAmount;
}

// Helper function to validate phone number using libphonenumber
function tzp_validate_phone_number($phoneNumber)
{
  // Check if phone starts with +
  if (strpos($phoneNumber, '+') !== 0) {
    return false;
  }

  // Validate using libphonenumber
  try {
    $phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
    $parsedNumber = $phoneUtil->parse($phoneNumber, null);
    return $phoneUtil->isValidNumber($parsedNumber);
  } catch (\libphonenumber\NumberParseException $e) {
    return false;
  }
}

// Helper function to parse phone number and get calling_code and number
function tzp_parse_phone_number($phoneNumber)
{
  $phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
  $parsedNumber = $phoneUtil->parse($phoneNumber, null);

  $countryCode = (string) $parsedNumber->getCountryCode();
  $nationalNumber = (string) $parsedNumber->getNationalNumber();

  // Validate combined length (7-15 digits excluding +, per E.164 standard)
  $totalDigits = strlen($countryCode) + strlen($nationalNumber);
  if ($totalDigits < 7 || $totalDigits > 15) {
    // If validation fails, return original values but log warning
    error_log("Phone number validation warning: Combined length is {$totalDigits} digits (expected 7-15)");
  }

  return array(
    "calling_code" => "+" . $countryCode,
    "number" => $nationalNumber,
  );
}

// Validate phone numbers for WooCommerce BLOCK checkout (Store API)
function tzp_validate_block_checkout_phone($order, $request)
{
  // Only validate if Tazapay is the selected payment method
  $payment_method = $request->get_param('payment_method');
  if ($payment_method !== 'tazapay') {
    return $order;
  }

  // Helper to throw route exception when available, otherwise throw generic Exception
  $throw_route_exception = function ($error_code, $message, $status_code = 400) {
    $class = 'Automattic\\WooCommerce\\StoreApi\\Exceptions\\RouteException';
    if (class_exists($class)) {
      throw new $class($error_code, $message, $status_code);
    } else {
      throw new \Exception($message, $status_code);
    }
  };

  // Validate billing phone (if provided)
  $billing_address = $request->get_param('billing_address');
  if (isset($billing_address['phone']) && !empty($billing_address['phone'])) {
    $billing_phone = trim($billing_address['phone']);

    if (!tzp_validate_phone_number($billing_phone)) {
      $throw_route_exception('woocommerce_rest_checkout_phone_error', 'Please enter a valid billing phone number with country code including +', 400);
    }
  }

  // Validate shipping phone (if provided)
  $shipping_address = $request->get_param('shipping_address');
  if (isset($shipping_address['phone']) && !empty($shipping_address['phone'])) {
    $shipping_phone = trim($shipping_address['phone']);

    if (!tzp_validate_phone_number($shipping_phone)) {
      $throw_route_exception('woocommerce_rest_checkout_phone_error', 'Please enter a valid shipping phone number with country code including +', 400);
    }
  }

  return $order;
}

// Validate phone numbers for WooCommerce CLASSIC checkout
function tzp_validate_classic_checkout_phone()
{

  // Only validate if Tazapay is the selected payment method
  $payment_method = isset($_POST['payment_method']) ? $_POST['payment_method'] : '';
  if ($payment_method !== 'tazapay') {
    return;
  }

  // Validate billing phone (if provided)
  if (isset($_POST['billing_phone']) && !empty($_POST['billing_phone'])) {
    $billing_phone = sanitize_text_field($_POST['billing_phone']);

    if (!tzp_validate_phone_number($billing_phone)) {
      wc_add_notice('Please enter a valid billing phone number with country code including +', 'error');
    }
  }

  // Validate shipping phone (if provided)
  if (isset($_POST['shipping_phone']) && !empty($_POST['shipping_phone'])) {
    $shipping_phone = sanitize_text_field($_POST['shipping_phone']);

    if (!tzp_validate_phone_number($shipping_phone)) {
      wc_add_notice('Please enter a valid shipping phone number with country code including +', 'error');
    }
  }
}

// Helper function to sanitize address fields by removing special characters
function tzp_sanitize_address_field($value)
{
  if (empty($value)) {
    return $value;
  }
  // Remove special characters: < > { } | \ ^ ` =
  $special_chars = array('<', '>', '{', '}', '|', '\\', '^', '`', '=');
  $sanitized = str_replace($special_chars, '', $value);

  // Normalize whitespace: collapse multiple spaces into single space and trim
  $sanitized = preg_replace('/\s+/', ' ', $sanitized);
  $sanitized = trim($sanitized);

  return $sanitized;
}

// Helper function to sanitize postal code according to backend validation
function tzp_sanitize_postal_code($value)
{
  if (empty($value)) {
    return $value;
  }
  // Remove all characters except A-Z, a-z, 0-9, spaces, and hyphens
  $sanitized = preg_replace('/[^A-Za-z0-9 -]/', '', $value);

  // Trim to max 12 characters
  $sanitized = substr($sanitized, 0, 12);

  return $sanitized;
}

// get Checkout API Args
function tzp_checkoutRequestBody($order, $description, $paymentArgs, $items)
{

  $plugin = tzp_get_plugin_info();
  $apiSettings = tzp_getAdminAPISettings();

  $billingDetails = array(
    "name" => $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
    "address" => array(
      "line1" => tzp_sanitize_address_field($order->get_billing_address_1()),
      "line2" => tzp_sanitize_address_field($order->get_billing_address_2()),
      "city" => tzp_sanitize_address_field($order->get_billing_city()),
      "state" => "",
      "country" => $order->get_billing_country(),
      "postal_code" => tzp_sanitize_postal_code($order->get_billing_postcode()),
    ),
  );

  // send phone field only if phone number is present
  if ($order->get_billing_phone()) {
    $billing_phone = $order->get_billing_phone();
    $parsedPhone = tzp_parse_phone_number($billing_phone);
    $billingDetails['phone'] = $parsedPhone;
  }

  if ($order->get_billing_state()) {
    $billingDetails['address']['state'] = $order->get_billing_country() . '-' . tzp_sanitize_address_field($order->get_billing_state());
  }

  $shippingDetails = array(
    "name" => $order->get_shipping_first_name() . ' ' . $order->get_shipping_last_name(),
    "address" => array(
      "line1" => tzp_sanitize_address_field($order->get_shipping_address_1()),
      "line2" => tzp_sanitize_address_field($order->get_shipping_address_2()),
      "city" => tzp_sanitize_address_field($order->get_shipping_city()),
      "state" => "",
      "country" => $order->get_shipping_country(),
      "postal_code" => tzp_sanitize_postal_code($order->get_shipping_postcode()),
    ),
  );

  if ($order->get_shipping_state()) {
    $shippingDetails['address']['state'] = $order->get_shipping_country() . '-' . tzp_sanitize_address_field($order->get_shipping_state());
  }

  if ($order->get_shipping_phone()) {
    $shipping_phone = $order->get_shipping_phone();
    $parsedPhone = tzp_parse_phone_number($shipping_phone);
    $shippingDetails['phone'] = $parsedPhone;
  }

  $customerDetails = array(
    "email" => $order->get_billing_email(),
    "name" => $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
    "country" => $order->get_billing_country(),
  );

  if ($order->get_billing_phone()) {
    $billing_phone = $order->get_billing_phone();
    $parsedPhone = tzp_parse_phone_number($billing_phone);
    $customerDetails['phone'] = $parsedPhone;
  }

  $today = new DateTime();
  $today->modify('+7 days');
  $expiresAt = $today->format('Y-m-d\TH:i:s\Z');

  $checkoutArgs = array(
    "amount" => formatToInt64($order->get_total()),
    "invoice_currency" => $order->get_currency(),
    "transaction_description" => $description,
    "txn_source_category" => "woocommerce",
    "txn_source" => "woocommerce_" . $plugin['Version'],
    "webhook_url" => $paymentArgs['callback_url'],
    "success_url" => $paymentArgs['complete_url'],
    "cancel_url" => $paymentArgs['abort_url'],
    "shipping_details" => $shippingDetails,
    "billing_details" => $billingDetails,
    "customer_details" => $customerDetails,
    "same_as_billing_address" => $paymentArgs['same_as_billing_address'],
    "expires_at" => $expiresAt,
    "reference_id" => strval($order->get_id()),
    "items" => $items,
  );

  if (!(bool) empty($apiSettings['paymentFilter'])) {
    $checkoutArgs['remove_payment_methods'] = $apiSettings['paymentFilter'];
  }

  return $checkoutArgs;
}

// validates the api keys entered in admin page.
function tzp_validate_api_keys($data)
{
  $mode = $data['woocommerce_tazapay_select_env_mode'];

  $api_key = $data['woocommerce_tazapay_prod_api_key'];
  $api_secret = $data['woocommerce_tazapay_prod_secret_key'];
  $base_api_url = 'https://service.tazapay.com';


  if ($mode === 'Sandbox') {
    $api_key = $data['woocommerce_tazapay_sandbox_api_key'];
    $api_secret = $data['woocommerce_tazapay_sandbox_secret_key'];
    $base_api_url = 'https://service-sandbox.tazapay.com';
  }

  $isValidKeys = tzp_collectMetaData_api($api_key, $api_secret, $base_api_url);
  if ($isValidKeys->status == 'error') {
    return true;
  }
  return false;
}

// validates the custom styling format entered in admin page.
function tzp_validate_custom_style_css($custom_style_css)
{

  if ($custom_style_css) {

    $custom_style_css = stripslashes($custom_style_css);

    $json = json_decode($custom_style_css, true, 5);

    $isString = is_string($custom_style_css);
    $isArray = is_array($json);
    $isObject = is_object($json);

    return $isString && ($isArray || $isObject);
  }
  return true;
}

// This func is for webhook verification which ensures origin of webhook is from Tazapay
function tzp_verify_webhook_signature($raw_payload, $signature_header)
{
  $settings = tzp_getAdminAPISettings();
  $webhook_secret = $settings['secretKey'];

  if (empty($webhook_secret)) {
    return false;
  }

  if (empty($signature_header)) {
    return false;
  }

  $payload = json_decode($raw_payload, true);
  if (!is_array($payload)) {
    return false;
  }

  $event_id  = isset($payload['id']) ? $payload['id'] : '';
  $timestamp = isset($payload['created_at']) ? $payload['created_at'] : '';

  if (empty($event_id) || empty($timestamp)) {
    return false;
  }

  $webhook_time = strtotime($timestamp);
  if ($webhook_time === false || abs(time() - $webhook_time) > 600) {
    return false;
  }

  $message            = $event_id . $raw_payload . $timestamp;
  $expected_signature = base64_encode(hash_hmac('sha256', $message, $webhook_secret, true));

  if (!hash_equals($expected_signature, $signature_header)) {
    return false;
  }

  return true;
}


// Adds txnDetailsTable in customers account orders->view.
add_action('woocommerce_view_order', 'tzp_TxnDetailsTable', 20);
function tzp_TxnDetailsTable($order_id)
{
  $order = wc_get_order($order_id);
  $paymentMethod = $order->get_payment_method();
  $txn_no = $order->get_meta('txn_no', true);

  if (!empty($txn_no) && $paymentMethod == 'tazapay') {
    $user_email = $order->get_billing_email();
    ?>
    <h2><?php esc_html_e('Transaction Details', 'wc-tp-payment-gateway'); ?></h2>
    <p><?php esc_html_e('Payment powered by Tazapay', 'wc-tp-payment-gateway'); ?></p>
    <table class="woocommerce-table shop_table gift_info">
      <tbody>
        <tr>
          <th scope="row"><?php esc_html_e('Tazapay Payer E-Mail', 'wc-tp-payment-gateway'); ?></th>
          <td><?php esc_html_e($user_email, 'wc-tp-payment-gateway'); ?></td>
        </tr>
        <?php if ($txn_no) { ?>
          <tr>
            <th scope="row"><?php esc_html_e('Transaction no', 'wc-tp-payment-gateway'); ?></th>
            <td><?php esc_html_e($txn_no, 'wc-tp-payment-gateway'); ?></td>
          </tr>
        <?php } ?>
      </tbody>
    </table>
    <?php

  }
}

// Removes 'manually refund' button in woocommerce->orders->order page
add_action('admin_head', 'tzp_remove_manual_refunds');
function tzp_remove_manual_refunds()
{

  echo '<style>
    .do-manual-refund {
      display: none !important;
    }
    </style>';
}

add_action('admin_head', 'tzp_remove_refund_button_for_refunded');
function tzp_remove_refund_button_for_refunded()
{

  if (isset($_GET['post'])) {

    $order_id = (int) sanitize_text_field($_GET['post']);
    $order = wc_get_order($order_id);

    if (!is_null($order) && $order) {
      $paymentMethod = $order->get_payment_method();

      if ($paymentMethod == 'tazapay') {

        $orderStatus = $order->get_status();

        if ('refunded' == $orderStatus) {

          echo '<style>
            button.button.refund-items {
              display: none !important;
            }
            </style>';
        }
      }
    }
  }
}

// removes 'custom fields' section in woocommerce->orders->order below item.
add_action('add_meta_boxes', 'tzp_remove_shop_order_meta_boxe', 90);
function tzp_remove_shop_order_meta_boxe()
{
  remove_meta_box('postcustom', 'shop_order', 'normal');
}

// shows transaction details on click on an order in seller orders tab.
add_action('woocommerce_admin_order_data_after_order_details', 'tzp_order_meta_general');
function tzp_order_meta_general($order)
{
  $order_id = $order->get_id();
  $account_id = $order->get_meta('account_id', true);
  $txn_no = $order->get_meta('txn_no', true);

  if ($order->get_payment_method() == 'tazapay' && isset($account_id) && !empty($account_id)) {
    ?>
    <br class="clear" />
    <h3><?php esc_html_e('Transaction Details', 'wc-tp-payment-gateway'); ?></h3>

    <div class="address">
      <p><strong><?php esc_html_e('TazaPay Transaction no: ', 'wc-tp-payment-gateway'); ?></strong>
        <?php esc_html_e($txn_no, 'wc-tp-payment-gateway'); ?></p>
      <?php
      $getEscrowstate = tzp_get_checkout_api($order_id);
      if ($getEscrowstate->status == 'success') {
        ?>
        <p>
          <strong><?php esc_html_e('Payment status: ', 'wc-tp-payment-gateway'); ?></strong><?php esc_html_e($getEscrowstate->data->payment_status, 'wc-tp-payment-gateway'); ?>
        </p>
        <?php
      }
      ?>
      <a href="<?php echo esc_url($order->get_edit_order_url(), 'wc-tp-payment-gateway'); ?>&order-status=true"
        class="order-status-response button button-primary"><?php esc_html_e('Refresh Status', 'wc-tp-payment-gateway'); ?></a>
    </div>
    <?php
  }
}