<?php
/**
 * View data for payment-summary and payment-table templates — keeps markup files thin.
 *
 * @package WPEventGenius
 */

namespace WPEventGenius\Common\Services;

use WPEventGenius\Common\Event\EventPost;
use WPEventGenius\Common\Registration\Payment\Cart\LineItem;

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

class PaymentSummaryView {

	/**
	 * Full view model for the payment-summary template (event block is still rendered in the template).
	 *
	 * @param EventPost $event_post
	 * @param array     $args Optional. Same keys as {@see PaymentSummaryTemplateData::get()}.
	 * @return array{
	 *   summary: array,
	 *   data_attributes_html: string,
	 *   quantity_has_type_lines: bool,
	 *   quantity_rows: array<int, array<string, mixed>>,
	 *   payment_table: array
	 * }
	 */
	public static function build( EventPost $event_post, array $args = [] ) {
		$args = self::normalize_summary_args( $args );
		$summary = PaymentSummaryTemplateData::get( $event_post, $args );

		return array(
			'summary'                  => $summary,
			'data_attributes_html'     => self::html_data_attributes( $summary['data_attributes'] ),
			'quantity_has_type_lines'  => count( $summary['quantity_line_items'] ) > 1,
			'quantity_rows'            => self::quantity_rows( $summary['quantity_line_items'] ),
			'payment_table'            => self::payment_table( $event_post, $summary ),
		);
	}

	/**
	 * Payment table only (e.g. checkout modal). Resolves defaults and formatted amounts.
	 *
	 * @param LineItem[] $line_items
	 * @return array{
	 *   lines: array<int, array<string, mixed>>,
	 *   subtotal: float,
	 *   fee: float,
	 *   total: float,
	 *   show_subtotal_block: bool,
	 *   subtotal_formatted: string,
	 *   fee_formatted: string,
	 *   total_formatted: string
	 * }
	 */
	public static function payment_table( EventPost $event_post, array $summary ) {
		$line_items          = isset( $summary['line_items'] ) && is_array( $summary['line_items'] ) ? $summary['line_items'] : array();
		$show_subtotal_block = ! empty( $summary['show_subtotal_block'] );
		$subtotal            = isset( $summary['subtotal'] ) ? (float) $summary['subtotal'] : 0.0;
		$fee                 = isset( $summary['fee'] ) ? (float) $summary['fee'] : 0.0;
		$total               = isset( $summary['total'] ) ? (float) $summary['total'] : 0.0;

		if ( empty( $line_items ) ) {
			$event_cost = method_exists( $event_post, 'get_the_cost_amount' ) ? (float) $event_post->get_the_cost_amount() : 0.0;
			$line_items = array(
				new LineItem(
					$event_post->get_the_title(),
					1,
					$event_cost,
					array(
						'line_total' => $event_cost,
						'type_id'    => null,
					)
				),
			);
		}

		if ( $show_subtotal_block && $subtotal === 0.0 && $total === 0.0 && ! empty( $line_items ) ) {
			foreach ( $line_items as $item ) {
				if ( $item instanceof LineItem ) {
					$subtotal += $item->get_line_total();
				}
			}
			$subtotal = round( $subtotal, 2 );
			$total    = $subtotal;
		}

		$lines = array();
		foreach ( $line_items as $index => $item ) {
			if ( ! $item instanceof LineItem ) {
				continue;
			}
			$display    = $item->to_array_for_display();
			$type_id    = isset( $display['type_id'] ) && (int) $display['type_id'] > 0 ? (int) $display['type_id'] : null;
			// Must match evge-registration-form.js (#evge-line-item-event) for the non–type-based cost branch.
			$item_id    = $type_id !== null
				? 'evge-line-item-type-' . $type_id
				: ( $index === 0 ? 'evge-line-item-event' : 'evge-line-item-' . $index );
			$css_class  = 'evge-modal-line-item evge-cost-item' . ( $type_id !== null ? ' evge-type-cost-line' : '' );
			$lines[]    = array(
				'css_class'          => $css_class,
				'item_id'            => $item_id,
				'type_id'            => $type_id,
				'data_type_id_attr'  => $type_id !== null ? (string) $type_id : '',
				'unit_price'         => (float) $display['unit_price'],
				'quantity'           => (int) $display['quantity'],
				'label'              => $display['label'],
				'line_total'         => (float) $display['line_total'],
				'line_total_formatted' => self::format_amount( $event_post, (float) $display['line_total'] ),
			);
		}

		return array(
			'lines'                 => $lines,
			'subtotal'              => $subtotal,
			'fee'                   => $fee,
			'total'                 => $total,
			'show_subtotal_block'   => $show_subtotal_block,
			'subtotal_formatted'    => self::format_amount( $event_post, $subtotal ),
			'fee_formatted'         => self::format_amount( $event_post, $fee ),
			'total_formatted'       => self::format_amount( $event_post, $total ),
		);
	}

	/**
	 * Standalone payment table context when not using full summary (checkout modal).
	 *
	 * @param LineItem[] $line_items
	 */
	public static function payment_table_standalone(
		EventPost $event_post,
		array $line_items,
		$show_subtotal_block = true,
		$subtotal = 0.0,
		$fee = 0.0,
		$total = 0.0
	) {
		return self::payment_table(
			$event_post,
			array(
				'line_items'          => $line_items,
				'show_subtotal_block' => $show_subtotal_block,
				'subtotal'            => (float) $subtotal,
				'fee'                 => (float) $fee,
				'total'               => (float) $total,
			)
		);
	}

	/**
	 * @param LineItem[] $items
	 * @return array<int, array{item_id: string, css_class: string, quantity: int, label: string, data_type_id: string}>
	 */
	protected static function quantity_rows( array $items ) {
		$rows = array();
		foreach ( $items as $item ) {
			if ( ! $item instanceof LineItem ) {
				continue;
			}
			$type_id = $item->get_type_id();
			$type_id = ( $type_id !== null && (int) $type_id > 0 ) ? (int) $type_id : null;
			$item_id = $type_id !== null ? 'evge-line-item-type-' . $type_id : 'evge-line-item-event';
			$css_class = $type_id !== null ? 'evge-modal-line-item evge-cost-item evge-quantity-line-item' : 'evge-modal-line-item evge-cost-item';
			$rows[]    = array(
				'item_id'       => $item_id,
				'css_class'     => $css_class,
				'quantity'      => (int) $item->get_quantity(),
				'label'         => $item->get_label(),
				'data_type_id'  => $type_id !== null ? (string) $type_id : '',
			);
		}
		return $rows;
	}

	/**
	 * @param array<string, string> $data_attributes
	 */
	protected static function html_data_attributes( array $data_attributes ) {
		$html = '';
		foreach ( $data_attributes as $key => $val ) {
			if ( $val !== '' ) {
				$html .= ' data-' . esc_attr( $key ) . '="' . esc_attr( $val ) . '"';
			}
		}
		return $html;
	}

	protected static function format_amount( EventPost $event_post, $amount ) {
		$amount = (float) $amount;
		$display = method_exists( $event_post, 'get_cost_display_for_amount' ) ? $event_post->get_cost_display_for_amount( $amount ) : '';
		return $display !== '' ? $display : number_format_i18n( $amount, 2 );
	}

	/**
	 * @param array $args
	 * @return array
	 */
	protected static function normalize_summary_args( array $args ) {
		$defaults = array(
			'initial_type_quantities' => array(),
			'initial_subtotal'        => null,
			'initial_fee'             => null,
			'initial_total'           => null,
		);
		$merged = wp_parse_args( $args, $defaults );
		if ( ! is_array( $merged['initial_type_quantities'] ) ) {
			$merged['initial_type_quantities'] = array();
		}
		return $merged;
	}
}
