<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class BingoCR_Email {

	/**
	 * Email strings per language.
	 *
	 * Customer emails follow the language the booking was made in
	 * ($reservation['language']); admin emails follow the widget language
	 * configured in Settings. Same self-contained EN/RO approach as the
	 * widget i18n — no .po/.mo files required.
	 */
	public static function strings( string $lang ): array {
		$strings = array(
			'en' => array(
				'subject_confirmation' => 'Your booking confirmation – %s',
				'subject_admin'        => 'New booking received – %s',
				'subject_confirmed'    => 'Your booking is confirmed – %s',
				'subject_cancelled'    => 'Your booking has been cancelled – %s',
				'dear'                 => 'Dear',
				'intro_received'       => 'Your car rental booking has been received. Here is a summary:',
				'confirmed_msg'        => 'Great news — your booking has been confirmed! Here are your booking details:',
				'cancelled_msg'        => 'Your booking has been cancelled. If you did not request this or have any questions, please contact us.',
				'reference'            => 'Reference:',
				'new_booking'          => 'New Booking Received',
				'booking_details'      => 'Booking Details',
				'customer'             => 'Customer',
				'email'                => 'Email',
				'phone'                => 'Phone',
				'vehicle'              => 'Vehicle',
				'pickup'               => 'Pickup',
				'return'               => 'Return',
				'pickup_location'      => 'Pickup Location',
				'dropoff_location'     => 'Drop-off Location',
				'status'               => 'Status',
				'payment'              => 'Payment',
				'pay_cash'             => 'Cash on pickup',
				'pay_card'             => 'Card on pickup',
				'pay_bank'             => 'Bank transfer',
				'pay_paypal'           => 'PayPal',
				'order_summary'        => 'Order Summary',
				'base_rental'          => 'Base rental (%d days)',
				'base_rental_one'      => 'Base rental (1 day)',
				'seasonal'             => 'Seasonal adjustment',
				'day'                  => 'day',
				'days'                 => 'days',
				'out_of_hours_fee'     => 'Out-of-hours fee',
				'discount'             => 'Discount',
				'total'                => 'Total',
				'deposit'              => 'Security deposit (refundable)',
				'notes'                => 'Notes:',
				'outro'                => 'We will contact you to confirm your booking. Thank you for choosing us!',
				'view_admin'           => 'View in Admin',
				'status_pending'       => 'Pending',
				'status_confirmed'     => 'Confirmed',
				'status_active'        => 'Active',
				'status_completed'     => 'Completed',
				'status_cancelled'     => 'Cancelled',
			),
			'ro' => array(
				'subject_confirmation' => 'Confirmarea rezervării tale – %s',
				'subject_admin'        => 'Rezervare nouă primită – %s',
				'subject_confirmed'    => 'Rezervarea ta este confirmată – %s',
				'subject_cancelled'    => 'Rezervarea ta a fost anulată – %s',
				'dear'                 => 'Dragă',
				'intro_received'       => 'Rezervarea ta auto a fost înregistrată. Iată un rezumat:',
				'confirmed_msg'        => 'Vești bune — rezervarea ta a fost confirmată! Iată detaliile rezervării:',
				'cancelled_msg'        => 'Rezervarea ta a fost anulată. Dacă nu ai solicitat această anulare sau ai întrebări, te rugăm să ne contactezi.',
				'reference'            => 'Referință:',
				'new_booking'          => 'Rezervare Nouă',
				'booking_details'      => 'Detalii Rezervare',
				'customer'             => 'Client',
				'email'                => 'Email',
				'phone'                => 'Telefon',
				'vehicle'              => 'Vehicul',
				'pickup'               => 'Preluare',
				'return'               => 'Returnare',
				'pickup_location'      => 'Locație preluare',
				'dropoff_location'     => 'Locație returnare',
				'status'               => 'Stare',
				'payment'              => 'Plată',
				'pay_cash'             => 'Numerar la preluare',
				'pay_card'             => 'Card la preluare',
				'pay_bank'             => 'Transfer bancar',
				'pay_paypal'           => 'PayPal',
				'order_summary'        => 'Rezumat Comandă',
				'base_rental'          => 'Chirie de bază (%d zile)',
				'base_rental_one'      => 'Chirie de bază (1 zi)',
				'seasonal'             => 'Ajustare sezonieră',
				'day'                  => 'zi',
				'days'                 => 'zile',
				'out_of_hours_fee'     => 'Taxă în afara programului',
				'discount'             => 'Reducere',
				'total'                => 'Total',
				'deposit'              => 'Garanție (returnabilă)',
				'notes'                => 'Observații:',
				'outro'                => 'Te vom contacta pentru confirmarea rezervării. Îți mulțumim că ne-ai ales!',
				'view_admin'           => 'Vezi în Admin',
				'status_pending'       => 'În așteptare',
				'status_confirmed'     => 'Confirmată',
				'status_active'        => 'Activă',
				'status_completed'     => 'Finalizată',
				'status_cancelled'     => 'Anulată',
			),
		);

		return $strings[ $lang ] ?? $strings['en'];
	}

	/** Translated status label with graceful fallback. */
	public static function status_label( string $status, array $l ): string {
		return $l[ 'status_' . $status ] ?? ucfirst( $status );
	}

	/** Translated payment-method label with graceful fallback. */
	public static function payment_label( string $method, array $l ): string {
		return $l[ 'pay_' . $method ] ?? ucfirst( $method );
	}

	public static function send_customer_confirmation( array $reservation ): void {
		$settings = BingoCR_DB::get_settings();
		$l        = self::strings( $reservation['language'] ?? 'en' );
		$to       = sanitize_email( $reservation['customer_email'] );
		$subject  = sprintf( $l['subject_confirmation'], $reservation['reservation_number'] );

		$body = self::get_template( 'customer-confirmation', array(
			'reservation' => $reservation,
			'settings'    => $settings,
			'l'           => $l,
		) );

		self::send( $to, $subject, $body, $settings );
	}

	public static function send_admin_notification( array $reservation ): void {
		$settings = BingoCR_DB::get_settings();
		$to       = sanitize_email( $settings['notify_email'] );
		if ( ! $to ) {
			return;
		}
		// Admin emails follow the site's configured widget language.
		$l       = self::strings( $settings['language'] ?? 'en' );
		$subject = sprintf( $l['subject_admin'], $reservation['reservation_number'] );

		$body = self::get_template( 'admin-notification', array(
			'reservation' => $reservation,
			'settings'    => $settings,
			'l'           => $l,
		) );

		self::send( $to, $subject, $body, $settings );
	}

	/**
	 * Customer notification when an admin changes the reservation status
	 * (confirmed / cancelled).
	 */
	public static function send_status_update( array $reservation ): void {
		$status = $reservation['status'] ?? '';
		if ( ! in_array( $status, array( 'confirmed', 'cancelled' ), true ) ) {
			return;
		}

		$settings = BingoCR_DB::get_settings();
		$l        = self::strings( $reservation['language'] ?? 'en' );
		$to       = sanitize_email( $reservation['customer_email'] );
		$subject  = sprintf(
			$status === 'confirmed' ? $l['subject_confirmed'] : $l['subject_cancelled'],
			$reservation['reservation_number']
		);

		$body = self::get_template( 'status-update', array(
			'reservation' => $reservation,
			'settings'    => $settings,
			'l'           => $l,
		) );

		self::send( $to, $subject, $body, $settings );
	}

	private static function send( string $to, string $subject, string $body, array $settings ): void {
		$headers = array(
			'Content-Type: text/html; charset=UTF-8',
			'From: ' . sanitize_text_field( $settings['from_name'] ) . ' <' . sanitize_email( $settings['from_email'] ) . '>',
		);

		wp_mail( $to, $subject, $body, $headers );
	}

	private static function get_template( string $name, array $vars = array() ): string {
		$file = BINGOCR_DIR . 'templates/email/' . $name . '.php';
		if ( ! file_exists( $file ) ) {
			return '';
		}
		extract( $vars, EXTR_SKIP ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
		ob_start();
		include $file;
		return ob_get_clean();
	}

	public static function format_price( float $amount, array $settings ): string {
		$symbol   = $settings['currency_symbol'] ?? '€';
		$position = $settings['currency_position'] ?? 'before';
		$formatted = number_format( $amount, 2 );
		return $position === 'before' ? $symbol . $formatted : $formatted . $symbol;
	}
}
