<?php

namespace EBCT\App\Controllers;

defined( 'ABSPATH' ) || exit;

use EDPW\Core\Helpers\EmailTemplate;
use EDPW\Core\Helpers\ShortCodes;
use EDPW\Core\Helpers\Util;
use EDPW\Core\Helpers\WC;
use WC_Booking;
use WC_Order;

class Booking {
	protected static $plugin_templates = [
		'new_booking',
		'booking_reminder',
		'booking_confirmed',
		'booking_pending_confirmation',
		'booking_notification',
		'booking_cancelled',
		'admin_booking_cancelled'
	];

	/**
	 * Add admin menu.
	 * @return void
	 */
	public static function addAdminMenu() {
		if ( WC::hasAdminPrivilege() ) {
			add_menu_page( EBCT_PLUGIN_NAME, EBCT_PLUGIN_NAME, 'manage_woocommerce', EBCT_PLUGIN_SLUG, [
				self::class,
				'displayMenuContent'
			], 'dashicons-megaphone', 57 );
		}
	}

	/**
	 * Hide add-on menu.
	 * @return void
	 */
	public static function hideMenu() {
		?>
        <style>
            #toplevel_page_ebct-booking-compatibility {
                display: none !important;
            }
        </style>
		<?php
	}

	/**
	 * Display menu content.
	 * @return void
	 */
	public static function displayMenuContent() {
		if ( ! WC::hasAdminPrivilege() ) {
			return;
		}
		wc_get_template( 'main.php', [], '', EBCT_PLUGIN_DIR . '/App/Views/Admin/' );
	}

	/**
	 * List booking short codes.
	 *
	 * @param array $short_codes Short codes.
	 * @param string $type Email type.
	 *
	 * @return array
	 */
	public static function addShortCodes( $short_codes, $type ) {

		if ( ! is_array( $short_codes ) ) {
			return $short_codes;
		}

		if ( ! in_array( $type, self::$plugin_templates ) ) {
			return $short_codes;
		}
		$short_codes['booking'] = [
			'label'       => __( 'Woocommerce Booking Shortcodes', 'email-editor-plus' ),
			'short_codes' => EmailTemplate::formatShortCode( self::getShortCodes( 'desc', 'booking.' ) )
		];

		return self::processShortCodeList( $type, $short_codes );
	}

	/**
	 * Add dummy data.
	 *
	 * @param array $short_codes short codes.
	 *
	 * @return array
	 */
	public static function addDummyData( $short_codes, $type ) {
		if ( ! is_array( $short_codes ) ) {
			return $short_codes;
		}
		if ( ! in_array( $type, self::$plugin_templates ) ) {
			return $short_codes;
		}
		$short_codes['booking'] = self::getShortCodes( 'default' );

		return $short_codes;
	}

	/**
	 * Get booking short codes.
	 * @return array
	 */
	public static function getShortCodes( $type = 'value', $pre_fix = '', $args = [] ) {
		$default = [
			'order'           => '',
			'booking'         => '',
			'email_arguments' => [],
		];
		$args    = wp_parse_args( $args, $default );
		extract( $args );
		$booking_edit_url = '';
		$booking_order    = '';
		if ( ! empty( $booking ) ) {
			$booking_id = WC::isMethodExists( $booking, 'get_id' ) ? $args['booking']->get_id() : 0;

			if ( $booking_id > 0 ) {
				$booking_edit_url = admin_url( 'post.php?post=' . $booking_id . '&action=edit' );
			}
			$booking_order = WC::isMethodExists( $booking, 'get_order' ) ? $booking->get_order() : 0;
		}
		$fields = apply_filters( EBCT_PLUGIN_PREFIX . '_booking_short_codes', [
			'resource'              => [
				'value'   => self::getBookingResources( $booking ),
				'desc'    => __( 'WooCommerce Booking Resources', 'email-editor-plus' ),
				'default' => ''
			],
			'details'               => [
				'value'   => self::getBookingDetailTable( $order, $args ),
				'desc'    => __( 'WooCommerce Booking Table', 'email-editor-plus' ),
				'default' => ''
			],
			'edit_url'              => [
				'value'   => $booking_edit_url,
				'desc'    => __( 'URL to edit booking order', 'email-editor-plus' ),
				'default' => ''
			],
			'requires_confirmation' => [
				'value'   => ! empty( $booking_order ) ? wc_booking_order_requires_confirmation( $booking_order ) : '',
				'desc'    => __( 'Does bookings need confirmation', 'email-editor-plus' ),
				'default' => ''
			],
			'status'                => [
				'value'   => WC::isMethodExists( $booking, 'get_status' ) ? $booking->get_status() : '',
				'desc'    => __( 'Status of the booking order', 'email-editor-plus' ),
				'default' => ''
			],
			'start_date'            => [
				'value'   => WC::isMethodExists( $booking, 'get_start_date' ) ? $booking->get_start_date() : '',
				'desc'    => __( 'Start date of the booking order', 'email-editor-plus' ),
				'default' => ''
			],
			'end_date'              => [
				'value'   => WC::isMethodExists( $booking, 'get_end_date' ) ? $booking->get_end_date() : '',
				'desc'    => __( 'End date of the booking order', 'email-editor-plus' ),
				'default' => ''
			],
			'notification_message'  => [
				'value'   => isset( $email_arguments['notification_message'] ) ? wptexturize( $email_arguments['notification_message'] ) : '',
				'desc'    => __( 'Notification of the booking order', 'email-editor-plus' ),
				'default' => ''
			],
		], $type );

		return ShortCodes::getFieldData( $fields, $type, $pre_fix );
	}

	/**
	 * Processes a list of short codes based on the specified type.
	 *
	 * @param string $type The type of short codes to process.
	 * @param array $short_codes An array of short codes to process.
	 *
	 * @return array
	 */
	public static function processShortCodeList( $type, $short_codes ) {
		if ( ! is_string( $type ) || ! is_array( $short_codes ) ) {
			return $short_codes;
		}
		switch ( $type ) {
			case 'new_booking':
				$ignore_short_codes = [
					'order'    => [
						'short_codes' => [ '{{order.last_note}}', '{{order.notes}}' ]
					],
					'customer' => [
						'short_codes' => [
							'{{customer.password}}',
							'{{customer.activation_url}}',
							'{{customer.set_password_url}}',
							'{{customer.password_reset_url}}'
						]
					],
					'booking'  => [
						'short_codes' => [ '{{booking.resource}}', '{{booking.notification_message}}' ]
					]
				];
				$short_codes        = ShortCodes::removeIgnoreShortCodes( $short_codes, $ignore_short_codes );
				break;
			case 'booking_reminder':
			case 'booking_confirmed':
			case 'booking_pending_confirmation':
			case 'booking_cancelled':
			case 'admin_booking_cancelled':
				$ignore_short_codes = [
					'order'    => [
						'short_codes' => [ '{{order.last_note}}', '{{order.notes}}' ]
					],
					'customer' => [
						'short_codes' => [
							'{{customer.password}}',
							'{{customer.activation_url}}',
							'{{customer.set_password_url}}',
							'{{customer.password_reset_url}}'
						]
					],
					'booking'  => [
						'short_codes' => [ '{{booking.notification_message}}' ]
					]
				];
				$short_codes        = ShortCodes::removeIgnoreShortCodes( $short_codes, $ignore_short_codes );
				break;
			case 'booking_notification':
				$ignore_short_codes = [
					'order'    => [
						'short_codes' => [ '{{order.last_note}}', '{{order.notes}}' ]
					],
					'customer' => [
						'short_codes' => [
							'{{customer.password}}',
							'{{customer.activation_url}}',
							'{{customer.set_password_url}}',
							'{{customer.password_reset_url}}'
						]
					]
				];
				$short_codes        = ShortCodes::removeIgnoreShortCodes( $short_codes, $ignore_short_codes );
				break;
		}

		return $short_codes;
	}

	/**
	 * Add booking short codes.
	 *
	 * @param array $short_codes Short code list.
	 * @param WC_Order $order Order object.
	 * @param array $args Arguments.
	 * @param bool $sample Is sample data.
	 *
	 * @return array
	 */
	public static function getTemplateShortCodes( $short_codes, $order, $args, $sample ) {
		if ( ! is_array( $short_codes ) ) {
			return $short_codes;
		}
		if ( $sample ) {
			if ( is_a( $order, '\WC_Order' ) ) {
				$order_id     = WC::getOrderId( $order );
				$booking_post = get_children( [
					'numberposts' => 1,
					'post_type'   => 'wc_booking',
					'post_status' => 'any',
					'post_parent' => $order_id,
				] );
				$booking_post = reset( $booking_post );

				if ( ! empty( $booking_post ) ) {
					$booking_id      = $booking_post->ID;
					$args['booking'] = get_wc_booking( $booking_id );
				}
			}
		}
		if ( empty( $args['booking'] ) ) {
			return $short_codes;
		}
		$short_codes['booking'] = $sample && empty( $order ) ? self::getShortCodes( 'default' ) : self::getShortCodes( 'value', '', [
			'order'           => $order,
			'booking'         => $args['booking'],
			'email_arguments' => $args
		] );

		return apply_filters( EBCT_PLUGIN_PREFIX . '_woocommerce_bookings_additional_short_codes', $short_codes, $order, $args, $sample );
	}

	/**
	 * Get booking resource.
	 *
	 * @param WC_Booking $booking booking object.
	 *
	 * @return string
	 */
	protected static function getBookingResources( $booking ) {
		if ( ! is_object( $booking ) ) {
			return '';
		}
		$resource = '';
		if ( WC::isMethodExists( $booking, 'has_resources' ) && $booking->has_resources() ) {
			$resource = WC::isMethodExists( $booking, 'get_resource' ) ? $booking->get_resource() : '';
		}

		return esc_html( $resource );
	}

	/**
	 * Get booking detail table.
	 *
	 * @param WC_Order $order Order object.
	 * @param array $args Arguments.
	 *
	 * @return string
	 */
	protected static function getBookingDetailTable( $order, $args ) {
		if ( ! is_object( $order ) ) {
			return '';
		}
		$template_path          = EBCT_PLUGIN_PATH . 'App/Views/Site/booking_details.php';
		$override_template_path = get_theme_file_path( EDPW_PLUGIN_SLUG . '/templates/booking_details.php' );
		if ( file_exists( $override_template_path ) ) {
			$template_path = $override_template_path;
		}
		$content = Util::renderTemplate( $template_path, $args );
		$css     = EmailTemplate::getSetting( 'custom_css', EmailTemplate::getDefaultCustomCss() );

		return apply_filters( EBCT_PLUGIN_PREFIX . '_woocommerce_bookings_details_table', WC::styleInline( $content, $css ), $order, $args );
	}

	/**
	 * Add booking template images.
	 *
	 * @param array $templates Template lists.
	 * @param string $name Template group name.
	 * @param string $type Template type.
	 *
	 * @return array
	 */
	public static function addTemplateImage( $templates, $name, $type ) {
		$booking_templates = self::getAllTemplateImages();
		foreach ( $templates as $template_name => $template ) {
			$template_images = $booking_templates[ $template_name ];
			if ( ! empty( $template_images ) ) {
				$templates[ $template_name ] = array_merge( $template, $template_images );
			}
		}

		return $templates;
	}

	/**
	 * Retrieves the list of booking preview images for the specified template group.
	 *
	 * @param string $template_group The template group to retrieve booking preview images for. Defaults to 'default'.
	 *
	 * @return array
	 */
	protected static function getBookingPreviewImageList( string $template_group = 'default' ) {
		if ( empty( $template_group ) ) {
			return [];
		}

		return [
			'new_booking'                  => EmailTemplate::getPreviewImageUrl( 'new-booking', $template_group ),
			'booking_reminder'             => EmailTemplate::getPreviewImageUrl( 'booking-reminder', $template_group ),
			'booking_confirmed'            => EmailTemplate::getPreviewImageUrl( 'booking-confirmed', $template_group ),
			'booking_pending_confirmation' => EmailTemplate::getPreviewImageUrl( 'booking-pending-confirmation', $template_group ),
			'booking_notification'         => EmailTemplate::getPreviewImageUrl( 'booking-notification', $template_group ),
			'booking_cancelled'            => EmailTemplate::getPreviewImageUrl( 'booking-cancelled', $template_group ),
			'admin_booking_cancelled'      => EmailTemplate::getPreviewImageUrl( 'admin-booking-cancelled', $template_group ),
		];
	}

	/**
	 * Get booking template list.
	 * @return array
	 */
	public static function getAllTemplateImages() {
		return apply_filters( EBCT_PLUGIN_PREFIX . '_bookings_template_images', [
			'default' => self::getBookingPreviewImageList(),
			'caramel' => self::getBookingPreviewImageList( 'caramel' ),
			'peanut'  => self::getBookingPreviewImageList( 'peanut' ),
			'biscuit' => self::getBookingPreviewImageList( 'biscuit' ),
			'mint'    => self::getBookingPreviewImageList( 'mint' )
		] );
	}

	/**
	 * Determines if the provided template is valid within the specified template group.
	 *
	 * @param string $template_group The template group to check against.
	 * @param string $template The template to validate.
	 *
	 * @return bool
	 */
	public static function isValidTemplate( $template_group, $template ) {
		$templates = self::getAllTemplateImages();

		return isset( $templates[ $template_group ] ) && array_key_exists( $template, $templates[ $template_group ] );
	}

	/**
	 * Add template path based on provided arguments.
	 *
	 * @param string $file_path File path to be checked for template.
	 * @param array $args Array containing template group and template name.
	 *                    Requires 'template_group' and 'template_name' keys to be present.
	 *
	 * @return string
	 */
	public static function addTemplatePath( $file_path, $args ) {
		if ( ! is_array( $args ) || empty( $args['template_group'] ) || empty( $args['template_name'] ) || ! self::isValidTemplate( $args['template_group'], $args['template_name'] ) ) {
			return $file_path;
		}
		$booking_file_path = EBCT_PLUGIN_PATH . 'App/Views/Templates/' . $args['template_name'] . '/' . $args['template_group'] . '.html';
		if ( file_exists( $booking_file_path ) ) {
			return $booking_file_path;
		}

		return $file_path;
	}

	/**
	 * Get tag details.
	 *
	 * @param string $template_plugin The template plugin.
	 * @param string $template The template.
	 *
	 * @return array
	 */
	public static function getTagDetails( $template_plugin, $template ) {
		if ( empty( $template ) || ! in_array( $template, self::$plugin_templates ) ) {
			return $template_plugin;
		}

		return [
			'group' => 'woocommerce_booking',
			'name'  => __( 'WooCommerce Bookings', 'email-editor-plus' ),
			'style' => 'color:#ffffff;backgroundColor:#9e39b8'
		];
	}

	/**
	 * Add a group to the existing groups array.
	 *
	 * @param array $groups The array of groups to which a new group will be added.
	 *
	 * @return array The updated array of groups with the new group added.
	 */
	public static function addToGroups( $groups ) {
		if ( ! is_array( $groups ) ) {
			return $groups;
		}
		$groups[] = [
			'label' => esc_html__( 'WooCommerce Bookings', 'email-editor-plus' ),
			'value' => 'woocommerce_booking'
		];

		return $groups;
	}
}