<?php
/**
 * Points d'entrée AJAX.
 */

defined( 'ABSPATH' ) || exit;

/**
 * Aperçu (image binaire) et enregistrement en médiathèque (JSON).
 */
class Mairie_Affiche_Information_Ajax {

	/**
	 * Accroches.
	 */
	public static function init() {
		add_action( 'wp_ajax_mairie_affiche_information_apercu', array( __CLASS__, 'apercu' ) );
		add_action( 'wp_ajax_mairie_affiche_information_enregistrer', array( __CLASS__, 'enregistrer' ) );
		add_action( 'wp_ajax_mairie_affiche_information_conseil_apercu', array( __CLASS__, 'conseil_apercu' ) );
		add_action( 'wp_ajax_mairie_affiche_information_conseil_enregistrer', array( __CLASS__, 'conseil_enregistrer' ) );
	}

	/**
	 * Convertit une date ISO en horodatage du fuseau du site.
	 *
	 * @param string $iso Date au format Y-m-d.
	 * @return int
	 */
	private static function horodatage( $iso ) {
		$date = DateTime::createFromFormat( '!Y-m-d', (string) $iso, wp_timezone() );
		if ( ! $date ) {
			$date = new DateTime( 'today', wp_timezone() );
		}
		return $date->getTimestamp();
	}

	/**
	 * Libellé à imprimer : texte personnalisé sinon date en toutes lettres.
	 *
	 * @param string $perso     Texte saisi.
	 * @param int    $timestamp Horodatage.
	 * @return string
	 */
	private static function libelle( $perso, $timestamp ) {
		$perso = trim( wp_strip_all_tags( (string) $perso ) );
		if ( '' !== $perso ) {
			return function_exists( 'mb_substr' ) ? mb_substr( $perso, 0, 80 ) : substr( $perso, 0, 80 );
		}
		return Mairie_Affiche_Information_Generateur::libelle_date( $timestamp );
	}

	/**
	 * Renvoie l'image générée (aperçu ou téléchargement).
	 */
	public static function apercu() {
		if ( ! mairie_affiche_information_utilisateur_autorise() ) {
			wp_die( esc_html__( 'Access denied.', 'mairie-affiche-information' ), '', array( 'response' => 403 ) );
		}
		check_ajax_referer( 'mairie_affiche_information_apercu', 'nonce' );

		$timestamp = self::horodatage( isset( $_GET['date'] ) ? sanitize_text_field( wp_unslash( $_GET['date'] ) ) : '' );
		$texte     = self::libelle( isset( $_GET['texte'] ) ? sanitize_text_field( wp_unslash( $_GET['texte'] ) ) : '', $timestamp );
		$format    = ( isset( $_GET['format'] ) && 'png' === $_GET['format'] ) ? 'png' : 'jpg';

		$binaire = Mairie_Affiche_Information_Generateur::rendu( $texte, $format );
		if ( is_wp_error( $binaire ) ) {
			wp_die( esc_html( $binaire->get_error_message() ), '', array( 'response' => 500 ) );
		}

		nocache_headers();
		header( 'Content-Type: ' . ( 'png' === $format ? 'image/png' : 'image/jpeg' ) );
		header( 'Content-Length: ' . strlen( $binaire ) );
		if ( ! empty( $_GET['dl'] ) ) {
			header( 'Content-Disposition: attachment; filename="' . Mairie_Affiche_Information_Generateur::nom_fichier( $timestamp, $format ) . '"' );
		}

		echo $binaire; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		exit;
	}

	/**
	 * Enregistre l'affiche dans la médiathèque.
	 */
	public static function enregistrer() {
		if ( ! mairie_affiche_information_utilisateur_autorise() ) {
			wp_send_json_error( array( 'message' => __( 'Access denied.', 'mairie-affiche-information' ) ), 403 );
		}
		if ( ! current_user_can( 'upload_files' ) ) {
			wp_send_json_error( array( 'message' => __( 'Your role is not allowed to upload files.', 'mairie-affiche-information' ) ), 403 );
		}
		check_ajax_referer( 'mairie_affiche_information_enregistrer', 'nonce' );

		$timestamp = self::horodatage( isset( $_POST['date'] ) ? sanitize_text_field( wp_unslash( $_POST['date'] ) ) : '' );
		$texte     = self::libelle( isset( $_POST['texte'] ) ? sanitize_text_field( wp_unslash( $_POST['texte'] ) ) : '', $timestamp );
		$format    = ( isset( $_POST['format'] ) && 'png' === $_POST['format'] ) ? 'png' : 'jpg';

		$resultat = Mairie_Affiche_Information_Mediatheque::enregistrer( $texte, $timestamp, $format );
		if ( is_wp_error( $resultat ) ) {
			wp_send_json_error( array( 'message' => $resultat->get_error_message() ) );
		}

		$resultat['message'] = sprintf(
			/* translators: %s : nom du fichier enregistré. */
			__( '%s has been added to the Media Library.', 'mairie-affiche-information' ),
			$resultat['nom']
		);

		wp_send_json_success( $resultat );
	}

	/**
	 * Paramètres communs aux deux points d'entrée « conseil ».
	 *
	 * @param array $source $_GET ou $_POST déjà déchappé.
	 * @return array timestamp, heure, lieu, format.
	 */
	private static function conseil_parametres( $source ) {
		$reglages = Mairie_Affiche_Information_Reglages::get();

		$heure = isset( $source['heure'] ) ? sanitize_text_field( $source['heure'] ) : '';
		$lieu  = isset( $source['lieu'] ) ? sanitize_text_field( $source['lieu'] ) : '';

		if ( '' === $lieu ) {
			$lieu = $reglages['conseil_lieu'];
		}
		if ( function_exists( 'mb_substr' ) ) {
			$lieu = mb_substr( $lieu, 0, 60 );
		} else {
			$lieu = substr( $lieu, 0, 60 );
		}

		return array(
			'timestamp' => self::horodatage( isset( $source['date'] ) ? sanitize_text_field( $source['date'] ) : '' ),
			'heure'     => '' !== $heure ? $heure : $reglages['conseil_heure'],
			'lieu'      => $lieu,
			'format'    => ( isset( $source['format'] ) && 'png' === $source['format'] ) ? 'png' : 'jpg',
		);
	}

	/**
	 * Aperçu du visuel « Conseil municipal ».
	 */
	public static function conseil_apercu() {
		if ( ! mairie_affiche_information_utilisateur_autorise() ) {
			wp_die( esc_html__( 'Access denied.', 'mairie-affiche-information' ), '', array( 'response' => 403 ) );
		}
		check_ajax_referer( 'mairie_affiche_information_conseil_apercu', 'nonce' );

		$p = self::conseil_parametres( wp_unslash( $_GET ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		$binaire = Mairie_Affiche_Information_Conseil::rendu( $p['timestamp'], $p['heure'], $p['lieu'], $p['format'] );
		if ( is_wp_error( $binaire ) ) {
			wp_die( esc_html( $binaire->get_error_message() ), '', array( 'response' => 500 ) );
		}

		nocache_headers();
		header( 'Content-Type: ' . ( 'png' === $p['format'] ? 'image/png' : 'image/jpeg' ) );
		header( 'Content-Length: ' . strlen( $binaire ) );
		if ( ! empty( $_GET['dl'] ) ) {
			header( 'Content-Disposition: attachment; filename="' . Mairie_Affiche_Information_Conseil::nom_fichier( $p['timestamp'], $p['format'] ) . '"' );
		}

		echo $binaire; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		exit;
	}

	/**
	 * Enregistre le visuel « Conseil municipal » dans la médiathèque.
	 */
	public static function conseil_enregistrer() {
		if ( ! mairie_affiche_information_utilisateur_autorise() ) {
			wp_send_json_error( array( 'message' => __( 'Access denied.', 'mairie-affiche-information' ) ), 403 );
		}
		if ( ! current_user_can( 'upload_files' ) ) {
			wp_send_json_error( array( 'message' => __( 'Your role is not allowed to upload files.', 'mairie-affiche-information' ) ), 403 );
		}
		check_ajax_referer( 'mairie_affiche_information_conseil_enregistrer', 'nonce' );

		$p = self::conseil_parametres( wp_unslash( $_POST ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing

		$resultat = Mairie_Affiche_Information_Mediatheque::enregistrer_conseil( $p['timestamp'], $p['heure'], $p['lieu'], $p['format'] );
		if ( is_wp_error( $resultat ) ) {
			wp_send_json_error( array( 'message' => $resultat->get_error_message() ) );
		}

		$resultat['message'] = sprintf(
			/* translators: %s: saved file name. */
			__( '%s has been added to the Media Library.', 'mairie-affiche-information' ),
			$resultat['nom']
		);

		wp_send_json_success( $resultat );
	}
}
