<?php

namespace includes\views;

use Exception;
use includes\api\WTV_Invoices;
use includes\WTV_Plugin;
use WC_Order;

/**
 * WooCommerce My Account: Faktura column on Orders and Visma PDF download for the order owner.
 */
class WTV_My_Account_Invoices {

	const ORDERS_ENDPOINT = 'orders';

	const DOWNLOAD_QUERY = 'wtv_visma_invoice';

	/**
	 * Register hooks once WooCommerce is available.
	 */
	public static function init() {
		if ( false !== has_filter( 'woocommerce_account_orders_columns', array( __CLASS__, 'orders_columns' ) ) ) {
			return;
		}

		add_filter( 'woocommerce_account_orders_columns', array( __CLASS__, 'orders_columns' ) );
		add_action( 'woocommerce_my_account_my_orders_column_faktura', array( __CLASS__, 'orders_column_faktura' ) );
		add_action( 'template_redirect', array( __CLASS__, 'maybe_stream_invoice_pdf' ), 1 );
	}

	/**
	 * Whether My Account invoice downloads are enabled in settings.
	 *
	 * @return bool
	 */
	public static function is_feature_enabled() {
		return (bool) get_option( 'visma_show_my_account_invoices' );
	}

	/**
	 * @param array $columns
	 * @return array
	 */
	public static function orders_columns( $columns ) {
		if ( ! self::is_feature_enabled() ) {
			return $columns;
		}

		$new = array();
		foreach ( $columns as $key => $label ) {
			if ( 'order-actions' === $key ) {
				$new['faktura'] = __( 'Faktura', WTV_Plugin::TEXTDOMAIN );
			}
			$new[ $key ] = $label;
		}

		return $new;
	}

	/**
	 * @param WC_Order $order
	 */
	public static function orders_column_faktura( $order ) {
		if ( ! self::is_feature_enabled() ) {
			return;
		}

		if ( ! $order instanceof WC_Order ) {
			return;
		}

		if ( ! WTV_Invoices::get_visma_invoice_id( $order ) ) {
			return;
		}

		if ( ! self::order_matches_payment_method_filter( $order ) ) {
			return;
		}

		$download_url = self::get_download_url( $order );
		?>
		<a href="<?php echo esc_url( $download_url ); ?>" class="woocommerce-button button" target="_blank" rel="noopener noreferrer"><?php echo esc_html__( 'Ladda ned', WTV_Plugin::TEXTDOMAIN ); ?></a>
		<?php
	}

	/**
	 * @param WC_Order $order
	 * @return bool
	 */
	public static function order_matches_payment_method_filter( $order ) {
		$selected = get_option( 'visma_my_account_invoices_payment_methods', array() );
		if ( ! is_array( $selected ) ) {
			$selected = array();
		}
		$selected = array_values(
			array_filter(
				array_map(
					static function ( $v ) {
						return is_string( $v ) ? trim( $v ) : '';
					},
					$selected
				)
			)
		);
		if ( empty( $selected ) ) {
			return true;
		}

		return in_array( $order->get_payment_method(), $selected, true );
	}

	/**
	 * Early checks for streaming a Visma invoice PDF from My Account (query args, page, endpoint, user, order id).
	 *
	 * @return int|null Order ID when the request is a candidate for streaming; null otherwise.
	 */
	private static function get_invoice_pdf_stream_order_id() {
		if ( ! isset( $_GET[ self::DOWNLOAD_QUERY ], $_GET['order_id'], $_GET['_wpnonce'] ) ) {
			return null;
		}

		if ( ! function_exists( 'is_account_page' ) || ! is_account_page() ) {
			return null;
		}
		if ( ! function_exists( 'is_wc_endpoint_url' ) || ! is_wc_endpoint_url( self::ORDERS_ENDPOINT ) ) {
			return null;
		}
		if ( ! is_user_logged_in() ) {
			return null;
		}

		$order_id = absint( wp_unslash( $_GET['order_id'] ) );
		if ( ! $order_id ) {
			return null;
		}

		return $order_id;
	}

	/**
	 * Stream PDF before My Account HTML when download query args are present on the orders endpoint.
	 */
	public static function maybe_stream_invoice_pdf() {
		if ( ! self::is_feature_enabled() ) {
			return;
		}

		$order_id = self::get_invoice_pdf_stream_order_id();
		if ( null === $order_id ) {
			return;
		}

		wtv_write_log( '[WTV MyAccount Invoices] maybe_stream_invoice_pdf: order_id=' . $order_id . ' user_id=' . get_current_user_id() );

		if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), self::nonce_action( $order_id ) ) ) {
			wtv_write_log( '[WTV MyAccount Invoices] maybe_stream_invoice_pdf: nonce failed order_id=' . $order_id );
			wp_die( esc_html__( 'Link expired', WTV_Plugin::TEXTDOMAIN ), esc_html__( 'Error', WTV_Plugin::TEXTDOMAIN ), array( 'response' => 403 ) );
		}

		$order = wc_get_order( $order_id );
		if ( ! $order instanceof WC_Order ) {
			wtv_write_log( '[WTV MyAccount Invoices] maybe_stream_invoice_pdf: invalid order_id=' . $order_id );
			wp_die( esc_html__( 'Invalid order.', WTV_Plugin::TEXTDOMAIN ), esc_html__( 'Error', WTV_Plugin::TEXTDOMAIN ), array( 'response' => 404 ) );
		}

		$user_id = get_current_user_id();
		if ( (int) $order->get_user_id() !== $user_id || $user_id <= 0 ) {
			wtv_write_log( '[WTV MyAccount Invoices] maybe_stream_invoice_pdf: ownership denied order_id=' . $order_id );
			wp_die( esc_html__( 'Invalid order.', WTV_Plugin::TEXTDOMAIN ), esc_html__( 'Error', WTV_Plugin::TEXTDOMAIN ), array( 'response' => 403 ) );
		}

		if ( ! WTV_Invoices::get_visma_invoice_id( $order ) ) {
			wtv_write_log( '[WTV MyAccount Invoices] maybe_stream_invoice_pdf: no visma_invoice_id order_id=' . $order_id );
			wp_die( esc_html__( 'Invalid order.', WTV_Plugin::TEXTDOMAIN ), esc_html__( 'Error', WTV_Plugin::TEXTDOMAIN ), array( 'response' => 404 ) );
		}

		if ( ! self::order_matches_payment_method_filter( $order ) ) {
			wtv_write_log( '[WTV MyAccount Invoices] maybe_stream_invoice_pdf: payment method not allowed order_id=' . $order_id );
			wp_die( esc_html__( 'Invalid order.', WTV_Plugin::TEXTDOMAIN ), esc_html__( 'Error', WTV_Plugin::TEXTDOMAIN ), array( 'response' => 403 ) );
		}

		try {
			wtv_write_log( '[WTV MyAccount Invoices] maybe_stream_invoice_pdf: fetching PDF via Visma /print order_id=' . $order_id );
			$pdf = WTV_Invoices::get_invoice_print_body( $order );
		} catch ( Exception $e ) {
			wtv_write_log( '[WTV MyAccount Invoices] maybe_stream_invoice_pdf: exception order_id=' . $order_id . ' msg=' . $e->getMessage() );
			wp_die( esc_html( $e->getMessage() ), esc_html__( 'Error', WTV_Plugin::TEXTDOMAIN ), array( 'response' => 500 ) );
		}

		wtv_write_log( '[WTV MyAccount Invoices] maybe_stream_invoice_pdf: OK streamed PDF order_id=' . $order_id . ' bytes=' . strlen( $pdf ) );
		nocache_headers();
		header( 'Content-Type: application/pdf' );
		header( 'Content-Disposition: inline; filename="visma-invoice-order-' . $order_id . '.pdf"' );
		header( 'Content-Length: ' . strlen( $pdf ) );
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- binary PDF
		echo $pdf;
		exit;
	}

	/**
	 * @param int $order_id
	 * @return string
	 */
	public static function nonce_action( $order_id ) {
		return 'wtv_myaccount_invoice_pdf_' . (int) $order_id;
	}

	/**
	 * @param WC_Order $order
	 * @return string
	 */
	public static function get_download_url( $order ) {
		$url = add_query_arg(
			array(
				self::DOWNLOAD_QUERY => '1',
				'order_id'           => $order->get_id(),
			),
			wc_get_endpoint_url( self::ORDERS_ENDPOINT, '', wc_get_page_permalink( 'myaccount' ) )
		);

		return wp_nonce_url( $url, self::nonce_action( $order->get_id() ) );
	}
}
