<?php
/**
 * Staff notification and frontend access rules.
 *
 * @package Vachr Short-Term Rental Reservations
 * @license GPLv2 or later
 */

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

class VSTRB_Staff_Access {
	public static function allowed_fields() {
		return [
			'unit',
			'dates',
			'guests',
			'status',
			'source',
			'customer',
			'contact',
			'price',
			'note',
			'booking_reference',
			'guest_names',
		];
	}

	public static function default_fields() {
		return ['unit', 'dates', 'guests'];
	}

	public static function allowed_events() {
		return [
			'new_booking',
			'registration',
			'arrival',
			'departure',
			'ical_cancelled',
		];
	}

	public static function default_events() {
		return ['new_booking', 'registration', 'departure'];
	}

	public static function field_labels() {
		return [
			'unit' => __('Apartment', 'vachr-short-term-rental-reservations'),
			'dates' => __('Dates', 'vachr-short-term-rental-reservations'),
			'guests' => __('Guests', 'vachr-short-term-rental-reservations'),
			'status' => __('Status', 'vachr-short-term-rental-reservations'),
			'source' => __('Booking Source', 'vachr-short-term-rental-reservations'),
			'customer' => __('Customer', 'vachr-short-term-rental-reservations'),
			'contact' => __('Contact', 'vachr-short-term-rental-reservations'),
			'price' => __('Price', 'vachr-short-term-rental-reservations'),
			'note' => __('Note', 'vachr-short-term-rental-reservations'),
			'booking_reference' => __('Booking Reference', 'vachr-short-term-rental-reservations'),
			'guest_names' => __('Guest Names', 'vachr-short-term-rental-reservations'),
		];
	}

	private static function safe_text($value) {
		if (is_array($value) || is_object($value)) {
			return '';
		}
		return sanitize_text_field((string) $value);
	}

	private static function normalize_email($email) {
		$email = sanitize_email((string) $email);
		return is_email($email) ? strtolower($email) : '';
	}

	private static function normalize_locale($locale) {
		$locale = trim((string) $locale);
		if ($locale === '') {
			return '';
		}
		$locale = str_replace('-', '_', $locale);
		return preg_match('/^[A-Za-z]{2}(?:_[A-Za-z]{2})?$/', $locale) ? $locale : '';
	}

	private static function normalize_days_before($days) {
		if ($days === '' || $days === null) {
			return 1;
		}
		$days = trim((string) $days);
		if (!preg_match('/^\d+$/', $days)) {
			return 1;
		}
		return max(0, min(365, (int) $days));
	}

	private static function normalize_fields($fields) {
		$allowed = self::allowed_fields();
		$out = [];
		foreach ((array) $fields as $field) {
			$field = strtolower(trim((string) $field));
			if ($field === 'all') {
				return $allowed;
			}
			if (in_array($field, $allowed, true) && !in_array($field, $out, true)) {
				$out[] = $field;
			}
		}
		return $out ?: self::default_fields();
	}

	private static function normalize_events($events) {
		$allowed = self::allowed_events();
		$out = [];
		foreach ((array) $events as $event) {
			$event = strtolower(trim((string) $event));
			if ($event === 'all') {
				return $allowed;
			}
			if ($event === 'booking') {
				$event = 'new_booking';
			}
			if ($event === 'guest_registration') {
				$event = 'registration';
			}
			if (in_array($event, $allowed, true) && !in_array($event, $out, true)) {
				$out[] = $event;
			}
		}
		return $out ?: self::default_events();
	}

	public static function sanitize_rules_text($raw) {
		$rules = self::parse_rules_text((string) $raw);
		$lines = [];
		foreach ($rules as $rule) {
			$line = $rule['email'] . '|' . implode(',', $rule['fields']) . '|' . implode(',', $rule['events']);
			$days_before = self::days_before($rule);
			if (!empty($rule['locale']) || $days_before !== 1) {
				$line .= '|' . $rule['locale'];
			}
			if (!empty($rule['locale']) || $days_before !== 1) {
				$line .= '|' . $days_before;
			}
			$lines[] = $line;
		}
		return implode("\n", $lines);
	}

	public static function parse_rules_text($raw) {
		$rules = [];
		$lines = preg_split('/\R+/', (string) $raw);
		foreach ((array) $lines as $line) {
			$line = trim((string) $line);
			if ($line === '') {
				continue;
			}
			$parts = explode('|', $line);
			$email = self::normalize_email($parts[0] ?? '');
			if ($email === '') {
				continue;
			}
			$field_text = (string) ($parts[1] ?? '');
			$event_text = (string) ($parts[2] ?? '');
			$locale = self::normalize_locale($parts[3] ?? '');
			$days_text = $parts[4] ?? '';
			if ($locale === '' && isset($parts[3]) && preg_match('/^\d+$/', trim((string) $parts[3]))) {
				$days_text = $parts[3];
			}
			$field_parts = preg_split('/[\s,;]+/', $field_text);
			$event_parts = preg_split('/[\s,;]+/', $event_text);
			$rules[$email] = [
				'email' => $email,
				'fields' => self::normalize_fields($field_parts),
				'events' => self::normalize_events($event_parts),
				'locale' => $locale,
				'days_before' => self::normalize_days_before($days_text),
			];
		}
		return array_values($rules);
	}

	public static function get_rules() {
		if (class_exists('VSTRB_Staff_Tasks') && is_array(get_option(VSTRB_Staff_Tasks::OPTION, null))) {
			return VSTRB_Staff_Tasks::flattened_rules();
		}
		$rules = self::parse_rules_text((string) get_option('vstrb_staff_notification_rules', ''));
		if (!empty($rules)) {
			return $rules;
		}

		$legacy = (string) get_option('vstrb_staff_notification_emails', '');
		$emails = preg_split('/[\s,;]+/', $legacy);
		$out = [];
		foreach ((array) $emails as $email) {
			$email = self::normalize_email($email);
			if ($email !== '') {
				$out[$email] = [
					'email' => $email,
					'fields' => self::default_fields(),
					'events' => self::default_events(),
					'locale' => '',
					'days_before' => 1,
				];
			}
		}
		return array_values($out);
	}

	public static function get_rules_text() {
		$text = (string) get_option('vstrb_staff_notification_rules', '');
		if (trim($text) !== '') {
			return self::sanitize_rules_text($text);
		}
		$lines = [];
		foreach (self::get_rules() as $rule) {
			$line = $rule['email'] . '|' . implode(',', $rule['fields']) . '|' . implode(',', $rule['events']);
			$days_before = self::days_before($rule);
			if (!empty($rule['locale']) || $days_before !== 1) {
				$line .= '|' . $rule['locale'];
			}
			if (!empty($rule['locale']) || $days_before !== 1) {
				$line .= '|' . $days_before;
			}
			$lines[] = $line;
		}
		return implode("\n", $lines);
	}

	public static function get_rule($email) {
		$email = self::normalize_email($email);
		if ($email === '') {
			return null;
		}
		foreach (self::get_rules() as $rule) {
			if ($rule['email'] === $email) {
				return $rule;
			}
		}
		return null;
	}

	public static function can($rule, $field) {
		return is_array($rule) && in_array((string) $field, (array) ($rule['fields'] ?? []), true);
	}

	public static function wants_event($rule, $event) {
		return is_array($rule) && in_array((string) $event, (array) ($rule['events'] ?? self::default_events()), true);
	}

	public static function locale($rule) {
		return is_array($rule) ? self::normalize_locale($rule['locale'] ?? '') : '';
	}

	public static function days_before($rule) {
		return is_array($rule) ? self::normalize_days_before($rule['days_before'] ?? 1) : 1;
	}

	public static function booking_lines($booking, $rule) {
		if (!$booking || !is_array($rule)) {
			return [];
		}
		$lines = [];
		$unit_title = get_the_title((int) ($booking->unit_id ?? 0));
		if (self::can($rule, 'unit')) {
			$lines[__('Apartment', 'vachr-short-term-rental-reservations')] = $unit_title;
		}
		if (self::can($rule, 'dates')) {
			$lines[__('Dates', 'vachr-short-term-rental-reservations')] = self::safe_text($booking->date_from ?? '') . ' to ' . self::safe_text($booking->date_to ?? '');
		}
		if (self::can($rule, 'guests')) {
			$lines[__('Guests', 'vachr-short-term-rental-reservations')] = (string) max(1, (int) ($booking->guests ?? 1));
		}
		if (self::can($rule, 'status')) {
			$lines[__('Status', 'vachr-short-term-rental-reservations')] = self::safe_text($booking->status ?? '');
		}
		if (self::can($rule, 'source')) {
			$lines[__('Booking Source', 'vachr-short-term-rental-reservations')] = self::safe_text($booking->source ?? '');
		}
		if (self::can($rule, 'customer')) {
			$lines[__('Customer', 'vachr-short-term-rental-reservations')] = trim(self::safe_text($booking->customer_name ?? '') . ' ' . self::safe_text($booking->customer_lastname ?? ''));
		}
		if (self::can($rule, 'contact')) {
			$contact = trim(self::safe_text($booking->customer_email ?? '') . ' ' . self::safe_text($booking->customer_phone ?? ''));
			$lines[__('Contact', 'vachr-short-term-rental-reservations')] = $contact;
		}
		if (self::can($rule, 'price')) {
			$lines[__('Price', 'vachr-short-term-rental-reservations')] = trim(self::safe_text($booking->total_price ?? '') . ' ' . self::safe_text($booking->currency ?? ''));
		}
		if (self::can($rule, 'note')) {
			$lines[__('Note', 'vachr-short-term-rental-reservations')] = self::safe_text($booking->note ?? '');
		}
		return array_filter($lines, static function($value) {
			return trim((string) $value) !== '';
		});
	}

	public static function registration_group_lines($unit_id, $guest_count, $date_from, $date_to, $email, $source = '', $booking_reference = '', $guest_names = [], $rule = null) {
		if (!is_array($rule)) {
			return [];
		}
		$lines = [];
		if (self::can($rule, 'unit')) {
			$lines[__('Apartment', 'vachr-short-term-rental-reservations')] = get_the_title((int) $unit_id);
		}
		if (self::can($rule, 'dates')) {
			$lines[__('Stay', 'vachr-short-term-rental-reservations')] = self::safe_text($date_from) . ' to ' . self::safe_text($date_to);
		}
		if (self::can($rule, 'guests')) {
			$lines[__('Guests', 'vachr-short-term-rental-reservations')] = (string) max(1, (int) $guest_count);
		}
		if (self::can($rule, 'source')) {
			$lines[__('Booking Source', 'vachr-short-term-rental-reservations')] = self::safe_text($source);
		}
		if (self::can($rule, 'booking_reference')) {
			$lines[__('Booking Reference', 'vachr-short-term-rental-reservations')] = self::safe_text($booking_reference);
		}
		if (self::can($rule, 'contact')) {
			$lines[__('Contact', 'vachr-short-term-rental-reservations')] = self::safe_text($email);
		}
		if (self::can($rule, 'guest_names')) {
			$clean_names = [];
			foreach ((array) $guest_names as $guest_name) {
				$guest_name = self::safe_text($guest_name);
				if ($guest_name !== '') {
					$clean_names[] = $guest_name;
				}
			}
			$lines[__('Guest Names', 'vachr-short-term-rental-reservations')] = implode(', ', $clean_names);
		}
		return array_filter($lines, static function($value) {
			return trim((string) $value) !== '';
		});
	}
}
