<?php

namespace Bookingor\Frontend\Controller\TimeSheet;

use Bookingor\Frontend\Controller\TimeSheet\ServiceTimeSheetControlFront;

class WeeklyTimeSheetControlFront
{
	private static $bookingorDb;
	public static $f_staff_time_sheet;
	public static $f_service;
	public static $f_service_time_sheet;
	public static $f_business_time_sheet;
	public static $dp_prefix = "bookingor_";
	public static $staff_slot_availability = 'one_at_a_time';

	/**
	 * Ajax function to get the weekly time sheet of a service.
	 * 
	 * @package bookingor
	 * @since 1.0.0
	 */
	public function bookingor_front_business_weekly_time_sheet()
	{
		$response  = new \stdclass();
		$response->success = false;
		global $wpdb;
		$staff = $wpdb->prefix . self::$dp_prefix . 'staff_add';
		$service = $wpdb->prefix . self::$dp_prefix . 'services';
		$get_id = $wpdb->prefix . self::$dp_prefix . 'staff_assign_service';
		$slot_booked = $wpdb->prefix . self::$dp_prefix . 'booked_appointment';
		$business_time_sheet = get_option("bookingor_business_hours");

		// phpcs:disable WordPress.Security.NonceVerification.Recommended -- Verified elsewhere.
		// phpcs:disable WordPress.Security.NonceVerification.Missing -- Verified elsewhere.
		$service_get_id = isset($_REQUEST['service_id_only']) ? intval($_REQUEST['service_id_only']) : 0;
		$date_get_day = isset($_REQUEST['get_days']) ? intval($_REQUEST['get_days']) : 0;
		$date_full = sanitize_text_field(wp_unslash(isset($_POST['get_date']) ? $_POST['get_date'] : ''));
		$get_end_date = sanitize_text_field(wp_unslash($_POST['get_end_date'] ?? ""));
		$get_time_format = get_option("bookingor_time_format");


		if (!empty($service_get_id)) {
			$response =   $wpdb->get_row(
				$wpdb->prepare("SELECT 
				service_icon, 
				service_name, 
				category_get_id, 
				service_cost, 
				service_duration, 
				service_duration_type,
				wc_id, 
				status 
			FROM 
				{$wpdb->prefix}bookingor_services 
			WHERE 
				service_id = %d", $service_get_id)
			);
		}
		// find capacity 1 or greater than 1
		$find_capacity = $wpdb->get_results($wpdb->prepare(
			"SELECT 
				sb.service_get_id, 
				sb.staff_get_id, 
				sb.start_time, 
				sb.end_time, 
				sb.picked_date, 
				SUM(sb.people_count) AS total_people_count
			FROM 
				{$wpdb->prefix}bookingor_booked_appointment sb 
			LEFT JOIN 
				{$wpdb->prefix}bookingor_services s ON s.service_id = sb.service_get_id 
			WHERE 
				sb.picked_date = %s AND sb.service_get_id = %d 
			GROUP BY 
				sb.service_get_id, sb.end_time, sb.start_time",
			$date_full,
			$service_get_id
		));
		if (empty($get_end_date)) {
			$get_end_date = $date_full;
		}
		// find booked slots
		$find_booked_slot = $wpdb->get_results($wpdb->prepare(
			"SELECT 
			start_time, 
			end_time,
			picked_date,
			picked_date_end
		FROM 
			{$wpdb->prefix}bookingor_booked_appointment  
		WHERE 
			picked_date <= %s AND COALESCE(picked_date_end, picked_date) >= %s",
			$get_end_date,
			$date_full
		));

		$serviceDuration_Type = null;
		$service_start_time_slot = null;
		if (isset($response) && !empty($response)) {
			if (isset($response->service_duration)) {
				$service_duration = $response->service_duration;
			}
			if (isset($response->service_duration_type) && !empty($response->service_duration_type)) {
				$serviceDuration_Type = $response->service_duration_type;
			}
		}
		$get_dats = str_replace('\\', '', $business_time_sheet);

		$bookedTimeSlot = [];
		$findTotalCapacity = [];
		foreach ($find_capacity as $capacity) {
			$serviceCapacity = 1;
			$peopleCount = $capacity->total_people_count;
			$findTotalCapacity[] = [$serviceCapacity, $peopleCount];
		}
		foreach ($find_booked_slot as $booked) {
			$bookStart = strtotime($booked->start_time);
			$bookEnd = strtotime($booked->end_time);
			$bookedTimeSlot[] = [$bookStart, $bookEnd];
		}

		function checkBookedTimecapBusiness($StartTime, $bookedTimeSlot, $findTotalCapacity)
		{
			if (!empty($findTotalCapacity)) {
				foreach ($findTotalCapacity as $capacity) {
					if ($capacity[0] <= $capacity[1] && $capacity[0] > 1) {
						if (!empty($bookedTimeSlot)) {
							$isBooked = false;
							foreach ($bookedTimeSlot as $booked) {
								if ($StartTime >= $booked[0] && $StartTime < $booked[1]) {
									$isBooked = true;
									break;
								}
							}
							if ($isBooked) {
								return $booked[1]; // Return the end time as a timestamp
							}
						}
					} else if ($capacity[0] <= $capacity[1] && $capacity[0] <= 1) {
						if (!empty($bookedTimeSlot)) {
							$isBooked = false;
							foreach ($bookedTimeSlot as $booked) {
								if ($StartTime >= $booked[0] && $StartTime < $booked[1]) {
									$isBooked = true;
									break;
								}
							}
							if ($isBooked) {
								return $booked[1]; // Return the end time as a timestamp
							}
						}
					}
					return $StartTime;
				}
			}
		}
		if ($serviceDuration_Type === "minute" || $serviceDuration_Type === "hour") {
			foreach (json_decode($get_dats)  as $innerKey => $innerValue) {

				if ($date_get_day === ($innerKey + 1) || $innerKey === 6) {
					$weekly_time = [];
					foreach ($innerValue as $dayKey => $dayValue) {
						$StartTime   = !empty($dayValue[0]) ? strtotime($dayValue[0]) : ""; //Get Timestamp
						$EndTime     = !empty($dayValue[1]) ? strtotime($dayValue[1]) : ""; //Get Timestamp
						$AddDuration = $service_duration * 60; // Add Duration
						$breakTimestamps = [];

						if (empty($innerValue->breaks)) {
							while ($StartTime < $EndTime) {
								// 0/ null means start time slot increment toggle off 
								if ($StartTime < $EndTime) {
									if (!empty($bookedTimeSlot) && !empty($findTotalCapacity)) {
										$isBooked = false;
										foreach ($bookedTimeSlot as $booked) {
											if ($StartTime >= $booked[0] && $StartTime < $booked[1]) {
												$isBooked = true;
												$lastBooked = $booked;
												break;
											}
										}
										// If not a break, add split timing
										if (!$isBooked) {
											$weekly_time[$dayKey][] = [date('h:i A', $StartTime), date('h:i A', $StartTime + $AddDuration)];
											$StartTime += $AddDuration;
											$StartTime = checkBookedTimecapBusiness($StartTime, $bookedTimeSlot, $findTotalCapacity);
										} else {
											$StartTime = $booked[1];
											$StartTime = checkBookedTimecapBusiness($StartTime, $bookedTimeSlot, $findTotalCapacity);
										}
									} else {
										$weekly_time[$dayKey][] = [date($get_time_format, $StartTime), date($get_time_format, $StartTime + $AddDuration)];
										$StartTime  += $AddDuration;
										if (!empty($bookedTimeSlot) && !empty($findTotalCapacity)) {
											$StartTime = checkBookedTimecapBusiness($StartTime, $bookedTimeSlot, $findTotalCapacity);
										}
									}
								} else {
									// start time slot increment toggle on
									if (isset($timeSlots) && $timeSlots > 0) {
										// No buffer start. No buffer end. with start time slot toggle on
										$weekly_time[$dayKey][] = date($get_time_format, $StartTime);
										if ($StartTime < $EndTime) {
											$weekly_time[$dayKey][] = date($get_time_format, $StartTime + $timeSlots);
											$StartTime  += $timeSlots;
										}
									}
								}
							}
							if ($weekly_time[$dayKey] === null) {
								echo wp_json_encode(["success" => false, "error" => "No Availability, Try another Date"]);
								die();
							} else {
								echo wp_json_encode($weekly_time[$dayKey]);
								die();
							}
						}
					}
				}
			}
		} else if ($serviceDuration_Type === "day" || $serviceDuration_Type === "week" || $serviceDuration_Type === "monthly") {
			foreach (json_decode($get_dats)  as $innerKey => $innerValue) {

				if ($date_get_day === ($innerKey + 1) || $innerKey === 6) {
					$weekly_time = [];
					foreach ($innerValue as $dayKey => $dayValue) {
						if ($dayKey === 'breaks') {
							continue;
						}

						if ($dayValue == "off") {
							echo wp_json_encode(["success" => false, "error" => "No Availability, Try another Date"]);
							die();
						}
						// Check if the slot is already booked
						if (!empty($find_booked_slot)) {
							echo wp_json_encode(["success" => false, "error" => "No Availability, Try another Date"]);
							die();
						}

						$StartTime   = !empty($dayValue[0]) ? strtotime($dayValue[0]) : ""; //Get Timestamp
						$EndTime     = !empty($dayValue[1]) ? strtotime($dayValue[1]) : ""; //Get Timestamp

						if ($StartTime < $EndTime) {
							// Calculate End Date
							// Assuming $date_full is the start date Y-m-d
							// Duration type: day, week, minute
							$duration_type_str = $serviceDuration_Type;
							if ($serviceDuration_Type == 'monthly') {
								$duration_type_str = 'month';
							}

							$modify_string = "+ " . (int)$service_duration . " " . $duration_type_str . "s";
							$show_start_Date = $date_full;
							$show_end_date = $get_end_date;

							// For 'day', 'week', 'minute' in this block, we show the full business day
							// start time and end time, plus the calculated end date.
							$weekly_time[$dayKey][] = [
								date($get_time_format, $StartTime),
								date($get_time_format, $EndTime),
								$date_full,
								$get_end_date

							];

							echo wp_json_encode($weekly_time[$dayKey]);
							die();
						} else {
							echo wp_json_encode(["success" => false, "error" => "No Availability, Try another Date"]);
							die();
						}
					}
				}
			}
		}
	}
}
