<?php
/**
 * Base Environment Implementation
 *
 * Abstract base class containing shared logic for all environments.
 * Concrete environment classes only need to define URLs and SSL behavior.
 *
 * @package Freefactu
 * @since 0.5.0
 */

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

use Freefactu_Vendor\Endroid\QrCode\Builder\Builder;
use Freefactu_Vendor\Endroid\QrCode\Encoding\Encoding;
use Freefactu_Vendor\Endroid\QrCode\ErrorCorrectionLevel;
use Freefactu_Vendor\Endroid\QrCode\RoundBlockSizeMode;
use Freefactu_Vendor\Endroid\QrCode\Writer\PngWriter;

/**
 * Class Freefactu_Base_Environment
 *
 * Abstract base class for environment implementations.
 * Contains all shared logic for QR generation, SOAP communication, and error handling.
 */
abstract class Freefactu_Base_Environment implements Freefactu_Environment_Interface {

	/**
	 * SOAP endpoint URL.
	 *
	 * @var string
	 */
	protected $soap_endpoint;

	/**
	 * QR validation base URL.
	 *
	 * @var string
	 */
	protected $qr_base_url;

	/**
	 * Get the AEAT SOAP endpoint URL.
	 *
	 * What this function does:
	 * - Returns the SOAP endpoint URL for AEAT Verifactu service
	 * - URL differs between production and test environments
	 * - Set by child classes (Production_Environment or Test_Environment)
	 *
	 * Where it's called from:
	 * - abstract-base-environment.php: send_to_aeat() method
	 *
	 * @return string SOAP endpoint URL.
	 */
	public function get_soap_endpoint(): string {
		return $this->soap_endpoint;
	}

	/**
	 * Get the AEAT QR validation base URL.
	 *
	 * What this function does:
	 * - Returns the base URL for QR code validation
	 * - URL differs between production and test environments
	 * - Set by child classes (Production_Environment or Test_Environment)
	 *
	 * Where it's called from:
	 * - abstract-base-environment.php: generate_qr_url() method
	 * - abstract-base-generator.php: prepare_verifactu_data() method
	 *
	 * @return string QR validation base URL.
	 */
	public function get_qr_base_url(): string {
		return $this->qr_base_url;
	}

	/**
	 * Generate the Verifactu QR code URL.
	 *
	 * What this function does:
	 * - Builds QR validation URL with invoice parameters
	 * - Includes NIF, invoice number, date, and amount
	 * - Uses environment-specific base URL
	 * - Returns complete URL for QR code generation
	 *
	 * Where it's called from:
	 * - class-freefactu-client.php: render_qr_code() method
	 * - class-freefactu-client.php: generate_and_save_qr() method
	 * - abstract-base-generator.php: prepare_verifactu_data() method
	 *
	 * @param WC_Order $order WooCommerce order.
	 * @param string   $invoice_number Invoice number.
	 * @param string   $company_nif Company NIF.
	 * @return string QR code validation URL.
	 */
	public function generate_qr_url( $order, string $invoice_number, string $company_nif ): string {
		// Safely get date, fallback to current date if order has no creation date
		$date_created = $order->get_date_created();
		$fecha = $date_created ? $date_created->date( 'd-m-Y' ) : gmdate( 'd-m-Y' );

		$params = array(
			'nif'      => $company_nif,
			'numserie' => $invoice_number,
			'fecha'    => $fecha,
			'importe'  => number_format( $order->get_total(), 2, '.', '' ),
		);

		return $this->qr_base_url . '?' . http_build_query( $params );
	}

	/**
	 * Generate QR code image as base64.
	 *
	 * What this function does:
	 * - Generates QR code image using endroid/qr-code library
	 * - Caches result in transients (30 days)
	 * - Returns base64 encoded PNG image
	 * - Returns empty string on failure
	 * - Uses v2 cache key to invalidate old external API cache
	 *
	 * Where it's called from:
	 * - class-freefactu-client.php: render_qr_code() method
	 * - class-freefactu-client.php: generate_and_save_qr() method
	 * - abstract-base-generator.php: prepare_verifactu_data() method
	 *
	 * @param string $url URL to encode in QR code.
	 * @param int    $size QR code size in pixels.
	 * @return string Base64 encoded image or empty string on failure.
	 */
	public function generate_qr_image( string $url, int $size = 150 ): string {
		if ( empty( $url ) ) {
			return '';
		}

		// Check cache first (v2 to invalidate old external API cache)
		$cache_key = 'freefactu_qr_v2_' . md5( $url . $size );
		$cached    = get_transient( $cache_key );

		if ( false !== $cached && strpos( $cached, 'data:image/png;base64,' ) === 0 ) {
			return $cached;
		}

		// Check if QR library is available
		if ( ! class_exists( 'Freefactu_Vendor\\Endroid\\QrCode\\Builder\\Builder' ) ) {
			Freefactu_Logger::log( 'QR Code library not loaded', 'error' );
			return '';
		}

		try {
		// Generate QR code using endroid/qr-code library (v6 uses named constructor args)
			$builder = new Builder(
				writer: new PngWriter(),
				data: $url,
				encoding: new Encoding( 'UTF-8' ),
				errorCorrectionLevel: ErrorCorrectionLevel::Low,
				size: $size,
				margin: 0,
				roundBlockSizeMode: RoundBlockSizeMode::Enlarge,
			);
			$result = $builder->build();

			// Convert to base64 using built-in getDataUri()
			$base64 = $result->getDataUri();

			// Cache for 30 days (QR content doesn't change)
			set_transient( $cache_key, $base64, 30 * DAY_IN_SECONDS );

			return $base64;

		} catch ( Exception $e ) {
			Freefactu_Logger::log( 'QR Code Generation Error: ' . $e->getMessage(), 'error' );
			return '';
		}
	}
}

