<?php

namespace Bookingor\Backend\Controller\Staff;

use stdClass;
use Bookingor\BK_NGTR_Zoom_Controller;
use Bookingor\Integrations\Email\EmailNotification;

/**
 * Class managing staff-related operations such as deletion, update, addition, and data retrieval.
 *
 * @var string $dp_prefix Database table prefix for booking-related tables.
 * @var bool $staff_view Flag to indicate whether the staff view is enabled or disabled.
 * @var array|null $staff_data Stores data related to staff members.
 * @var array|null $staff_data_sp_day Stores data related to staff availability on a specific day.
 * @var array|null $staff_data_leave Stores data related to staff leave.
 * @var array|null $staff_assign Stores data related to staff assignments.
 * @var array|null $staff_location Stores data related to staff locations.
 * @var array|null $staff_add_location Stores data related to staff add locations.
 * 
 * 
 */


class StaffControl
{

	private static $bookingorDb;
	/**
	 * Database table prefix for booking-related tables.
	 *
	 * @var string
	 */
	public static $dp_prefix = "bookingor_";
	/**
	 * Flag to indicate whether the staff view is enabled or disabled.
	 *
	 * @var bool
	 */
	public static $staff_view;
	/**
	 * Stores data related to staff members.
	 *
	 * @var array|null
	 */
	public static $staff_data;
	/**
	 * Stores data related to staff availability on a specific day.
	 *
	 * @var array|null
	 */
	public static $staff_data_sp_day;
	/**
	 * Stores data related to staff leave.
	 *
	 * @var array|null
	 */
	public static $staff_data_leave;
	/**
	 * Stores data related to staff assignments.
	 *
	 * @var array|null
	 */
	public static $staff_assign;
	/**
	 * Stores data related to staff locations.
	 *
	 * @var array|null
	 */
	public static $staff_location;
	/**
	 * Stores data related to staff add locations.
	 *
	 * @var array|null
	 */
	public static $staff_add_location;
	/**
	 * Deletes a staff member from the database.
	 *
	 * @return void
	 */
	public function bp_delete_staff()
	{
		global $wpdb;
		$add_staff = $wpdb->prefix . self::$dp_prefix . 'staff_add';
		$assign_staff_service = $wpdb->prefix . self::$dp_prefix . 'staff_assign_service';

		self::$bookingorDb = $wpdb;
		$staff_id = sanitize_text_field(wp_unslash($_REQUEST["id"] ?? ""));
		if (isset($_POST['nonce'])) {
			if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'bookingor_ajax_nonce')) {
				$response = [
					'status' => htmlspecialchars('error'),
					'message' => htmlspecialchars('Nonce verification failed.')
				];
			}
		}

		$get_staff_email = self::$bookingorDb->get_results($wpdb->prepare("SELECT staff_email FROM %1\$s WHERE staff_id = %d", $add_staff, $staff_id));

		$user = get_user_by('email', $get_staff_email->staff_email);
		if ($user && in_array('bookingor_staff', $user->roles)) {
			wp_delete_user($user->ID);
		}

		self::$bookingorDb->delete($add_staff, array(
			'staff_id' => $staff_id
		));
		self::$bookingorDb->delete($assign_staff_service, array(
			'staff_get_id' => $staff_id
		));
	}
	/**
	 * Updates staff information in the database based on the provided data.
	 *
	 * Retrieves staff details from the form submission and updates the staff record in the database.
	 * Handles staff creation if a new user is being added.
	 * Manages staff special days, holidays, assigned services, and assigned locations.
	 *
	 * @return void
	 */
	/**
	 * Adds a new staff member to the database based on the provided data.
	 * Handles staff creation, including user creation if necessary, and manages staff details, special days, holidays, assigned services, and locations.
	 *
	 * @return void
	 */
	public function bp_staff_update()
	{
		global $wpdb;
		$add_staff = $wpdb->prefix . self::$dp_prefix . 'staff_add';
		$assign_staff_service = $wpdb->prefix . self::$dp_prefix . 'staff_assign_service';
		$staff_location_assign = $wpdb->prefix . self::$dp_prefix . 'location_assign_staff';

		self::$bookingorDb = $wpdb;
		$staff_get_id = isset($_REQUEST['get_staff_id']) ? intval($_REQUEST['get_staff_id']) : 0;
		if (isset($_POST['nonce'])) {
			if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'bookingor_ajax_nonce')) {
				$response = [
					'status' => htmlspecialchars('error'),
					'message' => htmlspecialchars('Nonce verification failed.')
				];
			}
		}
		if (isset($_REQUEST['action'])) {
			$staff_first_name = sanitize_text_field(wp_unslash($_POST['staff_first_name'] ?? ''));
			$staff_last_name = sanitize_text_field(wp_unslash($_POST['staff_last_name'] ?? ''));
			$staff_phone = sanitize_text_field(wp_unslash($_POST['staff_phone'] ?? ''));
			$staff_email = sanitize_text_field(wp_unslash($_POST['staff_email'] ?? ''));
			$staff_location = sanitize_text_field(wp_unslash($_POST['staff_location'] ?? ''));
			$staff_image = sanitize_text_field(wp_unslash($_POST['staff_image'] ?? ''));
			$status = sanitize_text_field(wp_unslash($_POST['status'] ?? ''));
			$staff_password = sanitize_text_field(wp_unslash($_POST['staff_wp_password'] ?? ''));
			$staff_assign_service = sanitize_text_field(wp_unslash($_POST['staff_assign'] ?? ''));
			$staff_tag_line = sanitize_text_field(wp_unslash($_POST['staff_tag_line'] ?? ''));
			$staff_about = sanitize_text_field(wp_unslash($_POST['bookingor_staff_about'] ?? ''));
			$staff_new_user = sanitize_text_field(wp_unslash($_POST['bp_new_user_create'] ?? ''));

			$staff_zoom_id = sanitize_text_field(wp_unslash($_POST['staff_zoom_id'] ?? ''));
			$staff_weekly_schedule = str_replace('\\', '', sanitize_text_field(wp_unslash($_POST['staff_work_day'])));
			if ($staff_new_user === 'on') {
				$staff_password = wp_generate_password(6, true);
				$user_id = wp_insert_user(
					array(
						'user_login' => $staff_first_name,
						'user_pass' => $staff_password,
						'user_email' => $staff_email,
						'first_name' => $staff_first_name,
						'last_name' => $staff_last_name,
						'role' => 'Bkinz Staff',
						'user_status' => '1',
						'user_registered' => current_time('mysql'),
						'user_activation_key' => wp_generate_password(20, true),
					)
				);
			}
			self::$bookingorDb->update(
				$add_staff,
				array(
					'staff_first_name' => $staff_first_name,
					'staff_last_name' => $staff_last_name,
					'staff_email' => $staff_email,
					'staff_phone' => $staff_phone,
					'staff_tag_line' => $staff_tag_line,
					'staff_about' => $staff_about,
					'staff_location' => $staff_location,
					'staff_icon' => $staff_image,
					'zoom_user_id' => $staff_zoom_id,
					'status' => $status,
					'staff_sheet_weekly' => $staff_weekly_schedule
				),
				array('staff_id' => $staff_get_id)
			);
			$id = $wpdb->insert_id;

			//================================


			self::$bookingorDb->delete($assign_staff_service, array(
				'staff_get_id' => $staff_get_id,
			));

			// =========================================


			/* ============================================================
			  Update assign services on header
			============================================ */

			$assign_services_in_staff = map_deep(wp_unslash($_POST['assign_services_in_staff'] ?? ''), 'sanitize_text_field');

			if (!empty($assign_services_in_staff)) {
				self::$bookingorDb->delete($assign_staff_service, array(
					'staff_get_id' => $staff_get_id,
				));
				foreach ($assign_services_in_staff as $key => $value) {
					if (isset($_POST['staff_service_get_id'])) {
						self::$bookingorDb->update(
							$assign_staff_service,
							array(
								'staff_get_id' => $staff_get_id,
								'service_get_id' => $value['staff_service_get_id'],
							),
							array('staff_get_id' => $staff_get_id,)
						);
					}
					if (empty($assign_services_in_staff)) {
						self::$bookingorDb->delete($assign_staff_service, array(
							'staff_get_id' => $staff_get_id,
						));
					} else {
						self::$bookingorDb->insert(
							$assign_staff_service,
							array(
								'staff_get_id' => $staff_get_id,
								'service_get_id' => $value['staff_service_get_id'],
							)
						);
					}
				}
			} else {
				self::$bookingorDb->delete($assign_staff_service, array(
					'staff_get_id' => $staff_get_id,
				));
				$assign_services_in_staff = null;
			}
			/* ============================================================
			 /* ============================================================
			location update
			============================================ */

			$staff_location = map_deep(wp_unslash($_POST['service_assign_location_updated'] ?? ''), 'sanitize_text_field');
			if (!empty($staff_location)) {
				self::$bookingorDb->delete($staff_location_assign, array(
					'staff_get_id' => $staff_get_id
				));
				foreach ($staff_location as $key => $value) {
					if (isset($_POST['service_location_get_id'])) {
						self::$bookingorDb->update(
							$staff_location_assign,
							array(
								'staff_get_id' => $staff_get_id,
								'location_get_id' => $value['service_location_get_id'],
							),
							array("staff_get_id", $staff_get_id)
						);
					}
					if (empty($_POST['service_assign_location_updated'])) {
						self::$bookingorDb->delete($staff_location, array(
							'staff_get_id' => $staff_get_id
						));
					} else {
						self::$bookingorDb->insert(
							$staff_location_assign,
							array(
								'staff_get_id' => $staff_get_id,
								'location_get_id' => $value['service_location_get_id'],
							),
						);
					}
				}
			} else {
				self::$bookingorDb->delete($staff_location_assign, array(
					'staff_get_id' => $staff_get_id
				));
				$_POST['service_location_get_id'] = null;
			}
			// ========================= location update end ==============================
			$get_staff_name = get_option('bookingor_settings_staff_name');
			$response = [
				'status' => htmlspecialchars('success'),
				'message' => $get_staff_name . htmlspecialchars(' Updated Successfully')
			];
			echo wp_json_encode($response);
			exit;
		}
	}
	/**
	 * Adds a new staff member to the database based on the provided data.
	 * Handles staff creation, including user creation if necessary, and manages staff details, special days, holidays, assigned services, and locations.
	 *
	 * @return void
	 */
	public function bp_add_staff()
	{
		global $wpdb;
		self::$bookingorDb = $wpdb;
		$add_staff = $wpdb->prefix . self::$dp_prefix . 'staff_add';
		$assign_staff_service = $wpdb->prefix . self::$dp_prefix . 'staff_assign_service';
		$staff_location_assign = $wpdb->prefix . self::$dp_prefix . 'location_assign_staff';
		$add_wordpress_users = $wpdb->prefix . 'users';
		if (isset($_REQUEST['action'])) {
			if (isset($_POST['nonce'])) {
				if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'bookingor_ajax_nonce')) {
					$response = [
						'status' => htmlspecialchars('error'),
						'message' => htmlspecialchars('Nonce verification failed.')
					];
				}
			}
			if (!current_user_can('manage_options')) {
				$response = [
					'status' => htmlspecialchars('error'),
					'message' => htmlspecialchars('You do not have permission.')
				];
				echo wp_json_encode($response);
				die();
			}
			$staff_first_name = sanitize_text_field(wp_unslash($_POST['staff_first_name'] ?? ""));
			$staff_last_name = sanitize_text_field(wp_unslash($_POST['staff_last_name'] ?? ""));
			$staff_phone = sanitize_text_field(wp_unslash($_POST['staff_phone'] ?? ""));
			$staff_email = sanitize_text_field(wp_unslash($_POST['staff_email'] ?? ""));
			$staff_image = sanitize_text_field(wp_unslash($_POST['staff_image'] ?? ""));
			$status = sanitize_text_field(wp_unslash($_POST['status'] ?? ""));
			$staff_password = sanitize_text_field(wp_unslash($_POST['staff_wp_password'] ?? ""));
			$role = "staff";
			$staff_tag_line = sanitize_text_field(wp_unslash($_POST['staff_tag_line'] ?? ""));
			$staff_about = sanitize_text_field(wp_unslash($_POST['bookingor_staff_about'] ?? ""));

			// Check staff limit for free version
			$staff = self::bp_view_staff();
			$staff_count = is_array($staff) ? count($staff) : (is_object($staff) ? count((array)$staff) : 0);
			$is_pro = class_exists('Bookingor\Backend\Controller\LocationTimeSheet\LocationTimeSheetControl');
			
			if ($staff_count >= 2 && !$is_pro) {
				$response = [
					'status' => 'error',
					'message' => __('The free version allows only 2 staff members. Upgrade to our Pro plan to add unlimited staff members.', 'bookingor')
				];
				echo wp_json_encode($response);
				exit;
			}

			update_option("bookingor_settings_staff_active", "on");
			$staff_new_user = isset($_POST['bp_new_user_create']) ? $_POST['bp_new_user_create'] : '';

			$staff_weekly_schedule = str_replace('\\', '', sanitize_text_field(wp_unslash($_POST['staff_work_day'])));

			if ($staff_new_user === 'on') {
				$staff_password = wp_generate_password(12, true);
				$user_id = wp_insert_user(
					array(
						'user_login' => $staff_first_name,
						'user_pass' => $staff_password,
						'user_email' => $staff_email,
						'first_name' => $staff_first_name,
						'display_name' => $staff_first_name . ' ' . $staff_last_name,
						'last_name' => $staff_last_name,
						'role' => 'bookingor_staff',
						'user_status' => 1,
						'user_registered' => current_time('mysql'),
						'user_activation_key' => wp_generate_password(20, true)
					)
				);
				if (is_wp_error($user_id)) {
					$response = [
						'status' => 'error',
						'message' => $user_id->get_error_message()
					];
					echo wp_json_encode($response);
					exit;
				}

				if (!is_wp_error($user_id && $user_id > 0)) {
					// User created successfully
					// Add additional user meta as needed
					add_user_meta($user_id, 'first_name', $staff_first_name);
					add_user_meta($user_id, 'last_name', $staff_last_name);
				}
				// send email to staff member
				$to = $staff_email;
				$subject = esc_html__('Your Account has been created', 'bookingor');
				$message = sprintf(
					__('Hello %1$s %2$s,<br><br>Your account has been created successfully. Here are your login details:<br><br>Email: %3$s<br>Password: %4$s<br><br>Please log in to your account and change your password after your first login.<br><br>', 'bookingor'),
					esc_html($staff_first_name),
					esc_html($staff_last_name),
					esc_html($staff_email),
					esc_html($staff_password)
				);
				if (!empty(get_option("bookingor_settings_email_type"))) {
					EmailNotification::sendEmail($to, $subject, $message);
				}
			}
			self::$bookingorDb->insert(
				$add_staff,
				array(
					'staff_first_name' => $staff_first_name,
					'staff_last_name' => $staff_last_name,
					'staff_email' => $staff_email,
					'staff_tag_line' => $staff_tag_line,
					'staff_about' => $staff_about,
					'staff_phone' => $staff_phone,
					'staff_icon' => $staff_image,
					'status' => $status,
					'staff_sheet_weekly' => $staff_weekly_schedule,
				),
			);
			$id = $wpdb->insert_id;
			// =========================================

			/* ============================================================
			  add services on staff
			============================================ */

			$assign_services_in_staff = map_deep(wp_unslash($_POST['assign_services_in_staff'] ?? ''), 'sanitize_text_field');
			if (!empty($assign_services_in_staff)) {
				self::$bookingorDb->delete($assign_staff_service, array(
					'staff_get_id' => $id,
				));
				foreach ($assign_services_in_staff as $key => $value) {
					if (isset($_POST['staff_service_get_id'])) {
						self::$bookingorDb->update(
							$assign_staff_service,
							array(
								'staff_get_id' => $id,
								'service_get_id' => $value['staff_service_get_id'],
							),
							array('staff_get_id' => $id,)
						);
					}
					if (empty($assign_services_in_staff)) {
						self::$bookingorDb->delete($assign_staff_service, array(
							'staff_get_id' => $id,
						));
					} else {
						self::$bookingorDb->insert(
							$assign_staff_service,
							array(
								'staff_get_id' => $id,
								'service_get_id' => $value['staff_service_get_id'],
							)
						);
					}
				}
			} else {
				self::$bookingorDb->delete($assign_staff_service, array(
					'staff_get_id' => $id,
				));
				$assign_services_in_staff = null;
			}
			/* ============================================================
			  end add services on staff
			============================================ */
			/* ============================================================
			location add staff
			============================================ */

			$staff_location = map_deep(wp_unslash($_POST['assign_locations_in_staff'] ?? ''), 'sanitize_text_field');
			if (!empty($staff_location)) {
				foreach ($staff_location as $key => $value) {
					self::$bookingorDb->insert(
						$staff_location_assign,
						array(
							'staff_get_id' => $id,
							'location_get_id' => $value['staff_location_get_id'],
						),
					);
				}
			} else {
				$_POST['staff_location_get_id'] = null;
			}
			// ========================= location end ==============================
			$get_staff_name = get_option('bookingor_settings_staff_name');



			$response = [
				'status' => 'success',
				'message' => $get_staff_name . ' Updated Successfully'
			];
			echo wp_json_encode($response);
			exit;
		}
	}
	/**
	 * Retrieves staff details from the database.
	 *
	 * Retrieves and returns staff information including staff ID, first name, last name, email, phone number, location, icon, weekly schedule, holidays, Google Calendar ID, Google access token, Google time zone, and status.
	 *
	 * @return array|null An array of staff details or null if no data is found.
	 */
	public static function bp_view_staff()
	{
		global $wpdb;
		self::$bookingorDb = $wpdb;
		$view_staff = $wpdb->prefix . self::$dp_prefix . 'staff_add';
		$location = $wpdb->prefix . self::$dp_prefix . 'location';
		$staff_location = $wpdb->prefix . self::$dp_prefix . 'location_assign_staff';

		return self::$staff_view = self::$bookingorDb->get_results($wpdb->prepare(
			"SELECT 
            s.staff_id, 
            s.staff_first_name, 
            s.staff_last_name, 
            s.staff_email, 
            s.staff_phone, 
            s.staff_location, 
            s.staff_icon, 
            s.staff_sheet_weekly, 
            s.google_calendar_id, 
            s.google_access_token, 
            s.google_time_zone, 
            s.status,
            l.staff_get_id,
            l.location_get_id,
            loc.location_id,
            GROUP_CONCAT(loc.location_address) AS location_address
        FROM 
            %1\$s AS s
        LEFT JOIN 
             {$wpdb->prefix}bookingor_location_assign_staff AS l ON s.staff_id = l.staff_get_id
        LEFT JOIN 
             {$wpdb->prefix}bookingor_location AS loc ON l.location_get_id = loc.location_id
			GROUP BY 
            s.staff_id",
			$view_staff,

		));
	}
	/**
	 * Retrieves staff details from the database based on the provided staff ID.
	 * Retrieves staff information including first name, last name, email, phone number, location, icon, tag line, about, weekly schedule, holidays, Google Calendar ID, Google access token, Google time zone, and status.
	 *
	 * @return stdClass An object containing staff data, special days, leave information, assigned services, and locations.
	 */
	public static function bp_get_staff_data()
	{
		$staffDetails = new stdClass();
		global $wpdb;
		self::$bookingorDb = $wpdb;
		$get_staff_data = $wpdb->prefix . self::$dp_prefix . 'staff_add';
		$get_staff_assign_service_data = $wpdb->prefix . self::$dp_prefix . 'staff_assign_service';
		$get_staff_location = $wpdb->prefix . self::$dp_prefix . 'location_assign_staff';
		$id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;
		if (isset($_POST['nonce'])) {
			if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'bookingor_ajax_nonce')) {
				$response = [
					'status' => htmlspecialchars('error'),
					'message' => htmlspecialchars('Nonce verification failed.')
				];
			}
		}

		self::$staff_data = self::$bookingorDb->get_results($wpdb->prepare("
			SELECT 
				staff_id, 
				staff_first_name, 
				staff_last_name, 
				staff_email, 
				staff_phone, 
				staff_location, 
				staff_icon,
				staff_tag_line,
				staff_about, 
				staff_sheet_weekly, 
				staff_holiday,
				zoom_user_id, 
				google_calendar_id, 
				google_access_token, 
				google_time_zone, 
				status 
			FROM 
				%1\$s 
			WHERE 
				staff_id = %2\$d
		", $get_staff_data, $id));
		self::$staff_assign = self::$bookingorDb->get_results($wpdb->prepare("
			SELECT 
				assign_id, 
				staff_get_id, 
				service_get_id, 
				staff_price 
			FROM 
				%1\$s 
			WHERE 
				staff_get_id = %2\$d
		", $get_staff_assign_service_data, $id));
		self::$staff_location = self::$bookingorDb->get_results($wpdb->prepare("
			SELECT 
				location_assign_id, 
				location_get_id, 
				staff_get_id 
			FROM 
				%1\$s 
			WHERE 
				staff_get_id = %2\$d
		", $get_staff_location, $id));
		$staffDetails->staffData = self::$staff_data;
		$staffDetails->staffDataSpDay = self::$staff_data_sp_day;
		$staffDetails->staffDataLeave = self::$staff_data_leave;
		$staffDetails->staffAssign = self::$staff_assign;
		$staffDetails->staffLocation = self::$staff_location;
		return $staffDetails;
	}
	/**
	 * Retrieves and returns the list of locations for staff members.
	 *
	 * Retrieves location details including ID, title, icon, country, city, address, phone number, latitude, longitude, time sheet, and status.
	 *
	 * @return array|null An array of location details or null if no data is found.
	 */
	public static function bp_get_location_fr_staff()
	{
		global $wpdb;
		self::$bookingorDb = $wpdb;
		$staff_get_location = $wpdb->prefix . self::$dp_prefix . 'location';
		if (!empty(self::$staff_add_location)) {
			return self::$staff_add_location = self::$bookingorDb->get_results($wpdb->prepare("SELECT location_id, location_title, location_icon, location_country, location_city, location_address, location_phone, location_latitude, location_longitude, location_time_sheet, status FROM %1\$s", $staff_get_location));
		}
	}
}
