<?php

namespace GravityKit\GravityExport\PdfRenderer\Rendering;

use GravityKit\GravityExport\Feature;

/**
 * Adds a header image to the PDF, like a logo.
 * @since $ver$
 */
final class HeaderImage extends Feature {
	/**
	 * The setting names.
	 * @since $ver$
	 */
	private const SETTING_HEADER_IMAGE = 'pdf-header-image';
	private const SETTING_HEADER_IMAGE_MEDIA = 'pdf-header-image-media';
	private const SETTING_HEADER_IMAGE_PLACEMENT = 'pdf-header-image-placement';

	/**
	 * The placement options.
	 * @since $ver$
	 */
	private const SETTING_HEADER_IMAGE_PLACEMENT_LEFT = 'left';
	private const SETTING_HEADER_IMAGE_PLACEMENT_CENTER = 'center';
	private const SETTING_HEADER_IMAGE_PLACEMENT_RIGHT = 'right';

	/**
	 * @inheritDoc
	 * @since $ver$
	 */
	protected function init(): void {
		add_filter( 'gk/gravityexport/settings/sections', \Closure::fromCallable( [ $this, 'add_settings' ] ), 10, 2 );
		add_filter( 'gk/gravityexport/pdf/header', \Closure::fromCallable( [ $this, 'add_header_image' ] ), 10, 2 );
	}

	/**
	 * Add the settings to the foundation settings page.
	 * @since $ver$
	 *
	 * @param array $sections The sections.
	 *
	 * @return array The updated sections.
	 */
	private function add_settings( array $sections ): array {
		foreach ( $sections as $s => $section ) {
			if ( 'pdf-section' !== ( $section['id'] ?? null ) ) {
				continue;
			}

			$settings = [
				[
					'name'        => self::SETTING_HEADER_IMAGE,
					'id'          => self::SETTING_HEADER_IMAGE,
					'title'       => esc_html__( 'Use Header Image', 'gk-gravityexport' ),
					'description' => esc_html__( 'Add a header image to the PDF.', 'gk-gravityexport' ),
					'type'        => 'checkbox',
					'value'       => $this->addon->get_plugin_setting( self::SETTING_HEADER_IMAGE ) ?? false,
				],
				[
					'name'             => self::SETTING_HEADER_IMAGE_MEDIA,
					'id'               => self::SETTING_HEADER_IMAGE_MEDIA,
					'title'            => esc_html__( 'Header Image', 'gk-gravityexport' ),
					'type'             => 'media',
					'previewSize'      => 'medium',
					'useButtonText'    => 'Use image',
					'selectButtonText' => 'Select image',
					'removeButtonText' => 'Remove image',
					'fileTypes'        => [ 'image' ],
					'value'            => $this->addon->get_plugin_setting( self::SETTING_HEADER_IMAGE_MEDIA ) ?? '',
					'requires'         => [ [ 'id' => self::SETTING_HEADER_IMAGE, 'value' => true ] ],
				],
				[
					'name'        => self::SETTING_HEADER_IMAGE_PLACEMENT,
					'id'          => self::SETTING_HEADER_IMAGE_PLACEMENT,
					'title'       => esc_html__( 'Header Image placement', 'gk-gravityexport' ),
					'description' => esc_html__( 'The header image will have a height of 60px.', 'gk-gravityexport' ),
					'type'        => 'select',
					'choices'     => [
						[
							'title' => 'Left',
							'value' => self::SETTING_HEADER_IMAGE_PLACEMENT_LEFT,
						],
						[
							'title' => 'Center',
							'value' => self::SETTING_HEADER_IMAGE_PLACEMENT_CENTER,
						],
						[
							'title' => 'Right',
							'value' => self::SETTING_HEADER_IMAGE_PLACEMENT_RIGHT,
						],
					],
					'requires'    => [
						[ 'id' => self::SETTING_HEADER_IMAGE, 'value' => true ],
					],
				],
			];

			$sections[ $s ]['settings'] = array_merge( $section['settings'], $settings );
		}

		return $sections;
	}

	/**
	 * Adds the images to the header on every page.
	 * @since $ver$
	 *
	 * @param string[] $header The header HTML's.
	 * @param array    $form   The form object.
	 *
	 * @return array The updated header HTML's.
	 */
	private function add_header_image( array $header, array $form ): array {
		$form_id = (int) ( $form['id'] ?? 0 );
		if ( ! $this->is_header_enabled( $form_id ) ) {
			return $header;
		}

		$attachment_id = $this->get_attachment_id( $form_id );
		$image         = wp_get_attachment_image( $attachment_id, [ 300, 60 ] );

		if ( $image !== '' ) {
			$placement      = $this->get_placement( $form_id );
			$image          = sprintf( '<div class="header-image header-image--%s">%s</div>', $placement, $image );
			$header['even'] = $image . $header['even'];
			$header['odd']  = $image . $header['odd'];
		}

		return $header;
	}

	/**
	 * Whether the header image is enabled.
	 * @since  $ver$
	 *
	 * @filter `gk/gravityexport/pdf/header-image/enabled` Modify whether the header image is enabled.
	 *
	 * @param int $form_id The form id.
	 *
	 * @return bool Whether the header image is enabled.
	 */
	private function is_header_enabled( int $form_id ): bool {
		return (bool) gf_apply_filters( [
			'gk/gravityexport/pdf/header-image/enabled',
			$form_id,
		],
			(bool) $this->addon->get_plugin_setting( self::SETTING_HEADER_IMAGE ),
			$form_id
		);
	}

	/**
	 * Retrieve the attachment ID.
	 * @since  $ver$
	 *
	 * @param int $form_id The form ID.
	 *
	 * @filter `gk/gravityexport/pdf/header-image/attachment-id` Modify the attachment id.
	 * @return int The attachment ID.
	 */
	private function get_attachment_id( int $form_id ): int {
		return (int) gf_apply_filters( [
			'gk/gravityexport/pdf/header-image/attachment-id',
			$form_id,
		],
			(int) $this->addon->get_plugin_setting( self::SETTING_HEADER_IMAGE_MEDIA ),
			$form_id
		);
	}

	/**
	 * Retrieve the placement.
	 * @since  $ver$
	 *
	 * @param int $form_id The form ID.
	 *
	 * @filter `gk/gravityexport/pdf/header-image/placement` Modify the placement.
	 * @return string The placement.
	 */
	private function get_placement( int $form_id ): string {
		$setting = gf_apply_filters( [
			'gk/gravityexport/pdf/header-image/placement',
			$form_id,
		],
			$this->addon->get_plugin_setting( self::SETTING_HEADER_IMAGE_PLACEMENT ),
			$form_id
		);

		if ( ! in_array( $setting, [
			self::SETTING_HEADER_IMAGE_PLACEMENT_LEFT,
			self::SETTING_HEADER_IMAGE_PLACEMENT_CENTER,
			self::SETTING_HEADER_IMAGE_PLACEMENT_RIGHT,
		], true ) ) {
			$setting = self::SETTING_HEADER_IMAGE_PLACEMENT_LEFT;
		}

		return $setting;
	}
}
