<?php
declare(strict_types=1);

namespace Wohno\Plugin\Widget;

use WP_Widget;
use Wohno\Plugin\Api\Client;
use Wohno\Plugin\Api\ListingQuery;
use Wohno\Plugin\Render\ListingsRenderer;

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

/**
 * Classic sidebar/widget-area widget — lets the makler place listings in any
 * registered widget area ("die Stellen adressieren").
 */
final class ListingsWidget extends WP_Widget {

	/**
	 * Shared API client (set once at construction).
	 *
	 * @var Client|null
	 */
	private static ?Client $client = null;

	/**
	 * Shared renderer (set once at construction).
	 *
	 * @var ListingsRenderer|null
	 */
	private static ?ListingsRenderer $renderer = null;

	/**
	 * WordPress re-instantiates widgets without our dependencies, so the
	 * client/renderer are stored statically on the first (wired) construction.
	 *
	 * @param Client|null           $client   API client.
	 * @param ListingsRenderer|null $renderer HTML renderer.
	 */
	public function __construct( ?Client $client = null, ?ListingsRenderer $renderer = null ) {
		if ( null !== $client ) {
			self::$client = $client;
		}
		if ( null !== $renderer ) {
			self::$renderer = $renderer;
		}

		parent::__construct(
			'wohno_listings_widget',
			__( 'Wohno – Inserate', 'wohno' ),
			array( 'description' => __( 'Zeigt Wohno-Inserate in einer Widget-Area.', 'wohno' ) )
		);
	}

	/**
	 * Render the widget on the frontend.
	 *
	 * @param array<string, mixed> $args     Theme widget-area wrappers.
	 * @param array<string, mixed> $instance Saved widget settings.
	 * @return void
	 */
	public function widget( $args, $instance ): void {
		if ( null === self::$client || null === self::$renderer ) {
			return;
		}

		$title   = ! empty( $instance['title'] ) ? (string) $instance['title'] : '';
		$city    = ! empty( $instance['city'] ) ? (string) $instance['city'] : '';
		$limit   = ! empty( $instance['limit'] ) ? (int) $instance['limit'] : 3;
		$columns = ! empty( $instance['columns'] ) ? (int) $instance['columns'] : 1;

		$result = self::$client->listings(
			ListingQuery::from_atts(
				array(
					'city'  => $city,
					'limit' => $limit,
				)
			)
		);
		if ( is_wp_error( $result ) ) {
			return;
		}

		echo wp_kses_post( $args['before_widget'] );
		if ( '' !== $title ) {
			echo wp_kses_post( $args['before_title'] ) . esc_html( $title ) . wp_kses_post( $args['after_title'] );
		}
		// Renderer output is built entirely from esc_* helpers internally.
		echo self::$renderer->grid( $result['listings'], array( 'columns' => $columns ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo wp_kses_post( $args['after_widget'] );
	}

	/**
	 * Render the widget admin form.
	 *
	 * @param array<string, mixed> $instance Saved widget settings.
	 * @return void
	 */
	public function form( $instance ): void {
		$title   = $instance['title'] ?? '';
		$city    = $instance['city'] ?? '';
		$limit   = $instance['limit'] ?? 3;
		$columns = $instance['columns'] ?? 1;
		?>
		<p>
			<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php echo esc_html__( 'Titel', 'wohno' ); ?></label>
			<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
		</p>
		<p>
			<label for="<?php echo esc_attr( $this->get_field_id( 'city' ) ); ?>"><?php echo esc_html__( 'Stadt (optional)', 'wohno' ); ?></label>
			<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'city' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'city' ) ); ?>" type="text" value="<?php echo esc_attr( $city ); ?>" />
		</p>
		<p>
			<label for="<?php echo esc_attr( $this->get_field_id( 'limit' ) ); ?>"><?php echo esc_html__( 'Anzahl', 'wohno' ); ?></label>
			<input class="tiny-text" id="<?php echo esc_attr( $this->get_field_id( 'limit' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'limit' ) ); ?>" type="number" min="1" max="12" value="<?php echo esc_attr( (string) $limit ); ?>" />
		</p>
		<p>
			<label for="<?php echo esc_attr( $this->get_field_id( 'columns' ) ); ?>"><?php echo esc_html__( 'Spalten', 'wohno' ); ?></label>
			<input class="tiny-text" id="<?php echo esc_attr( $this->get_field_id( 'columns' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'columns' ) ); ?>" type="number" min="1" max="4" value="<?php echo esc_attr( (string) $columns ); ?>" />
		</p>
		<?php
	}

	/**
	 * Sanitise widget settings on save.
	 *
	 * @param array<string, mixed> $new_instance New settings from the form.
	 * @param array<string, mixed> $old_instance Previously saved settings.
	 * @return array<string, mixed> Sanitised settings to persist.
	 */
	public function update( $new_instance, $old_instance ): array {
		return array(
			'title'   => sanitize_text_field( (string) ( $new_instance['title'] ?? '' ) ),
			'city'    => sanitize_text_field( (string) ( $new_instance['city'] ?? '' ) ),
			'limit'   => max( 1, min( 12, (int) ( $new_instance['limit'] ?? 3 ) ) ),
			'columns' => max( 1, min( 4, (int) ( $new_instance['columns'] ?? 1 ) ) ),
		);
	}
}
