<?php

namespace GOSP\GravityOps\Core\SuiteCore\Admin;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Renders cross-form console, inventory, and analytics views inside the admin shell.
 *
 * Emits the shared `gops-*` table / stat-tile / empty-state markup so the "aggregate data
 * across forms/steps" tabs added to several suite plugins read as one system. Data gathering
 * and any inline action forms remain the responsibility of the calling plugin.
 */
class GridRenderer {

	/**
	 * Render a data table inside a card, or an empty state when there are no rows.
	 *
	 * Each cell is either a scalar (escaped as text) or an array with an `html` key
	 * (rendered raw — the caller must pre-escape it, e.g. badges, links, action forms).
	 * A column may be `['label' => '…', 'align' => 'right']`.
	 *
	 * @param array<string,mixed> $config `title`, `intro`, `columns` (list of strings or
	 *                                     arrays), `rows` (list of cell lists), `empty`
	 *                                     (args for empty_state()).
	 * @return void
	 */
	public static function table( array $config ): void {
		$title   = isset( $config['title'] ) ? (string) $config['title'] : '';
		$intro   = isset( $config['intro'] ) ? (string) $config['intro'] : '';
		$columns = isset( $config['columns'] ) && is_array( $config['columns'] ) ? $config['columns'] : [];
		$rows    = isset( $config['rows'] ) && is_array( $config['rows'] ) ? $config['rows'] : [];

		echo '<div class="gops-card">';
		if ( '' !== $title ) {
			echo '<h2 class="gops-title" style="margin:0 0 10px;">' . esc_html( $title ) . '</h2>';
		}
		if ( '' !== $intro ) {
			echo '<p>' . esc_html( $intro ) . '</p>';
		}

		if ( empty( $rows ) ) {
			$empty = isset( $config['empty'] ) && is_array( $config['empty'] ) ? $config['empty'] : [];
			self::empty_state( $empty );
			echo '</div>';
			return;
		}

		echo '<table class="gops-table"><thead><tr>';
		foreach ( $columns as $column ) {
			$label = is_array( $column ) ? (string) ( $column['label'] ?? '' ) : (string) $column;
			$align = is_array( $column ) && 'right' === ( $column['align'] ?? '' ) ? ' class="gops-table__num"' : '';
			echo '<th' . $align . '>' . esc_html( $label ) . '</th>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $align is a fixed literal.
		}
		echo '</tr></thead><tbody>';

		foreach ( $rows as $row ) {
			echo '<tr>';
			foreach ( (array) $row as $index => $cell ) {
				$column = $columns[ $index ] ?? '';
				$align  = is_array( $column ) && 'right' === ( $column['align'] ?? '' ) ? ' class="gops-table__num"' : '';
				if ( is_array( $cell ) && isset( $cell['html'] ) ) {
					echo '<td' . $align . '>' . $cell['html'] . '</td>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Caller-supplied pre-escaped markup.
				} else {
					echo '<td' . $align . '>' . esc_html( (string) $cell ) . '</td>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $align is a fixed literal.
				}
			}
			echo '</tr>';
		}

		echo '</tbody></table>';
		echo '</div>';
	}

	/**
	 * Render a row of compact summary stat tiles.
	 *
	 * @param array<int,array{label:string,value:string}> $stats Stat tiles (label + value).
	 * @return void
	 */
	public static function stat_cards( array $stats ): void {
		if ( empty( $stats ) ) {
			return;
		}

		echo '<div class="gops-stats">';
		foreach ( $stats as $stat ) {
			echo '<div class="gops-stat">';
			echo '<div class="gops-stat__value">' . esc_html( (string) ( $stat['value'] ?? '' ) ) . '</div>';
			echo '<div class="gops-stat__label">' . esc_html( (string) ( $stat['label'] ?? '' ) ) . '</div>';
			echo '</div>';
		}
		echo '</div>';
	}

	/**
	 * Render an empty-state message, optionally with a docs link/button.
	 *
	 * @param array<string,mixed> $args `title`, `message`, `docs_url`, `button_label`.
	 * @return void
	 */
	public static function empty_state( array $args = [] ): void {
		$title   = isset( $args['title'] ) ? (string) $args['title'] : '';
		$message = isset( $args['message'] ) ? (string) $args['message'] : 'Nothing to show here yet.';
		$url     = isset( $args['docs_url'] ) ? (string) $args['docs_url'] : '';
		$button  = isset( $args['button_label'] ) ? (string) $args['button_label'] : 'View the docs';

		echo '<div class="gops-empty">';
		if ( '' !== $title ) {
			echo '<p class="gops-empty__title">' . esc_html( $title ) . '</p>';
		}
		echo '<p class="gops-empty__msg">' . esc_html( $message ) . '</p>';
		if ( '' !== $url ) {
			echo '<a class="button button-primary" href="' . esc_url( $url ) . '">' . esc_html( $button ) . '</a>';
		}
		echo '</div>';
	}

	/**
	 * Build a column definition for table().
	 *
	 * @param string $label Column header label.
	 * @param string $align '' (left) or 'right' (numeric).
	 * @return array{label:string,align:string}
	 */
	public static function col( string $label, string $align = '' ): array {
		return [
			'label' => $label,
			'align' => $align,
		];
	}

	/**
	 * Build a status badge span.
	 *
	 * @param string $text  Badge text.
	 * @param string $state '' (neutral), 'ok', or 'warn'.
	 * @return string
	 */
	public static function badge( string $text, string $state = '' ): string {
		$class = 'gops-badge';
		if ( 'ok' === $state ) {
			$class .= ' gops-badge--ok';
		} elseif ( 'warn' === $state ) {
			$class .= ' gops-badge--warn';
		}

		return '<span class="' . esc_attr( $class ) . '">' . esc_html( $text ) . '</span>';
	}
}
