package com.project.whatsappchatbot.controller.BotController;

import java.sql.Date;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.annotation.PostConstruct;
import javax.transaction.Transactional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.project.whatsappchatbot.DTO.NotificationMessage;
import com.project.whatsappchatbot.model.Address;
import com.project.whatsappchatbot.model.ChatMessage;
import com.project.whatsappchatbot.model.City;
import com.project.whatsappchatbot.model.Complaint;
import com.project.whatsappchatbot.model.ConversationState;
import com.project.whatsappchatbot.model.Customer;
import com.project.whatsappchatbot.model.HelpSupport;
import com.project.whatsappchatbot.model.Invoice;
import com.project.whatsappchatbot.model.Order;
import com.project.whatsappchatbot.model.OrderCancellationReason;
import com.project.whatsappchatbot.model.Service;
import com.project.whatsappchatbot.model.UserResponse;
import com.project.whatsappchatbot.model.Vehicle;
import com.project.whatsappchatbot.model.VehicleModel;
import com.project.whatsappchatbot.repository.AddressRepository;
import com.project.whatsappchatbot.repository.BrandRepository;
import com.project.whatsappchatbot.repository.ChatMessageRepository;
import com.project.whatsappchatbot.repository.CityRepository;
import com.project.whatsappchatbot.repository.ComplaintRepository;
import com.project.whatsappchatbot.repository.ConversationStateRepository;
import com.project.whatsappchatbot.repository.CustomerRepository;
import com.project.whatsappchatbot.repository.HelpSupportRepository;
import com.project.whatsappchatbot.repository.InvoiceRepository;
import com.project.whatsappchatbot.repository.OrderCancellationReasonRepository;
import com.project.whatsappchatbot.repository.OrderRepository;
import com.project.whatsappchatbot.repository.ServiceRepository;
import com.project.whatsappchatbot.repository.StatusRepository;
import com.project.whatsappchatbot.repository.UserResponseRepository;
import com.project.whatsappchatbot.repository.VehicleModelRepository;
import com.project.whatsappchatbot.repository.VehicleRepository;
import com.project.whatsappchatbot.security.services.InputSanitizer;

@CrossOrigin(origins = "https://wati.bikefixup.co.in", maxAge = 3600)
@RestController
@RequestMapping("/chat")
@Transactional
public class WhatsAppBotController {

	@Autowired
	private StatusRepository statusRepository;
	@Autowired
	private VehicleModelRepository vehicleModelRepository;
	@Autowired
	private ServiceRepository serviceRepository;
	@Autowired
	private CustomerRepository customerRepository;
	@Autowired
	private CityRepository cityRepository;
	@Autowired
	private BrandRepository brandRepository;

	@Autowired
	private InvoiceRepository invoiceRepository;
	@Autowired
	private ConversationStateRepository conversationStateRepository;
	@Autowired
	private OrderCancellationReasonRepository orderCancellationReasonRepository;

	@Autowired
	private UserResponseRepository userResponseRepository;

	@Autowired
	private HelpSupportRepository helpSupportRepository;
	@Autowired
	private AddressRepository addressRepository;
	@Autowired
	private VehicleRepository vehicleRepository;

	@Autowired
	private OrderRepository orderRepository;

	@Autowired
	private ComplaintRepository complaintRepository;

	@Value("${baseurl}")
	private static String baseUrl;

	@Value("${whatsapp.api.url}")
    private  String whatsappApiUrl;

    @Value("${whatsapp.api.token}")
    private  String whatsappApiToken;

    @Value("${verify.token}")
    private   String verifyToken;

	private static final Logger log = LoggerFactory.getLogger(WhatsAppBotController.class);
	DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy");

 	public static String WHATSAPP_API_URL;
    public static String WHATSAPP_API_TOKEN;
    public static String VERIFY_TOKEN;

	private static final RestTemplate restTemplate = new RestTemplate();
	private StringBuilder userResponse;

	@Value("${phone.notification.numbers}")
    private String notificationNumbers;

    private List<String> notificationNumberList;

    @PostConstruct
    public void init() {
		WHATSAPP_API_URL = whatsappApiUrl;
        WHATSAPP_API_TOKEN = whatsappApiToken;
        VERIFY_TOKEN = verifyToken;

        if (notificationNumbers != null && !notificationNumbers.isBlank()) {
        	notificationNumberList = Arrays.asList(notificationNumbers.split(","));
        } else {
            notificationNumberList = new ArrayList<>();
        }
    }

	@Autowired
	private SimpMessagingTemplate template;

	@Autowired
	private ObjectMapper objectMapper;

	@GetMapping("/")
	public ResponseEntity<String> home() {
		return ResponseEntity.ok("WhatsApp Chatbot Server Running");
	}

	@GetMapping("/webhook")
	public ResponseEntity<String> verifyWebhook(@RequestParam("hub.mode") String mode,
			@RequestParam("hub.verify_token") String token, @RequestParam("hub.challenge") String challenge) {
		if ("subscribe".equals(mode) && VERIFY_TOKEN.equals(token)) {
			return ResponseEntity.ok(challenge);
		}
		return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
	}

	private Map<String, String> conversationStates = new HashMap<>();
	private Map<String, String> userNames = new HashMap<>();
	private Map<String, String> userRepairRequests = new HashMap<>();

	private String getConversationState(String recipientNumber) {
		return conversationStates.get(recipientNumber);
	}

	private void setConversationState(String recipientNumber, String state) {
		if (state == null) {
			conversationStates.remove(recipientNumber);
		} else {
			conversationStates.put(recipientNumber, state);
		}
	}

	private void setUserName(String recipientNumber, String name) {
		userNames.put(recipientNumber, name);
	}

	private void setUserRepairRequest(String recipientNumber, String request) {
		userRepairRequests.put(recipientNumber, request);
	}

	@PostMapping("/webhook")
	public ResponseEntity<String> webhook(@RequestBody Map<String, Object> webhookData) {
		System.out.println("Received webhook data: " + webhookData);

		List<Map<String, Object>> entries = (List<Map<String, Object>>) webhookData.getOrDefault("entry",
				Collections.emptyList());
		entries.forEach(entry -> {
			List<Map<String, Object>> changes = (List<Map<String, Object>>) entry.getOrDefault("changes",
					Collections.emptyList());
			changes.forEach(change -> {
				if ("messages".equals(change.get("field"))) {
					Map<String, Object> value = (Map<String, Object>) change.get("value");

					List<Map<String, Object>> contacts = (List<Map<String, Object>>) value.getOrDefault("contacts",
							Collections.emptyList());
					String senderName = null;
					if (!contacts.isEmpty()) {
						Map<String, Object> contact = contacts.get(0);
						Map<String, Object> profile = (Map<String, Object>) contact.get("profile");
						senderName = (String) profile.get("name");
					}

					System.out.println("Extracted senderName: " + senderName);

					List<Map<String, Object>> messages = (List<Map<String, Object>>) value.getOrDefault("messages",
							Collections.emptyList());
					String finalSenderName = senderName;
					messages.forEach(message -> {
						String recipientNumber = (String) message.get("from");
						recipientNumber = "+" + recipientNumber;
						recipientNumber = recipientNumber.replace("+91", "");
						String userMessage = null;
						if ("text".equals(message.get("type"))) {
							Map<String, Object> messageContent = (Map<String, Object>) message.get("text");
							userMessage = (String) messageContent.get("body");
						} else if ("interactive".equals(message.get("type"))) {
							Map<String, Object> interactiveContent = (Map<String, Object>) message.get("interactive");
							Map<String, Object> listReply = (Map<String, Object>) interactiveContent.get("list_reply");
							if (listReply != null) {
								userMessage = (String) listReply.get("title");
							}
						} else if ("location".equals(message.get("type"))) {
							Map<String, Object> locationContent = (Map<String, Object>) message.get("location");
							double latitude = (double) locationContent.get("latitude");
							double longitude = (double) locationContent.get("longitude");
							userMessage = "Location received: Latitude = " + latitude + ", Longitude = " + longitude;
						}

						ConversationState conversationState = conversationStateRepository
								.findByPhoneNumber(recipientNumber);
						if (conversationState == null) {
							conversationState = new ConversationState();
							conversationState.setPhoneNumber(recipientNumber);
						}

						List<UserResponse> userResponses = userResponseRepository.findByPhoneNumber(recipientNumber);
						List<UserResponse> newUserResponses = new ArrayList<>(userResponses);

						if (userMessage == null) {
							sendTextMessage(recipientNumber, "Sorry, I didn't understand that message.");
							saveOrUpdateChatMessage(recipientNumber, "Bot", "Sorry, I didn't understand that message.");
							return;
						} else if (userMessage.toLowerCase().equals("exit")) {

							try {
								userResponseRepository.deleteByPhoneNumber(recipientNumber);
								System.out.println("User responses cleared for: " + recipientNumber);
							} catch (Exception e) {
								System.err.println("Error clearing user responses: " + e.getMessage());
							}
							newUserResponses.clear();

							conversationState.setState(null);
						} else if (userMessage.toLowerCase().equals("hi")) {

							try {
								userResponseRepository.deleteByPhoneNumber(recipientNumber);
								System.out.println("User responses cleared for: " + recipientNumber);
							} catch (Exception e) {
								System.err.println("Error clearing user responses: " + e.getMessage());
							}
							newUserResponses.clear();
							conversationState.setState(null);
						} else if (Arrays.asList("📝 Quick Booking", "⚙ Services", "\uD83D\uDCBB Booking Management",
								"⏱ Service Status", "📄 Invoice", "\uD83D\uDCDE Help & Support",
								"\uD83D\uDCF2 Download our app", "🚨 Complaint").contains(userMessage)) {
							try {
								userResponseRepository.deleteByPhoneNumber(recipientNumber);
								System.out.println("User responses cleared for: " + recipientNumber);
							} catch (Exception e) {
								System.err.println("Error clearing user responses: " + e.getMessage());
							}
							newUserResponses.clear();
							conversationState.setState("AWAITING_MAIN_MENU_SELECTION");
						}

						if (conversationState.getState() == null) {

							Customer customer = customerRepository.findByPhone(recipientNumber);
							boolean isNewCustomer = false;

							if (customer == null) {
								customer = new Customer();
								customer.setPhone(recipientNumber);

								if (customer.getName() == null) {

									if (finalSenderName != null) {
										customer.setName(finalSenderName);
									}
								}
								isNewCustomer = true;
							}

							try {
								customerRepository.save(customer);
								System.out.println("Customer saved: " + customer);
							} catch (Exception e) {
								System.err.println("Error saving customer: " + e.getMessage());
								sendTextMessage(recipientNumber,
										"There was an error processing your request. Please try again later.");
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"There was an error processing your request. Please try again later.");
								return;
							}

							if (isNewCustomer) {
								sendTextMessage(recipientNumber, "Welcome, I'm Leo. How may I assist you today?");
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Welcome, I'm Leo. How may I assist you today?");
							} else {

								sendTextMessage(recipientNumber,
										"Welcome back " + customer.getName() + "! How may I assist you today?");
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Welcome back " + customer.getName() + "! How may I assist you today?");
							}

							sendQuickReplies(recipientNumber,
									Arrays.asList("📝 Quick Booking", "⚙ Services", "\uD83D\uDCBB Booking Management",
											"⏱ Service Status", "📄 Invoice", "\uD83D\uDCDE Help & Support",
											"\uD83D\uDCF2 Download our app", "🚨 Complaint"));
							saveOrUpdateChatMessage(recipientNumber, recipientNumber, userMessage);
							conversationState.setState("AWAITING_MAIN_MENU_SELECTION");
						} else {

							switch (conversationState.getState()) {

							case "AWAITING_MAIN_MENU_SELECTION":

								newUserResponses
										.add(new UserResponse(recipientNumber, "Main Menu Selection: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Main Menu Selection: " + userMessage);
								conversationState.setState(handleMainMenuSelection(recipientNumber, userMessage));
								break;

///////////////////////    New Booking  Start

							case "AWAITING_NEWB_FULLNAME":
								saveOrUpdateChatMessage(recipientNumber, recipientNumber, userMessage);
								newUserResponses.add(new UserResponse(recipientNumber, "Full Name: " + userMessage));
								sendTextMessage(recipientNumber, "Please Provide the your Contact Number");
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Please Provide the your Contact Number");
								conversationState.setState("AWAITING_NEWB_CONTACT_NUMBER");
								break;

							case "AWAITING_NEWB_CONTACT_NUMBER":
								newUserResponses
										.add(new UserResponse(recipientNumber, "Contact Phone Number: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Contact Phone Number: " + userMessage);
								sendTextMessage(recipientNumber, "Please provide the city where you currently reside.");
								sendQuickReplies(recipientNumber, Arrays.asList("Bengaluru", "Hyderabad ", "Pune",
										"Faridabad", "Delhi", "Noida", "Chennai ", "Ghaziabad", "Ahmedabad", "Mumbai"));
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Please provide the city where you currently reside.");
								conversationState.setState("AWAITING_NEWB_CITES_SELECTION"); // Corrected to move to the
								// correct state
								break;

							case "AWAITING_NEWB_CITES_SELECTION":
								newUserResponses.add(new UserResponse(recipientNumber, "City: " + userMessage));
								if (1 == 1) {
									saveOrUpdateChatMessage(recipientNumber, recipientNumber, "City: " + userMessage);
									sendTextMessage(recipientNumber, "Please provide Brand of your Vehicle");
									sendQuickReplies(recipientNumber, Arrays.asList("Hero", "Honda", "TVS",
											"Royal Enfield", "Yamaha", "Suzuki", "Bajaj", "Other"));
									saveOrUpdateChatMessage(recipientNumber, "Bot",
											"Please provide Brand of your Vehicle");
									conversationState.setState("AWAITING_NEWB_BRAND_SELECTION"); // Corrected to move to
									// the correct state

								}
								break;

							case "AWAITING_NEWB_BRAND_SELECTION":
								handle_NEWB_BrandSelection(recipientNumber, userMessage);
								newUserResponses
										.add(new UserResponse(recipientNumber, "Brand Selection: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Brand Selection: " + userMessage);
								conversationState.setState("AWAITING_NEWB_DESCRIPTION");
								break;

							case "AWAITING_NEWB_DESCRIPTION":

								if (1 == 1) {
									newUserResponses.add(
											new UserResponse(recipientNumber, "Problem Description: " + userMessage));
									saveOrUpdateChatMessage(recipientNumber, recipientNumber,
											"Problem Description: " + userMessage);
									sendTextMessage(recipientNumber, "Please provide your Address.");
									saveOrUpdateChatMessage(recipientNumber, "Bot", "Please provide your Address.");

									conversationState.setState("AWAITING_NEWB_ADDRESS");
								}

								break;

							case "AWAITING_NEWB_ADDRESS":
								log.info("Newb address {}", userMessage);
								saveOrUpdateChatMessage(recipientNumber, recipientNumber, "Address: " + userMessage);
								newUserResponses.add(new UserResponse(recipientNumber, "Address: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Please share your location using the location feature");

								if (1 == 1) {
									Map<String, Object> payload = createLocationRequestPayload(recipientNumber,
											"Please share your location using the location feature");
									sendMessage1(payload);
								}
								conversationState.setState("AWAITING_NEWB_LOCATION");
								break;

							case "AWAITING_NEWB_LOCATION":
								if (1 == 1) {
									saveOrUpdateChatMessage(recipientNumber, recipientNumber,
											"Location: " + userMessage);
									newUserResponses.add(new UserResponse(recipientNumber, "Location: " + userMessage));
									sendTextMessage(recipientNumber,
											"Could you please provide a preferred date for the service?");
									saveOrUpdateChatMessage(recipientNumber, "Bot",
											"Could you please provide a preferred date for the service?");

									List<String> dateOptions = generateDateOptions();
									sendQuickReplies(recipientNumber, dateOptions);

									conversationState.setState("AWAITING_NEWB_DATE_SELECTION");
								}
								break;

							case "AWAITING_NEWB_DATE_SELECTION":
								newUserResponses
										.add(new UserResponse(recipientNumber, "Date Selection: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Date Selection: " + userMessage);

								sendTextMessage(recipientNumber,
										"Could you please provide a preferred time slot for the service?");
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Could you please provide a preferred time slot for the service?");
								if (1 == 1) {
									List<String> timeSlots = generateTimeSlots();
									sendQuickReplies(recipientNumber, timeSlots);
								}
								conversationState.setState("AWAITING_NEWB_TIME_SELECTION");
								break;

							case "AWAITING_NEWB_TIME_SELECTION":
								if (1 == 1) {
									newUserResponses
											.add(new UserResponse(recipientNumber, "Time Selection: " + userMessage));
									saveOrUpdateChatMessage(recipientNumber, recipientNumber,
											"Time Selection: " + userMessage);
									StringBuilder summary = new StringBuilder(
											"Here are the details you've provided:\n");
									summary.append("Name: ").append(finalSenderName).append("\n");
									for (UserResponse response : newUserResponses) {
										summary.append(response.getResponse()).append("\n");
									}
									sendTextMessage(recipientNumber, summary.toString());
									sendTextMessage(recipientNumber,
											"Please type 'Yes' to confirm your booking or 'No' to cancel it.");
									saveOrUpdateChatMessage(recipientNumber, "Bot",
											"Please type 'Yes' to confirm your booking or 'No' to cancel it.");
									conversationState.setState("AWAITING_NEWB_CONFIRMATION");
								}
								break;
							case "AWAITING_NEWB_CONFIRMATION":

								if (1 == 1) {
									handle_NEWB_Confirmation(recipientNumber, userMessage);
									saveOrUpdateChatMessage(recipientNumber, recipientNumber, userMessage);

								}

								conversationState.setState(null);
								try {
									userResponseRepository.deleteByPhoneNumber(recipientNumber);
									System.out.println("User responses cleared for: " + recipientNumber);
								} catch (Exception e) {
									System.err.println("Error clearing user responses: " + e.getMessage());
								}
								newUserResponses.clear();
								break;
////////         New Booking End

////////////    Services Start

							case "AWAITING_SERVICES_SERVICE_TYPE":

								newUserResponses.add(new UserResponse(recipientNumber, "Service Type: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Service Type: " + userMessage);

								if (userMessage.equalsIgnoreCase("General Services")) {
									sendTextMessage(recipientNumber, "You've selected General Service. This includes:\n"
											+ "- Comprehensive check-up\n" + "- Oil change\n" + "- General tune-up\n"
											+ "Would you like to book this service? (Yes/No)");
								}

								if (userMessage.equalsIgnoreCase("Repairing")) {
									sendTextMessage(recipientNumber,
											"You've selected Repairing. This includes:\n" + "- Fuse Issue\n"
													+ "- Spark Problem\n" + "- Battery Issue\n" + "- Magnet Issue\n"
													+ "Would you like to book this service? (Yes/No)");
								}

								if (userMessage.equalsIgnoreCase("Engine Work")) {
									sendTextMessage(recipientNumber, "You've selected Engine Work. This includes:\n"
											+ "- Piston\n" + "- Crank Assembly\n" + "- Bearing\n" + "- Seal Kit\n"
											+ "- Bore\n" + "- Head Repair\n" + "- Spark Plug\n" + "- DC Kit\n"
											+ "- Engine Oil\n" + "Would you like to book this service? (Yes/No)");
								}

								if (userMessage.equalsIgnoreCase("Body Parts")) {
									sendTextMessage(recipientNumber,
											"You've selected Body Parts. This includes:\n" + "- Mirror Replacement\n"
													+ "- Handle Bar Replacement\n" + "- Fork Bend Removal\n"
													+ "- Tail Light Bulb Replacement\n" + "- Foot Rest Replacement\n"
													+ "- Head Repair\n" + "- Parking Bulb Replacement\n"
													+ "Would you like to book this service? (Yes/No)");
								}

								if (userMessage.equalsIgnoreCase("Special Request")) {
									sendTextMessage(recipientNumber,
											"You've selected Special Request. This includes:\n" +

													"Would you like to book this service? (Yes/No)");
								}

								if (userMessage.equalsIgnoreCase("Other")) {
									sendTextMessage(recipientNumber, "You've selected Other. This includes:\n" +

											"Would you like to book this service? (Yes/No)");
								}
								conversationState.setState("AWAITING_SERVICES_CONFIRM_SERVICE");

								break;

							case "AWAITING_SERVICES_CONFIRM_SERVICE":
								newUserResponses.add(
										new UserResponse(recipientNumber, "Confirmation for Service: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Confirmation for Service: " + userMessage);
								conversationState
										.setState(handle_SERVICES_SELECTION_Confirmation(recipientNumber, userMessage));
								break;

							case "AWAITING_SERVICES_FULLNAME":
								newUserResponses.add(new UserResponse(recipientNumber, "Full Name: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber, "Full Name: " + userMessage);
								sendTextMessage(recipientNumber, "Please Provide the your Contact Number");
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Please Provide the your Contact Number");
								conversationState.setState("AWAITING_SERVICES_CONTACT_NUMBER");
								break;

							case "AWAITING_SERVICES_CONTACT_NUMBER":
								newUserResponses
										.add(new UserResponse(recipientNumber, "Contact Phone Number: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Contact Phone Number: " + userMessage);
								sendTextMessage(recipientNumber, "Please provide the city where you currently reside.");
								sendQuickReplies(recipientNumber, Arrays.asList("Bengaluru", "Hyderabad ", "Pune",
										"Faridabad", "Delhi", "Noida", "Chennai ", "Ghaziabad", "Ahmedabad", "Mumbai"));
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Please provide the city where you currently reside.");
								conversationState.setState("AWAITING_SERVICES_CITES_SELECTION");
								break;

							case "AWAITING_SERVICES_CITES_SELECTION":
								newUserResponses.add(new UserResponse(recipientNumber, "City: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber, "City: " + userMessage);
								sendTextMessage(recipientNumber, "Please provide Brand of your Vehicle");
								sendQuickReplies(recipientNumber, Arrays.asList("Hero", "Honda", "TVS", "Royal Enfield",
										"Yamaha", "Suzuki", "Bajaj", "Other"));
								saveOrUpdateChatMessage(recipientNumber, "Bot", "Please provide Brand of your Vehicle");
								conversationState.setState("AWAITING_NEWB_BRAND_SELECTION");
								break;

							case "AWAITING_SERVICES_BRAND_SELECTION":
								newUserResponses
										.add(new UserResponse(recipientNumber, "Brand Selection: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Brand Selection: " + userMessage);
								sendTextMessage(recipientNumber, "Please Provide where your Address is");
								saveOrUpdateChatMessage(recipientNumber, "Bot", "Please Provide where your Address is");
								conversationState.setState("AWAITING_SERVICE_ADDRESS");
								break;

							case "AWAITING_SERVICE_ADDRESS":
								newUserResponses.add(new UserResponse(recipientNumber, "Address: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber, "Address: " + userMessage);
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Please share your location using the location feature.");
								Map<String, Object> payload = createLocationRequestPayload(recipientNumber,
										"Please share your location using the location feature");
								sendMessage1(payload);
								conversationState.setState("AWAITING_SERVICE_LOCATION");
								break;

							case "AWAITING_SERVICE_LOCATION":
								if (1 == 1) {
									newUserResponses.add(new UserResponse(recipientNumber, "Location: " + userMessage));
									saveOrUpdateChatMessage(recipientNumber, recipientNumber,
											"Location: " + userMessage);
									sendTextMessage(recipientNumber,
											"Could you please provide a preferred date for the service?");
									saveOrUpdateChatMessage(recipientNumber, "Bot",
											"Could you please provide a preferred date for the service?");

									List<String> dateOptions = generateDateOptions();
									sendQuickReplies(recipientNumber, dateOptions);

									conversationState.setState("AWAITING_SERVICE_DATE_SELECTION");
								}
								break;

							case "AWAITING_SERVICE_DATE_SELECTION":
								newUserResponses
										.add(new UserResponse(recipientNumber, "Date Selection: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Date Selection: " + userMessage);

								sendTextMessage(recipientNumber,
										"Could you please provide a preferred time for the service?");
								if (1 == 1) {
									List<String> timeSlots = generateTimeSlots();
									sendQuickReplies(recipientNumber, timeSlots);

								}
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Could you please provide a preferred time for the service?");
								conversationState.setState("AWAITING_SERVICE_TIME_SELECTION");
								break;

							case "AWAITING_SERVICE_TIME_SELECTION":
								if (1 == 1) {
									newUserResponses
											.add(new UserResponse(recipientNumber, "Time Selection: " + userMessage));
									saveOrUpdateChatMessage(recipientNumber, recipientNumber,
											"Time Selection: " + userMessage);
									StringBuilder summary = new StringBuilder(
											"Here are the details you've provided:\n");
									summary.append("Name: ").append(finalSenderName).append("\n");
									for (UserResponse response : newUserResponses) {
										summary.append(response.getResponse()).append("\n");
									}

									sendTextMessage(recipientNumber,
											"Please Provide Additional Description you want to add.");
									saveOrUpdateChatMessage(recipientNumber, "Bot",
											"Please Provide Additional Description you want to add.");

									conversationState.setState("AWAITING_SERVICES_DESCRIPTION");

								}
								break;

							case "AWAITING_SERVICES_DESCRIPTION":

								if (1 == 1) {

									newUserResponses
											.add(new UserResponse(recipientNumber, "Description: " + userMessage));
									saveOrUpdateChatMessage(recipientNumber, recipientNumber,
											"Description: " + userMessage);
									StringBuilder summary = new StringBuilder(
											"Here are the details you've provided:\n");
									summary.append("Name: ").append(finalSenderName).append("\n");
									for (UserResponse response : newUserResponses) {
										summary.append(response.getResponse()).append("\n");
									}
									sendTextMessage(recipientNumber, summary.toString());
									sendTextMessage(recipientNumber,
											"Please type 'Yes' to confirm your booking or 'No' to cancel it.");
									saveOrUpdateChatMessage(recipientNumber, "Bot",
											"Please type 'Yes' to confirm your booking or 'No' to cancel it.");

									conversationState.setState("AWAITING_SERVICES_CONFIRMATION");
								}

								break;

							case "AWAITING_SERVICES_CONFIRMATION":
								handle_SERVICES_Confirmation(recipientNumber, userMessage);
								saveOrUpdateChatMessage(recipientNumber, recipientNumber, userMessage);

								conversationState.setState(null);
								try {
									userResponseRepository.deleteByPhoneNumber(recipientNumber);
									System.out.println("User responses cleared for: " + recipientNumber);
								} catch (Exception e) {
									System.err.println("Error clearing user responses: " + e.getMessage());
								}
								newUserResponses.clear();
								break;
////////         Services End

////  -------
/////////////////        Booking Management		Start
							case "AWAITING_BOOKING_MANAGEMENT_SELECTION":
								newUserResponses.add(new UserResponse(recipientNumber,
										"Booking Management Selection: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Booking Management Selection: " + userMessage);
								sendTextMessage(recipientNumber, "Please Provide the booking Id");
								saveOrUpdateChatMessage(recipientNumber, "Bot", "Please Provide the booking Id");
								conversationState.setState("AWAITING_BOOKING_MANAGEMENT_ID");
								break;

							case "AWAITING_BOOKING_MANAGEMENT_ID":
								String result = getOrder(userMessage, recipientNumber);

								saveOrUpdateChatMessage(recipientNumber, recipientNumber, "Booking Id: " + userMessage);

								String lowerCaseResult = result.trim().toLowerCase();
								System.out.println("Result from getOrder: " + lowerCaseResult);

								if (lowerCaseResult.equals("forbidden: phone number doesn't match.")
										|| lowerCaseResult.equals("order not found.")
										|| lowerCaseResult.equals("invalid order id format.")) {

									saveOrUpdateChatMessage(recipientNumber, "Bot", result);
									sendTextMessage(recipientNumber, result);
									sendTextMessage(recipientNumber, "Please Provide the booking Id");
									saveOrUpdateChatMessage(recipientNumber, "Bot", "Please Provide the booking Id");

									conversationState.setState("AWAITING_BOOKING_MANAGEMENT_ID");
								} else {
									newUserResponses
											.add(new UserResponse(recipientNumber, "Booking Id: " + userMessage));
									sendTextMessage(recipientNumber, result);
									saveOrUpdateChatMessage(recipientNumber, "Bot", result);
									conversationState.setState(handleRescheduleOrCancel(recipientNumber));
								}
								break;

							case "AWAITING_BOOKING_MANAGEMENT_DATE_SELECTION":
								newUserResponses
										.add(new UserResponse(recipientNumber, "Date Selection: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Date Selection: " + userMessage);

								sendTextMessage(recipientNumber,
										"Could you please provide a preferred time for the service?");
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Could you please provide a preferred time for the service?");

								List<String> timeSlots = generateTimeSlots();
								sendQuickReplies(recipientNumber, timeSlots);

								conversationState.setState("AWAITING_BOOKING_MANAGEMENT_TIME_SELECTION");
								break;

							case "AWAITING_BOOKING_MANAGEMENT_TIME_SELECTION":
								newUserResponses
										.add(new UserResponse(recipientNumber, "Time Selection: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Time Selection: " + userMessage);

								StringBuilder summary = new StringBuilder("Here are the details you've provided:\n");
								summary.append("Name: ").append(finalSenderName).append("\n");
								for (UserResponse response : newUserResponses) {
									summary.append(response.getResponse()).append("\n");
								}
								sendTextMessage(recipientNumber, summary.toString());
								sendTextMessage(recipientNumber,
										"Please type 'Yes' to confirm your reschedule or 'No' to cancel it.");
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Please type 'Yes' to confirm your reschedule or 'No' to cancel it.");

								conversationState.setState("AWAITING_BOOKING_MANAGEMENT_CONFIRMATION");
								break;

							case "AWAITING_BOOKING_MANAGEMENT_CANCELLATION_REASON":
								newUserResponses
										.add(new UserResponse(recipientNumber, "Cancellation Reason: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Cancellation Reason: " + userMessage);

								sendTextMessage(recipientNumber,
										"Are you sure you want to cancel this booking? Please type 'Yes' to confirm the cancellation or 'No' to cancel the process.");
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Are you sure you want to cancel this booking? Please type 'Yes' to confirm the cancellation or 'No' to cancel the process.");

								conversationState.setState("AWAITING_BOOKING_MANAGEMENT_CONFIRMATION");
								break;

							case "AWAITING_BOOKING_MANAGEMENT_CONFIRMATION":
								handle_BOOKING_MANAGEMENT_Confirmation(recipientNumber, userMessage);
								saveOrUpdateChatMessage(recipientNumber, recipientNumber, userMessage);

								conversationState.setState(null);
								try {
									userResponseRepository.deleteByPhoneNumber(recipientNumber);
									System.out.println("User responses cleared for: " + recipientNumber);
								} catch (Exception e) {
									System.err.println("Error clearing user responses: " + e.getMessage());
								}
								newUserResponses.clear();
								break;

//////////////////////  Booking ManZagement       End

/////////////////////////////        	Start invoice management
							case "AWAITING_INVOICE_ORDER_ID":
								newUserResponses.add(
										new UserResponse(recipientNumber, "Booking ID for Invoice: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Booking ID for Invoice: " + userMessage);

								if (1 == 1) {
									String results = getCustomerInvoice(userMessage, recipientNumber);
									conversationState.setState(results);
									if (results.toLowerCase().equals("AWAITING_MAIN_MENU_SELECTION".toLowerCase())) {

										conversationState.setState(null);
										try {
											userResponseRepository.deleteByPhoneNumber(recipientNumber);
											System.out.println("User responses cleared for: " + recipientNumber);
										} catch (Exception e) {
											System.err.println("Error clearing user responses: " + e.getMessage());
										}
										newUserResponses.clear();
										conversationState.setState("AWAITING_MAIN_MENU_SELECTION");
									}

								}

								break;

//////////////////////  End Invoice  Mangement

////////////////      HELP AND SUPPORT	Start
							case "AWAITING_HELP_SUPPORT_DESCRIPTION":

								newUserResponses.add(
										new UserResponse(recipientNumber, "Help_Support Description: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, recipientNumber,
										"Help_Support Description: " + userMessage);
								handle_Save_Help_Support(recipientNumber, userMessage);

								conversationState.setState(null);
								newUserResponses.clear();
								userResponses.clear();
								conversationState.setState("AWAITING_MAIN_MENU_SELECTION");
								break;

//////////////////////  HELP AND SUPPORT	      End

/////////////////        	Start Complaint Mangement
							case "AWAITING_COMPLAINT_BOOKING_ID":

								String results = getCustomerComplaint(userMessage, recipientNumber);
								conversationState.setState(results);
								if (results.toLowerCase().equals("AWAITING_COMPLAINT_DESCRIPTION".toLowerCase())) {
									newUserResponses
											.add(new UserResponse(recipientNumber, "Booking Id: " + userMessage));
									saveOrUpdateChatMessage(recipientNumber, recipientNumber,
											"Booking Id: " + userMessage);
								}

								break;

							case "AWAITING_COMPLAINT_DESCRIPTION":
								newUserResponses.add(
										new UserResponse(recipientNumber, "Description for Compliant: " + userMessage));
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Description for Compliant: " + userMessage);

								String resulted = handle_Save_Complaint(recipientNumber, userMessage);

								if (resulted.toLowerCase().equals("AWAITING_MAIN_MENU_SELECTION".toLowerCase())) {

									conversationState.setState(null);
									try {
										userResponseRepository.deleteByPhoneNumber(recipientNumber);
										System.out.println("User responses cleared for: " + recipientNumber);
									} catch (Exception e) {
										System.err.println("Error clearing user responses: " + e.getMessage());
									}
									newUserResponses.clear();

								}

								conversationState.setState("AWAITING_MAIN_MENU_SELECTION");
								break;

//////////////////////  Start Complaint Mangement      End

							default:
								sendTextMessage(recipientNumber,
										"Sorry, I didn't understand that. Can you please choose an option from the menu?");
								saveOrUpdateChatMessage(recipientNumber, "Bot",
										"Sorry, I didn't understand that. Can you please choose an option from the menu?");
								sendQuickReplies(recipientNumber,
										Arrays.asList("📝 Quick Booking", "⚙ Services",
												"\uD83D\uDCBB Booking Management", "⏱ Service Status", "📄 Invoice",
												"\uD83D\uDCDE Help & Support", "\uD83D\uDCF2 Download our app",
												"🚨 Complaint"));
								conversationState.setState(null);
								newUserResponses.clear();
								conversationState.setState("AWAITING_MAIN_MENU_SELECTION");
								break;
							}
						}

						try {

							conversationStateRepository.save(conversationState);
							userResponseRepository.saveAll(newUserResponses);
							System.out.println("Conversation state and responses saved for: " + recipientNumber);
						} catch (Exception e) {
							System.err.println("Error saving conversation state or responses: " + e.getMessage());
							sendTextMessage(recipientNumber,
									"There was an error processing your request. Please try again later.");
							saveOrUpdateChatMessage(recipientNumber, "Bot",
									"There was an error processing your request. Please try again later.");

						}
					});
				}
			});
		});

		return ResponseEntity.ok("EVENT_RECEIVED");
	}

	private String handle_BOOKING_MANAGEMENT_Confirmation(String recipientNumber, String confirmation) {
		List<UserResponse> userResponses = userResponseRepository.findByPhoneNumber(recipientNumber);
		String date = null, time = null, bookingID = null, cancellationReason = null;
		boolean isReschedule = false;
		boolean isCancel = false;

		if (userResponses != null) {
			for (UserResponse userResponse : userResponses) {
				String response = userResponse.getResponse();
				if (response.startsWith("Booking Id: ")) {
					bookingID = InputSanitizer.sanitize(response.substring(12));
				} else if (response.startsWith("Date Selection: ")) {
					date = InputSanitizer.sanitize(response.substring(16));
				} else if (response.startsWith("Time Selection: ")) {
					time = InputSanitizer.sanitize(response.substring(16));
				} else if (response.contains("Reschedule Booking")) {
					isReschedule = true;
				} else if (response.contains("Cancel Booking")) {
					isCancel = true;
				} else if (response.startsWith("Cancellation Reason: ")) {
					cancellationReason = InputSanitizer.sanitize(response.substring(20));
				}
			}
		}

		if (isReschedule) {
			if ("yes".equalsIgnoreCase(confirmation)) {
				if (bookingID != null && date != null && time != null) {
					Order order = orderRepository.findById(Long.valueOf(bookingID)).orElse(null);
					if (order != null) {

						Customer customer = customerRepository.findByPhone(recipientNumber);
						Optional<Service> optionalService = serviceRepository.findById(order.getServiceId());
						if (optionalService.isEmpty()) {
							throw new IllegalArgumentException("Service cannot be empty");
						}

						Service service = optionalService.get();

						try {
//							order.setDateAndTime(convertToTimestamp(date, time));
							order.setDate(Date.valueOf(LocalDate.parse(date, dateFormatter)));
							order.setTime(time);
							order.setStatus(statusRepository.findById(2L).get());
							sendTextMessage(recipientNumber, "Your booking has been rescheduled.");
							saveOrUpdateChatMessage(recipientNumber, "Bot", "Your booking has been rescheduled.");

							String googleMapsLink = "";
							Address address = order.getAddress();
							String latitude = address.getLatitude();
							String longitude = address.getLongitude();
							googleMapsLink = "Google Maps Link: https://www.google.com/maps/search/?api=1&query="
									+ latitude + "," + longitude;

							for (String adminNumber : notificationNumberList) {
								sendTemplateMessageRescheduled(adminNumber, order.getId().toString(), service.getName(),
										order.getVehicle().getBrand().getName(), "N/A",
										address.getCity().getStateId().getName(), address.getCity().getName(),
										address.getAddress(), order.getDateAndTime(), customer.getName(),
										customer.getPhone(), service.getDescription(), googleMapsLink,
										order.getStatus2());
							}

							return "AWAITING_MAIN_MENU_SELECTION";
						} catch (DateTimeParseException e) {
							sendTextMessage(recipientNumber,
									"There was an error parsing the date or time. Please try again.");
							saveOrUpdateChatMessage(recipientNumber, "Bot",
									"There was an error parsing the date or time. Please try again.");
							return "AWAITING_MAIN_MENU_SELECTION";
						}
					}
				} else {
					sendTextMessage(recipientNumber,
							"Booking ID, date, or time is missing. Please provide the complete information.");
					saveOrUpdateChatMessage(recipientNumber, "Bot",
							"Booking ID, date, or time is missing. Please provide the complete information.");
					return "AWAITING_BOOKING_MANAGEMENT_DATE_SELECTION";
				}
			} else if ("no".equalsIgnoreCase(confirmation)) {
				sendTextMessage(recipientNumber, "No worries! Let's start over. Please explore our services again.");
				saveOrUpdateChatMessage(recipientNumber, "Bot",
						"No worries! Let's start over. Please explore our services again.");
				return "AWAITING_MAIN_MENU_SELECTION";
			} else {
				sendTextMessage(recipientNumber, "Please type 'Yes' to confirm your service or 'No' to start over.");
				saveOrUpdateChatMessage(recipientNumber, "Bot",
						"Please type 'Yes' to confirm your service or 'No' to start over.");
				return "AWAITING_SERVICES_SERVICE_TYPE";
			}
		} else if (isCancel) {
			if ("yes".equalsIgnoreCase(confirmation)) {
				if (bookingID != null) {
					Order order = orderRepository.findById(Long.valueOf(bookingID)).orElse(null);
					if (order != null) {
						Customer customer = order.getUser();
						Optional<Service> optionalService = serviceRepository.findById(order.getServiceId());

						if (optionalService.isEmpty()) {
							throw new IllegalArgumentException("Service not found.");
						}
						Service service = optionalService.get();
						order.setStatus(statusRepository.findById(8L).get());
						Optional<OrderCancellationReason> orderCancell = orderCancellationReasonRepository
								.findByTitle(cancellationReason);
						System.out.println(orderCancellationReasonRepository.findAll());
						if (orderCancell.isPresent()) {
							order.setOrderCancellationReason(orderCancell.get());
						} else {
							OrderCancellationReason orderCancellationReason = new OrderCancellationReason();
							orderCancellationReason.setTitle(cancellationReason);
							orderCancellationReason.setActive(1);
							orderCancellationReasonRepository.saveAndFlush(orderCancellationReason);
							order.setOrderCancellationReason(orderCancellationReason);
						}

						sendTextMessage(recipientNumber, "Your booking has been cancelled.");
						saveOrUpdateChatMessage(recipientNumber, "Bot", "Your booking has been cancelled.");

						String googleMapsLink = "";
						Optional<Address> address = Optional.of(order.getAddress());

						String latitude = address.get().getLatitude();
						String longitude = address.get().getLongitude();
						googleMapsLink = "Google Maps Link: https://www.google.com/maps/search/?api=1&query=" + latitude
								+ "," + longitude;

						for (String adminNumber : notificationNumberList) {
							sendTemplateMessageCanceled(adminNumber, order.getId().toString(), service.getName(),
									order.getVehicle().getBrand().getName(), "N/A",
									address.get().getCity().getStateId().getName(), address.get().getCity().getName(),
									address.get().getAddress(), order.getDateAndTime(), customer.getName(),
									customer.getPhone(), service.getDescription(), googleMapsLink, order.getStatus2(),
									cancellationReason);
						}

						return "AWAITING_MAIN_MENU_SELECTION";
					}
				} else {
					sendTextMessage(recipientNumber, "Booking ID is missing. Please provide the complete information.");
					saveOrUpdateChatMessage(recipientNumber, "Bot",
							"Booking ID is missing. Please provide the complete information.");
					return "AWAITING_BOOKING_MANAGEMENT_SELECTION";
				}
			} else if ("no".equalsIgnoreCase(confirmation)) {
				sendTextMessage(recipientNumber, "No worries! Let's start over. Please explore our services again.");
				saveOrUpdateChatMessage(recipientNumber, "Bot",
						"No worries! Let's start over. Please explore our services again.");

				return "AWAITING_MAIN_MENU_SELECTION";
			}
		} else {
			sendTextMessage(recipientNumber, "Please type 'Exit' to start over.");
			saveOrUpdateChatMessage(recipientNumber, "Bot", "Please type 'Exit' to start over.");
			return "AWAITING_MAIN_MENU_SELECTION";
		}

		return recipientNumber;
	}

	public List<String> generateDateOptions() {
		List<String> dateOptions = new ArrayList<>();
		LocalDate today = LocalDate.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy");

		int maxOptions = 10;
		for (int i = 1; i <= maxOptions; i++) {
			LocalDate date = today.plusDays(i);
			dateOptions.add(date.format(formatter));
		}

		return dateOptions;
	}

	public List<String> generateTimeSlots() {
		List<String> timeSlots = new ArrayList<>();
		String[] times = { "09:00 AM", "10:00 AM", "11:00 AM", "12:00 PM", "01:00 PM", "02:00 PM", "03:00 PM",
				"04:00 PM", "05:00 PM", "06:00 PM" };

		for (int i = 0; i < times.length - 1; i++) {
			timeSlots.add(times[i] + " - " + times[i + 1]);
		}

		return timeSlots;
	}

	private String handle_SERVICES_SELECTION_Confirmation(String recipientNumber, String confirmation) {
		if ("yes".equalsIgnoreCase(confirmation)) {
			sendTextMessage(recipientNumber, "Awesome! Let's get started. Please provide the following details");
			sendTextMessage(recipientNumber, "Provide your Full Name");
			saveOrUpdateChatMessage(recipientNumber, "Bot", "Provide your Full Name");
			return ("AWAITING_SERVICES_FULLNAME");
		} else if ("no".equalsIgnoreCase(confirmation)) {
			sendTextMessage(recipientNumber, "No worries! Let's start over. Please explore our services again..");
			saveOrUpdateChatMessage(recipientNumber, "Bot",
					"No worries! Let's start over. Please explore our services again..");
			return ("AWAITING_MAIN_MENU_SELECTION");
		} else {

		}
		return ("AWAITING_SERVICES_SERVICE_TYPE");
	}

	private void handle_SERVICES_Confirmation(String recipientNumber, String confirmation) {
		if ("yes".equalsIgnoreCase(confirmation)) {

			List<UserResponse> userResponses = userResponseRepository.findByPhoneNumber(recipientNumber);
			String brand = null, serviceType = null, location = null, address = null, date = null, time = null,
					description = null, fullName = null, contactPhoneNumber = null, cites = null;
			log.info("User responses:");
			userResponses.forEach(userResponse1 -> log.info(userResponse1.getResponse()));

			for (UserResponse userResponse : userResponses) {
				String response = userResponse.getResponse();
				if (response.startsWith("Brand Selection: ")) {
					brand = InputSanitizer.sanitize(response.substring(17));
				} else if (response.startsWith("Service Type: ")) {
					serviceType = InputSanitizer.sanitize(response.substring(14));
				} else if (response.startsWith("Address: ")) {
					address = InputSanitizer.sanitize(response.substring(9));
				} else if (response.startsWith("Full Name: ")) {
					fullName = InputSanitizer.sanitize(response.substring(11));
				} else if (response.startsWith("Contact Phone Number: ")) {
					contactPhoneNumber = InputSanitizer.sanitize(response.substring(21));
				} else if (response.startsWith("Date Selection: ")) {
					date = InputSanitizer.sanitize(response.substring(16));
				} else if (response.startsWith("Time Selection: ")) {
					time = InputSanitizer.sanitize(response.substring(16));
				} else if (response.startsWith("Description: ")) {
					description = InputSanitizer.sanitize(response.substring(13));
				} else if (response.startsWith("Location: ")) {
					location = InputSanitizer.sanitize(response.substring(10));
				} else if (response.startsWith("City: ")) {
					cites = InputSanitizer.sanitize(response.substring(6));
				}

			}

			Order order = new Order();

			if (fullName != null && serviceType != null && brand != null) {

				Customer customer = customerRepository.findByPhone(recipientNumber);

				if (customer == null) {
					throw new RuntimeException("Customer not found with phone number: " + recipientNumber);
				}

				List<Order> activeOrders = orderRepository.findAllByUserIdAndStatusId(customer.getId(), 2L);
				activeOrders.addAll(orderRepository.findAllByUserIdAndStatusId(customer.getId(), 5L));
				if (!activeOrders.isEmpty()) {
					sendTextMessage(recipientNumber,
							"You already have an active booking. Please complete or cancel your existing booking before making a new one.");
					saveOrUpdateChatMessage(recipientNumber, "Bot",
							"You already have an active booking. Please complete or cancel your existing booking before making a new one.");
					return;
				}

				customer = customerRepository.findByPhone(recipientNumber);

				Optional<Service> serviceOptional = serviceRepository.findById(24L);

				Address address1 = new Address();

				Optional<City> city = cityRepository.findByName(cites);
				City finalCity;
				if (city.isEmpty()) {
					City city1 = new City();
					city1.setName(cites);
					cityRepository.saveAndFlush(city1);
					finalCity = city1;
				} else {
					finalCity = city.get();
				}

				address1.setCity(finalCity);
				address1.setLongitude(address);
				address1.setLatitude(address);
				address1.setUserId(customer.getId());
				address1.setZipCode("ZIP");
				address1.setAddress(address);
				addressRepository.saveAndFlush(address1);

				Service service = serviceOptional.get();
				order.setCreatedByBot(1);
				order.setServiceId(27L);
				order.setUser(customer);
				order.setDate(Date.valueOf(LocalDate.parse(date, dateFormatter)));
				order.setTime(time);
				order.setStatus(statusRepository.findById(2L).get());
				Vehicle vehicle = new Vehicle();
				vehicle.setCreatedByBot(1);
				log.info(brand);
				vehicle.setBrand(brandRepository.findByName(brand).get());
				vehicle.setUserId(String.valueOf(customer.getId()));
				VehicleModel vehicleModel = null;
				if (vehicleModelRepository.findByName("N/A").isEmpty()) {
					vehicleModel = new VehicleModel();
					vehicleModel.setName("N/A");
					vehicleModel.setImage("");
					vehicleModel.setSlug("N/A");
					vehicleModel.setBrandId(Math.toIntExact(brandRepository.findByName(brand).get().getId()));
					vehicleModelRepository.saveAndFlush(vehicleModel);
				} else {
					vehicleModel = vehicleModelRepository.findByName("N/A").get();
				}
				vehicle.setVehicleModel(vehicleModel);

				vehicleRepository.saveAndFlush(vehicle);
				order.setTotalPrice(service.getPrice());

				order.setPaymentStatus("Cash on Delivery");
				order.setDevicePlatform("Android");
				order.setRequirePickup(1);
				order.setIsPaid(0);
				order.setAddress(address1);
				order.setDescription(description);
				orderRepository.save(order);
				try {

					sendTextMessage(recipientNumber,
							"Thank you! Your booking has been confirmed. Your Order reference number is "
									+ order.getId());
					saveOrUpdateChatMessage(recipientNumber, "Bot",
							"Thank you! Your booking has been confirmed. Your Order reference number is "
									+ order.getId());
					String googleMapsLink = "";
					if (location != null && location.startsWith("Location received: Latitude = ")) {
						log.info("Location: {}", location);
						String[] parts = location.split(",");
						if (parts.length == 2) {
							String latitude = parts[0].split(" = ")[1].trim();
							String longitude = parts[1].split(" = ")[1].trim();
							googleMapsLink = "Google Maps Link: https://www.google.com/maps/search/?api=1&query="
									+ latitude + "," + longitude;
						}
					}

					template.convertAndSend("/topic/notifications",
							new NotificationMessage("Order ID: " + order.getId()));

					for (String adminNumber : notificationNumberList) {
						sendTemplateMessageNewBooking(adminNumber, order.getId().toString(),
								service.getServiceTypeId().getName(), brand, "N/A", city.get().getStateId().getName(),
								city.get().getName(), address1.getAddress(), order.getDateAndTime(), customer.getName(),
								"+91" + contactPhoneNumber, service.getName(), googleMapsLink,
								order.getStatus().getTitle(), "Unpaid");
					}

					sendTemplateMessageNewBooking("+91" + customer.getPhone(), order.getId().toString(),
							service.getServiceTypeId().getName(), brand, "N/A", city.get().getStateId().getName(),
							city.get().getName(), address1.getAddress(), order.getDateAndTime(), customer.getName(),
							"+91" + contactPhoneNumber, service.getName(), googleMapsLink, order.getStatus().getTitle(),
							"Unpaid");

				} catch (Exception e) {
					sendTextMessage(recipientNumber, "There was an error saving your booking. Please try again.");
					saveOrUpdateChatMessage(recipientNumber, "Bot",
							"There was an error saving your booking. Please try again.");
					throw e;
				}

			} else {
				sendTextMessage(recipientNumber,
						"Sorry, I couldn't retrieve all the details of your booking. Please start over.");
				saveOrUpdateChatMessage(recipientNumber, "Bot",
						"Sorry, I couldn't retrieve all the details of your booking. Please start over.");
			}
		} else if ("no".equalsIgnoreCase(confirmation)) {
			sendTextMessage(recipientNumber,
					"Your booking has been cancelled. If you have any other requests, please let us know.");
			saveOrUpdateChatMessage(recipientNumber, "Bot",
					"Your booking has been cancelled. If you have any other requests, please let us know.");
		} else {
			sendTextMessage(recipientNumber, "Please type 'Yes' to confirm your booking or 'No' to cancel it.");
			saveOrUpdateChatMessage(recipientNumber, "Bot",
					"Please type 'Yes' to confirm your booking or 'No' to cancel it.");
		}
	}

	private void handle_NEWB_Confirmation(String recipientNumber, String confirmation) {
		if ("yes".equalsIgnoreCase(confirmation)) {

			List<UserResponse> userResponses = userResponseRepository.findByPhoneNumber(recipientNumber);
			String brand = null, serviceType = null, address = null, location = null, date = null, time = null,
					description = null, fullName = null, contactPhoneNumber = null, cites = null;
			userResponses.forEach(response -> log.info(response.getResponse()));

			for (UserResponse userResponse : userResponses) {
				String response = userResponse.getResponse();
				if (response.startsWith("Brand Selection: ")) {
					brand = InputSanitizer.sanitize(response.substring(17));
				} else if (response.startsWith("Address: ")) {
					address = InputSanitizer.sanitize(response.substring(9));
				} else if (response.startsWith("Full Name: ")) {
					fullName = InputSanitizer.sanitize(response.substring(11));
				} else if (response.startsWith("Contact Phone Number: ")) {
					contactPhoneNumber = InputSanitizer.sanitize(response.substring(21));
				} else if (response.startsWith("Problem Description: ")) {
					description = InputSanitizer.sanitize(response.substring(20));
				} else if (response.startsWith("Date Selection: ")) {
					date = InputSanitizer.sanitize(response.substring(16));
				} else if (response.startsWith("Time Selection: ")) {
					time = InputSanitizer.sanitize(response.substring(16));
				} else if (response.startsWith("Location: ")) {
					location = InputSanitizer.sanitize(response.substring(10));
				} else if (response.startsWith("City: ")) {
					cites = InputSanitizer.sanitize(response.substring(6));
				}

			}
			System.out.println("TESSSSSTTSTTTSTT:" + date + time);

			if (brand != null && fullName != null) {

				Customer customer = customerRepository.findByPhone(recipientNumber);

				if (customer == null) {
					throw new RuntimeException("Customer not found with phone number: " + recipientNumber);
				}

				List<Order> activeOrders = orderRepository.findAllByUserIdAndStatusId(customer.getId(), 2L);
				activeOrders.addAll(orderRepository.findAllByUserIdAndStatusId(customer.getId(), 2L));
				if (!activeOrders.isEmpty()) {
					sendTextMessage(recipientNumber,
							"You already have an active booking. Please complete or cancel your existing booking before making a new one.");
					saveOrUpdateChatMessage(recipientNumber, "Bot",
							"You already have an active booking. Please complete or cancel your existing booking before making a new one.");
					return;
				}

				customer = customerRepository.findByPhone(recipientNumber);

				Optional<Service> serviceOptional = serviceRepository.findById(24L);

				Service service = serviceOptional.get();

				Order order = new Order();
				order.setCreatedByBot(1);
				Address address1 = new Address();
				Optional<City> city = cityRepository.findByName(cites);
				City finalCity;
				if (city.isEmpty()) {
					City city1 = new City();
					city1.setName(cites);
					cityRepository.saveAndFlush(city1);
					finalCity = city1;
				} else {
					finalCity = city.get();
				}

				address1.setCity(finalCity);

				String googleMapsLink = "";
				if (location != null && location.startsWith("Location received: Latitude = ")) {
					String[] parts = location.split(",");
					if (parts.length == 2) {
						String latitude = parts[0].split(" = ")[1].trim();
						String longitude = parts[1].split(" = ")[1].trim();
						address1.setLatitude(latitude);
						address1.setLongitude(longitude);
						googleMapsLink = "Google Maps Link: https://www.google.com/maps/search/?api=1&query=" + latitude
								+ "," + longitude;
					}
				}
				address1.setUserId(customer.getId());
				address1.setAddress(address);
				address1.setZipCode("ZIP");

				addressRepository.saveAndFlush(address1);

				order.setServiceId(27L);
				order.setDate(Date.valueOf(LocalDate.parse(date, dateFormatter)));
				order.setTime(time);
				order.setAddress(address1);
				Vehicle vehicle = new Vehicle();
				vehicle.setCreatedByBot(1);
				log.info(brand);
				vehicle.setBrand(brandRepository.findByName(brand).get());
				vehicle.setUserId(String.valueOf(customer.getId()));
				VehicleModel vehicleModel = null;

				if (vehicleModelRepository.findByName("N/A").isEmpty()) {
					vehicleModel = new VehicleModel();
					vehicleModel.setName("N/A");
					vehicleModel.setImage("");
					vehicleModel.setSlug("N/A");
					vehicleModel.setBrandId(Math.toIntExact(brandRepository.findByName(brand).get().getId()));
					vehicleModelRepository.saveAndFlush(vehicleModel);
				} else {
					vehicleModel = vehicleModelRepository.findByName("N/A").get();
				}
				vehicle.setVehicleModel(vehicleModel);
				vehicleRepository.saveAndFlush(vehicle);

				order.setVehicle(vehicle);
				order.setUser(customer);
				order.setTotalPrice(service.getPrice());
				order.setPaymentStatus("Cash on Delivery");
				order.setDevicePlatform("Android");
				order.setRequirePickup(1);
				order.setIsPaid(0);
				order.setStatus(statusRepository.findById(2L).get());
				order.setDescription(description);
				log.info(String.valueOf(order));
				log.info(order.toString());
				orderRepository.saveAndFlush(order);

				try {
					sendTextMessage(recipientNumber,
							"Thank you! Your booking has been confirmed. Your Order Id is " + order.getId());

					template.convertAndSend("/topic/notifications",
							new NotificationMessage("Order ID: " + order.getId()));

					for (String adminNumber : notificationNumberList) {
						sendTemplateMessageNewBooking(adminNumber, order.getId().toString(), service.getName(), brand,
								"N/A", city.get().getStateId().getName(), city.get().getName(), address1.getAddress(),
								order.getDateAndTime(), customer.getName(), "+91" + contactPhoneNumber,
								order.getDescription(), googleMapsLink, order.getStatus().getTitle(), "Unpaid");
					}
					sendTemplateMessageNewBooking("+91" + customer.getPhone(), order.getId().toString(),
							service.getName(), brand, "N/A", city.get().getStateId().getName(), city.get().getName(),
							address1.getAddress(), order.getDateAndTime(), customer.getName(),
							"+91" + contactPhoneNumber, order.getDescription(), googleMapsLink,
							order.getStatus().getTitle(), "Unpaid");

					saveOrUpdateChatMessage(recipientNumber, "Bot",
							"Thank you! Your booking has been confirmed. Your Order Id is " + order.getId());
				} catch (Exception e) {
					sendTextMessage(recipientNumber, "There was an error saving your booking. Please try again.");
					saveOrUpdateChatMessage(recipientNumber, "Bot",
							"There was an error saving your booking. Please try again.");
					throw e;
				}
			} else {
				sendTextMessage(recipientNumber,
						"Sorry, I couldn't retrieve all the details of your booking. Please start over.");
				saveOrUpdateChatMessage(recipientNumber, "Bot",
						"Sorry, I couldn't retrieve all the details of your booking. Please start over.");
			}
		} else if ("no".equalsIgnoreCase(confirmation)) {
			sendTextMessage(recipientNumber,
					"Your booking has been cancelled. If you have any other requests, please let us know.");
			saveOrUpdateChatMessage(recipientNumber, "Bot",
					"Your booking has been cancelled. If you have any other requests, please let us know.");
		} else {
			sendTextMessage(recipientNumber, "Please type 'Yes' to confirm your booking or 'No' to cancel it.");
			saveOrUpdateChatMessage(recipientNumber, "Bot",
					"Please type 'Yes' to confirm your booking or 'No' to cancel it.");
		}
	}

	public static String convertToTimestamp(String dateSelection, String timeSelection) {

		dateSelection = dateSelection.trim();

		DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy");
		LocalDate date = LocalDate.parse(dateSelection, dateFormatter);

		String[] timeParts = timeSelection.split(" - ");
		String startTime = timeParts[0];
		String endTime = timeParts[1];

		DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("h:mm a");
		LocalTime startLocalTime = LocalTime.parse(startTime, timeFormatter);
		LocalTime endLocalTime = LocalTime.parse(endTime, timeFormatter);

		LocalDateTime startDateTime = LocalDateTime.of(date, startLocalTime);
		LocalDateTime endDateTime = LocalDateTime.of(date, endLocalTime);

		DateTimeFormatter dateOutputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
		DateTimeFormatter timeOutputFormatter = DateTimeFormatter.ofPattern("ha");

		String formattedDate = date.format(dateOutputFormatter);
		String startTimestamp = startDateTime.format(timeOutputFormatter);
		String endTimestamp = endDateTime.format(timeOutputFormatter);

		return formattedDate + " : " + startTimestamp + "-" + endTimestamp;
	}

	private String handleMainMenuSelection(String recipientNumber, String userMessage) {
		List<String> validOptions = Arrays.asList("📝 Quick Booking", "⚙ Services", "\uD83D\uDCBB Booking Management",
				"⏱ Service Status", "📄 Invoice", "\uD83D\uDCDE Help & Support", "\uD83D\uDCF2 Download our app",
				"🚨 Complaint");
		if (validOptions.contains(userMessage)) {
			switch (userMessage) {

			case "📝 Quick Booking":
				sendTextMessage(recipientNumber, "Awesome! Let's get started. Please provide the following details");
				sendTextMessage(recipientNumber, "Provide your Full Name");
				saveOrUpdateChatMessage(recipientNumber, "Bot", "Provide your Full Name");
				setConversationState(recipientNumber, "AWAITING_NEWB_FULLNAME");
				return ("AWAITING_NEWB_FULLNAME");
			case "⚙ Services":
				handle_SERVICES_ServiceTypeSelection(recipientNumber, userMessage);
				setConversationState(recipientNumber, "AWAITING_SERVICES_SERVICE_TYPE");
				return ("AWAITING_SERVICES_SERVICE_TYPE");

			case "\uD83D\uDCBB Booking Management":
				sendTextMessage(recipientNumber, "Please Select Booking management option");
				saveOrUpdateChatMessage(recipientNumber, "Bot", "Please Select Booking management option");
				sendQuickReplies(recipientNumber, Arrays.asList("Reschedule Booking", "Cancel Booking"));
				setConversationState(recipientNumber, "AWAITING_BOOKING_MANAGEMENT_SELECTION");
				return ("AWAITING_BOOKING_MANAGEMENT_SELECTION");

			case "📄 Invoice":

				sendTextMessage(recipientNumber, "Please Provide the booking Id");
				saveOrUpdateChatMessage(recipientNumber, "Bot", "Please Provide the booking Id");

				return ("AWAITING_INVOICE_ORDER_ID");

			case "\uD83D\uDCDE Help & Support":
				sendTextMessage(recipientNumber,
						"How can we assist you today? Please describe your issue or question?");
				// sendQuickReplies(recipientNumber, Arrays.asList("Reschedule Booking", "Cancel
				// Booking"));
				saveOrUpdateChatMessage(recipientNumber, "Bot",
						"How can we assist you today? Please describe your issue or question?");
				setConversationState(recipientNumber, "AWAITING_HELP_SUPPORT_DESCRIPTION");
				return ("AWAITING_HELP_SUPPORT_DESCRIPTION");

			case "\uD83D\uDCF2 Download our app":
				sendTextMessage(recipientNumber,
						"You can download our app for easier bookings and service management. Here are the links:\n"
								+ "\n"
								+ "📱 *Android*: [Download on Play Store](https://play.google.com/store/apps/details?id=com.bikefixup.mobile)\n"
								+ "🍏 *iOS*: [Download on App Store](https://apps.apple.com/in/app/bikefixup/id1665163967)\n"
								+ "\n" + "If you have any questions, feel free to ask!");

				saveOrUpdateChatMessage(recipientNumber, "Bot",
						"You can download our app for easier bookings and service management. Here are the links:\n"
								+ "\n"
								+ "📱 *Android*: [Download on Play Store](https://play.google.com/store/apps/details?id=com.bikefixup.mobile)\n"
								+ "🍏 *iOS*: [Download on App Store](https://apps.apple.com/in/app/bikefixup/id1665163967)\n"
								+ "\n" + "If you have any questions, feel free to ask!");
				setConversationState(recipientNumber, "AWAITING_MAIN_MENU_SELECTION");
				return "AWAITING_MAIN_MENU_SELECTION";

			case "🚨 Complaint":
				sendTextMessage(recipientNumber,
						"We're sorry to hear that you have a complaint. Please provide your booking ID related to the issue");
				// sendQuickReplies(recipientNumber, Arrays.asList("Reschedule Booking", "Cancel
				// Booking"));

				saveOrUpdateChatMessage(recipientNumber, "Bot",
						"We're sorry to hear that you have a complaint. Please provide your booking ID related to the issue");
				setConversationState(recipientNumber, "AWAITING_COMPLAINT_BOOKING_ID");
				return ("AWAITING_COMPLAINT_BOOKING_ID");

			case "⏱ Service Status":
				sendTextMessage(recipientNumber, getCustomerOrder(recipientNumber).toString());

				return ("AWAITING_MAIN_MENU_SELECTION");

			default:
				sendTextMessage(recipientNumber, "Feature coming soon!");
				saveOrUpdateChatMessage(recipientNumber, "Bot", "Feature coming soon!");

				setConversationState(recipientNumber, "AWAITING_MAIN_MENU_SELECTION");
				return ("AWAITING_MAIN_MENU_SELECTION");
			}
		} else {

			sendQuickReplies(recipientNumber, validOptions);
		}
		return ("AWAITING_MAIN_MENU_SELECTION");

	}

	private void handle_SERVICES_BrandSelection(String recipientNumber, String userMessage) {
		List<String> validBrands = Arrays.asList("Hero", "Honda", "TVS", "Royal Enfield", "Yamaha", "Suzuki", "Bajaj",
				"Other");
		if (validBrands.contains(userMessage)) {
			sendTextMessage(recipientNumber,
					"Our experienced mechanics know how to handle every important part of maintenance for your Bike. ✌");
			saveOrUpdateChatMessage(recipientNumber, "Bot", "Please choose a valid option from the menu.");
			sendQuickReplies(recipientNumber, Arrays.asList("General Services", "Special Request", "Repairing",
					"Body Parts", "Engine Work", "Other"));

		} else {
			sendTextMessage(recipientNumber, "Please choose a valid bike brand.");
			sendQuickReplies(recipientNumber, validBrands);
		}
	}

	private void handle_SERVICES_ServiceTypeSelection(String recipientNumber, String userMessage) {
		List<String> validServiceTypes = Arrays.asList("General Services", "Special Request", "Repairing", "Body Parts",
				"Engine Work", "Other");
		if (validServiceTypes.contains(userMessage)) {
			sendTextMessage(recipientNumber, "Can you please provide your Address?");
			saveOrUpdateChatMessage(recipientNumber, "Bot", "Can you please provide your Address?");

			setConversationState(recipientNumber, "AWAITING_Address");
		} else {
			sendTextMessage(recipientNumber, "Please choose a valid service type.");
			saveOrUpdateChatMessage(recipientNumber, "Bot", "Please choose a valid service type.");
			sendQuickReplies(recipientNumber, validServiceTypes);
		}
	}

	private void handle_NEWB_BrandSelection(String recipientNumber, String userMessage) {
		List<String> validBrands = Arrays.asList("Hero", "Honda", "TVS", "Royal Enfield", "Yamaha", "Suzuki", "Bajaj",
				"Other");
		if (validBrands.contains(userMessage)) {
			sendTextMessage(recipientNumber, "Please Describe the Problem with Your Vehicle?");
			saveOrUpdateChatMessage(recipientNumber, "Bot", "Please Describe the Problem with Your Vehicle?");

		} else {
			sendTextMessage(recipientNumber, "Please choose a valid bike brand.");
			saveOrUpdateChatMessage(recipientNumber, "Bot", "Please choose a valid bike brand.");
			sendQuickReplies(recipientNumber, validBrands);
		}
	}

	private String handleRescheduleOrCancel(String recipientNumber) {
		List<UserResponse> userResponses = userResponseRepository.findByPhoneNumber(recipientNumber);
		boolean isReschedule = false;
		boolean isCancel = false;

		if (userResponses != null) {
			for (UserResponse userResponse : userResponses) {
				String response = userResponse.getResponse();
				if (response != null && response.contains("Reschedule Booking")) {
					isReschedule = true;

					break;
				} else if (response != null && response.contains("Cancel Booking")) {
					isCancel = true;
					break;
				}
			}
		}

		if (isReschedule) {
			sendTextMessage(recipientNumber, "Could you please provide a preferred date for the service?");
			saveOrUpdateChatMessage(recipientNumber, "Bot",
					"Could you please provide a preferred date for the service?");

			List<String> dateOptions = generateDateOptions();
			sendQuickReplies(recipientNumber, dateOptions);
			return "AWAITING_BOOKING_MANAGEMENT_DATE_SELECTION";
		} else if (isCancel) {
			sendTextMessage(recipientNumber, "Please provide your cancellation reason:");
			saveOrUpdateChatMessage(recipientNumber, "Bot", "Please provide your cancellation reason:");
			sendQuickReplies(recipientNumber,
					Arrays.asList("Found another shop", "Unsatisfied with service", "Change of plans", "Emergency",
							"No longer needed", "Appointment conflict", "Financial constraints", "Vehicle sold", "Other"

					));
			return "AWAITING_BOOKING_MANAGEMENT_CANCELLATION_REASON";
		} else {
			sendTextMessage(recipientNumber, "Please type 'Exit' to start over.");
			saveOrUpdateChatMessage(recipientNumber, "Bot", "Please type 'Exit' to start over.");
			return "AWAITING_MAIN_MENU_SELECTION";
		}
	}

	public void sendTextMessage(String recipientNumber, String text) {
		try {
			Map<String, Object> payload = new HashMap<>();
			payload.put("messaging_product", "whatsapp");
			payload.put("recipient_type", "individual");
			payload.put("to", recipientNumber);
			payload.put("type", "text");
			payload.put("text", Map.of("body", text));

			sendMessage(payload);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void sendQuickReplies(String recipientNumber, List<String> options) {
		try {
			Map<String, Object> payload = new HashMap<>();
			payload.put("messaging_product", "whatsapp");
			payload.put("recipient_type", "individual");
			payload.put("to", recipientNumber);
			payload.put("type", "interactive");

			Map<String, Object> interactive = new HashMap<>();
			interactive.put("type", "list");

			Map<String, Object> body = new HashMap<>();
			body.put("text", "Please choose an option:");

			List<Map<String, Object>> sections = new ArrayList<>();
			Map<String, Object> section = new HashMap<>();
			section.put("title", "Options");
			List<Map<String, Object>> rows = new ArrayList<>();
			for (String option : options) {
				Map<String, Object> row = new HashMap<>();
				row.put("id", option);
				row.put("title", option);
				rows.add(row);
			}
			section.put("rows", rows);
			sections.add(section);

			interactive.put("body", body);
			interactive.put("action", Map.of("button", "Choose", "sections", sections));

			payload.put("interactive", interactive);

			sendMessage(payload);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void sendMessage(Map<String, Object> payload) {
		try {
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.APPLICATION_JSON);
			headers.setBearerAuth(WHATSAPP_API_TOKEN);

			HttpEntity<Map<String, Object>> entity = new HttpEntity<>(payload, headers);

			ResponseEntity<String> response = restTemplate.exchange(WHATSAPP_API_URL, HttpMethod.POST, entity,
					String.class);
			System.out.println("Message response : " + response);
			if (!response.getStatusCode().is2xxSuccessful()) {
				throw new HttpClientErrorException(response.getStatusCode(),
						"Failed to send message: " + response.getBody());
			}

			System.out.println("Message sent successfully: " + response.getBody());
		} catch (HttpClientErrorException e) {
			System.err.println("HTTP Error: " + e.getStatusCode() + " - " + e.getResponseBodyAsString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String getOrder(String orderId, String customerPhoneNumber) {

		try {

			Optional<Order> optionalOrder = orderRepository.findById(Long.valueOf(orderId));
			if (optionalOrder.isPresent()) {
				Order order = optionalOrder.get();

				Optional<Customer> optionalCustomer = Optional.of(order.getUser());
				;

				Customer cust = null;
				if (optionalCustomer.isPresent()) {

					cust = optionalCustomer.get();
				}

				if (cust.getPhone().equals(customerPhoneNumber)) {
					sendTextMessage(customerPhoneNumber, "Could you please Check the details of booking and Proceed");
					return formatOrderDetails(order);
				} else {
					return "Forbidden: Phone number doesn't match.";
				}
			} else {
				return "Order not found.";
			}
		} catch (NumberFormatException e) {
			return "Invalid order ID format.";
		}

	}

	private String formatOrderDetails(Order order) {
		StringBuilder summary = new StringBuilder("Here are the details you've provided:\n");
		summary.append("Order ID: ").append("#" + order.getId()).append("\n");

		summary.append("Customer ID: ").append(order.getUser().getId()).append("\n");
		Optional<Customer> optionalCustomer = Optional.of(order.getUser());

		Customer cust = null;
		if (optionalCustomer.isPresent()) {

			cust = optionalCustomer.get();
		}

		summary.append("Customer Name: ").append(cust.getName()).append("\n");

		summary.append("Customer Phone Number: ").append(cust.getPhone()).append("\n");

		summary.append("Status: ").append(order.getStatus2()).append("\n");
		summary.append("Brand: ").append(order.getVehicle().getBrand().getName()).append("\n");
		summary.append("City: ").append(order.getAddress().getCity().getName()).append("\n");

		summary.append("Description: ").append(order.getDescription()).append("\n");

		Optional<Service> optionalService = serviceRepository.findById(Long.valueOf(order.getServiceId()));

		Service service = null;
		if (optionalService.isPresent()) {

			service = optionalService.get();

		}

		summary.append("Service Type: ").append(service.getServiceTypeId().getName()).append("\n");
		summary.append("Service Description: ").append(service.getDescription()).append("\n");

		summary.append("Address: ").append(order.getAddress().getStreet()).append("\n");
		summary.append("Preferred Date and Time: ").append(order.getDateAndTime()).append("\n");

		summary.append("Full Name: ").append(cust.getName()).append("\n");
		summary.append("Contact Phone Number: ").append(cust.getPhone()).append("\n");
		summary.append("Creation Date: ").append(order.getCreatedAt()).append("\n");
		summary.append("Completion Date: ").append(order.getUpdatedAt() != null ? order.getUpdatedAt() : "N/A")
				.append("\n");
		return summary.toString();
	}

	@Autowired
	private ChatMessageRepository chatMessageRepository;

	private void saveOrUpdateChatMessage(String phoneNumber, String sender, String message) {

		ChatMessage existingChatMessage = chatMessageRepository.findByPhoneNumberAndSender(phoneNumber, sender);

		if (existingChatMessage == null) {

			existingChatMessage = new ChatMessage();
			existingChatMessage.setPhoneNumber(phoneNumber);
		}

		existingChatMessage.setSender(sender);
		existingChatMessage.setMessage(message);
		existingChatMessage.setTimestamp(LocalDateTime.now());

		chatMessageRepository.save(existingChatMessage);
	}

	public String getCustomerOrder(String recipient) {
		try {

			Optional<Customer> optionalCustomer = Optional.ofNullable(customerRepository.findByPhone(recipient));

			if (optionalCustomer.isPresent()) {
				Customer customer = optionalCustomer.get();
				List<Order> orders = orderRepository.findByUserIdOrderByCreatedAtDesc(String.valueOf(customer.getId()));

				if (!orders.isEmpty()) {
					return formatOrderResponse(orders);
				} else {
					return "You have no bookings.";
				}
			} else {
				return "Customer not found.";
			}
		} catch (NumberFormatException e) {
			return "Invalid phone number format.";
		}
	}

	public String getCustomerInvoice(String orderId, String recipientNumber) {
		try {
			Optional<Order> optionalOrder = orderRepository.findById(Long.valueOf(orderId));
			if (optionalOrder.isPresent()) {
				Order order = optionalOrder.get();
				Optional<Customer> optionalCustomer = Optional.of(order.getUser());

				if (optionalCustomer.isPresent()) {
					Customer customer = optionalCustomer.get();
					if (customer.getPhone().equals(recipientNumber)) {
						Optional<Invoice> optionalInvoice = invoiceRepository.findByOrderId(order.getId());
						if (optionalInvoice.isPresent()) {
							Invoice invoice = optionalInvoice.get();

							if ("disabled".equalsIgnoreCase(invoice.getStatus())) {
								String message = "Invoice not found, please contact support 8607880788";
								sendTextMessage(recipientNumber, message);
								return "AWAITING_INVOICE_ORDER_ID";
							}

							String formattedMessage = formatInvoiceResponse(invoice);
							sendMessageInvoice(recipientNumber, formattedMessage);
							sendTextMessage(recipientNumber, "Send hi to start new conversation");
							return "AWAITING_MAIN_MENU_SELECTION";
						} else {
							String message = "Invoice not found, please contact support 8607880788";
							sendTextMessage(recipientNumber, message);
							return "AWAITING_INVOICE_ORDER_ID";
						}
					} else {
						String message = "Phone number doesn't match.";
						sendTextMessage(recipientNumber, message);
						sendTextMessage(recipientNumber, "Please provide the right booking ID again");
						return "AWAITING_INVOICE_ORDER_ID";
					}
				} else {
					String message = "Customer not found.";
					sendTextMessage(recipientNumber, message);
					sendTextMessage(recipientNumber, "Please provide the right booking ID again");
					return "AWAITING_INVOICE_ORDER_ID";
				}
			} else {
				String message = "Order not found.";
				sendTextMessage(recipientNumber, message);
				sendTextMessage(recipientNumber, "Please provide the right booking ID again");
				return "AWAITING_INVOICE_ORDER_ID";
			}
		} catch (NumberFormatException e) {
			String message = "Invalid order format.";
			sendTextMessage(recipientNumber, message);
			sendTextMessage(recipientNumber, "Please provide the right booking ID again");
			return "AWAITING_INVOICE_ORDER_ID";
		}
	}

	public String getCustomerComplaint(String orderId, String recipientNumber) {
		try {
			Optional<Order> optionalOrder = orderRepository.findById(Long.valueOf(orderId));
			if (optionalOrder.isPresent()) {
				Order order = optionalOrder.get();
				Optional<Customer> optionalCustomer = Optional.of(order.getUser());

				if (optionalCustomer.isPresent()) {
					Customer customer = optionalCustomer.get();
					if (customer.getPhone().equals(recipientNumber)) {

						sendTextMessage(recipientNumber, " Thank you. Please describe the issue you experienced.");
						saveOrUpdateChatMessage(recipientNumber, "Bot",
								" Thank you. Please describe the issue you experienced.");

						return "AWAITING_COMPLAINT_DESCRIPTION";

					} else {
						String message = "Phone number doesn't match.";
						sendTextMessage(recipientNumber, message);
						sendTextMessage(recipientNumber, "Please Provide the right booking Id again");
						return "AWAITING_COMPLAINT_BOOKING_ID";
					}
				} else {
					String message = "Customer not found.";
					sendTextMessage(recipientNumber, message);
					sendTextMessage(recipientNumber, "Please Provide the right booking Id again");
					return "AWAITING_COMPLAINT_BOOKING_ID";
				}
			} else {
				String message = "Order not found.";
				sendTextMessage(recipientNumber, message);
				sendTextMessage(recipientNumber, "Please Provide the right booking Id again");
				return "AWAITING_COMPLAINT_BOOKING_ID";
			}
		} catch (NumberFormatException e) {
			String message = "Invalid order format.";
			sendTextMessage(recipientNumber, message);
			sendTextMessage(recipientNumber, "Please Provide the right booking Id again");
			return "AWAITING_COMPLAINT_BOOKING_ID";
		}
	}

	private String formatInvoiceResponse(Invoice invoice) {
		StringBuilder invoiceDetails = new StringBuilder();
		invoiceDetails.append("Invoice Details:\n").append("Invoice ID: ").append(invoice.getId()).append("\n")
				.append("Order ID: ").append(invoice.getOrder().getId()).append("\n").append("Created At: ")
				.append(invoice.getCreatedAt()).append("\n").append("Updated At: ").append(invoice.getUpdatedAt())
				.append("\n").append("View Invoice: ").append(baseUrl).append(invoice.getUrl());
		return invoiceDetails.toString();
	}

	private static void sendMessageInvoice(String recipientNumber, String messageText) {
		try {
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.APPLICATION_JSON);
			headers.setBearerAuth(WHATSAPP_API_TOKEN);

			Map<String, Object> message = new HashMap<>();
			message.put("messaging_product", "whatsapp");
			message.put("to", recipientNumber);
			message.put("type", "text");

			Map<String, Object> text = new HashMap<>();
			text.put("preview_url", true);
			text.put("body", messageText);

			message.put("text", text);

			HttpEntity<Map<String, Object>> entity = new HttpEntity<>(message, headers);

			ResponseEntity<String> response = restTemplate.exchange(WHATSAPP_API_URL, HttpMethod.POST, entity,
					String.class);

			if (!response.getStatusCode().is2xxSuccessful()) {
				throw new HttpClientErrorException(response.getStatusCode(),
						"Failed to send message: " + response.getBody());
			}

			System.out.println("Message sent successfully: " + response.getBody());
		} catch (HttpClientErrorException e) {
			System.err.println("HTTP Error: " + e.getStatusCode() + " - " + e.getResponseBodyAsString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private String formatOrderResponse(List<Order> orders) {
		StringBuilder response = new StringBuilder("Your bookings:\n\n");

		for (Order order : orders) {
			Optional<Service> optionalService = serviceRepository.findById(order.getServiceId());
			Service service = optionalService.orElse(null);

			if (service == null) {
				response.append("Order ID: ").append("#").append(order.getId()).append("\n").append("Service Name: ")
						.append("Service not found").append("\n").append("Description: ")
						.append(order.getDescription() != null ? order.getDescription() : "N/A").append("\n")
						.append("Date and Time: ").append(order.getDateAndTime()).append("\n").append("Status: ")
						.append(order.getStatus2()).append("\n").append("Visit Charge: ").append(order.getTotalPrice())
						.append("\n").append("\n----------------------\n\n");
			} else {
				response.append("Order ID: ").append("#").append(order.getId()).append("\n").append("Service Name: ")
						.append(service.getName()).append("\n").append("Description: ")
						.append(order.getDescription() != null ? order.getDescription() : "N/A").append("\n")
						.append("Date and Time: ").append(order.getDateAndTime()).append("\n").append("Status: ")
						.append(order.getStatus2()).append("\n").append("Visit Charge: ").append(order.getTotalPrice())
						.append("\n").append("\n----------------------\n\n");
			}
		}
		return response.toString();
	}

	private String handle_Save_Help_Support(String recipientNumber, String description) {

		HelpSupport help_Support = new HelpSupport();
		help_Support.setPhoneNumber(recipientNumber);
		help_Support.setDescription(InputSanitizer.sanitize(description));
		help_Support.setCreationDate(new Timestamp(System.currentTimeMillis()));

		try {
			helpSupportRepository.save(help_Support);
			sendTextMessage(recipientNumber,
					"Thank you for your message. Our support team will review your issue and get back to you as soon as possible.\n \n");
			saveOrUpdateChatMessage(recipientNumber, "Bot",
					"Thank you for your message. Our support team will review your issue and get back to you as soon as possible.\n \n ");

			sendTextMessage(recipientNumber, "For immediate assistance, you can also reach us at:\n"
					+ "- Email: contact@bikefixup.in\n" + "- Phone: 8607880788");
		} catch (Exception e) {
			sendTextMessage(recipientNumber, "There was an error saving your Complaint. Please try again.");
			saveOrUpdateChatMessage(recipientNumber, "Bot",
					"There was an error saving your Complaint. Please try again.");
		}

		return "AWAITING_MAIN_MENU_SELECTION";
	}

	private String handle_Save_Complaint(String recipientNumber, String description) {

		List<UserResponse> userResponses = userResponseRepository.findByPhoneNumber(recipientNumber);
		String orderId = null;

		for (UserResponse userResponse : userResponses) {
			String response = userResponse.getResponse();
			System.out.println("Processing response: " + response);
			if (response.startsWith("Booking Id: ")) {
				orderId = InputSanitizer.sanitize(response.substring(12));
				System.out.println("Extracted orderId: " + orderId);
			}
		}
		String sanitizedDescription = InputSanitizer.sanitize(description);

		if (orderId != null && description != null) {

			Complaint complaint = new Complaint();
			complaint.setOrderId(orderId);
			complaint.setPhoneNumber(recipientNumber);
			complaint.setDescription(sanitizedDescription);
			complaint.setCreationDate(new Timestamp(System.currentTimeMillis()));

			try {
				complaintRepository.save(complaint);
				sendTextMessage(recipientNumber,
						"We're sorry for the inconvenience caused. Our support team will review your complaint and get back to you as soon as possible.");
				sendTextMessage(recipientNumber, "For immediate assistance, you can also reach us at:\n"
						+ "- Email: contact@bikefixup.in\n" + "- Phone: 8607880788");

				saveOrUpdateChatMessage(recipientNumber, "Bot", "For immediate assistance, you can also reach us at:\n"
						+ "- Email: contact@bikefixup.in\n" + "- Phone: 8607880788");
			} catch (Exception e) {
				sendTextMessage(recipientNumber, "There was an error saving your Complaint. Please try again.");
				saveOrUpdateChatMessage(recipientNumber, "Bot",
						"There was an error saving your Complaint. Please try again.");
			}
		} else {
			sendTextMessage(recipientNumber,
					"Sorry, I couldn't retrieve all the details of your Complaint. Please start over.");
			saveOrUpdateChatMessage(recipientNumber, "Bot",
					"Sorry, I couldn't retrieve all the details of your Complaint. Please start over.");
		}
		return "AWAITING_MAIN_MENU_SELECTION";
	}

	void sendMessage1(Map<String, Object> payload) {
		try {
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.APPLICATION_JSON);
			headers.setBearerAuth(WHATSAPP_API_TOKEN);

			HttpEntity<Map<String, Object>> entity = new HttpEntity<>(payload, headers);

			ResponseEntity<String> response = restTemplate.exchange(WHATSAPP_API_URL, HttpMethod.POST, entity,
					String.class);

			if (!response.getStatusCode().is2xxSuccessful()) {
				throw new HttpClientErrorException(response.getStatusCode(),
						"Failed to send message: " + response.getBody());
			}

			System.out.println("Message sent successfully: " + response.getBody());
		} catch (HttpClientErrorException e) {
			System.err.println("HTTP Error: " + e.getStatusCode() + " - " + e.getResponseBodyAsString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private Map<String, Object> createLocationRequestPayload(String toPhoneNumber, String bodyText) {
		Map<String, Object> payload = new HashMap<>();
		payload.put("messaging_product", "whatsapp");
		payload.put("recipient_type", "individual");
		payload.put("type", "interactive");
		payload.put("to", toPhoneNumber);

		Map<String, Object> interactive = new HashMap<>();
		interactive.put("type", "location_request_message");

		Map<String, Object> body = new HashMap<>();
		body.put("text", bodyText);
		interactive.put("body", body);

		Map<String, Object> action = new HashMap<>();
		action.put("name", "send_location");
		interactive.put("action", action);

		payload.put("interactive", interactive);

		return payload;
	}

	private static boolean isNullOrEmpty(String str) {
		return str == null || str.trim().isEmpty();
	}

	public static void sendTemplateMessageNewBooking(String recipientNumber, String bookingId, String serviceType,
			String brand, String model, String state, String city, String address, String dateTime, String customerName,
			String customerPhone, String description, String googleMapsLink, String status, String paymentStatus) {
		try {

			bookingId = isNullOrEmpty(bookingId) ? "N/A" : bookingId;
			serviceType = isNullOrEmpty(serviceType) ? "N/A" : serviceType;
			brand = isNullOrEmpty(brand) ? "N/A" : brand;
			city = isNullOrEmpty(city) ? "N/A" : city;
			dateTime = isNullOrEmpty(dateTime) ? "N/A" : dateTime;
			customerName = isNullOrEmpty(customerName) ? "N/A" : customerName;
			customerPhone = isNullOrEmpty(customerPhone) ? "N/A" : customerPhone;
			description = isNullOrEmpty(description) ? "N/A" : description;
			address = isNullOrEmpty(address) ? "N/A" : address;
			googleMapsLink = isNullOrEmpty(googleMapsLink) ? "https://maps.google.com" : googleMapsLink;
			status = isNullOrEmpty(status) ? "N/A" : status;
			model = isNullOrEmpty(model) ? "N/A" : model;
			state = isNullOrEmpty(state) ? "N/A" : state;
			paymentStatus = isNullOrEmpty(paymentStatus) ? "N/A" : paymentStatus;

			Map<String, Object> payload = new HashMap<>();
			payload.put("messaging_product", "whatsapp");
			payload.put("to", recipientNumber);
			payload.put("type", "template");
			payload.put("template", Map.of("name", "newbooking1", "language", Map.of("code", "en_US"), "components",
					new Object[] { Map.of("type", "HEADER", "parameters", new Object[] {
//							Map.of("type", "image", "image", Map.of("link", baseUrl+"/images/confirmed.jpg"))
							Map.of("type", "image", "image",
									Map.of("link", "https://i.ibb.co/TB5HBNMQ/confirmed.jpg")) }),
							Map.of("type", "BODY", "parameters", new Object[] {
									Map.of("type", "text", "text", bookingId),
									Map.of("type", "text", "text", serviceType), Map.of("type", "text", "text", brand),
									Map.of("type", "text", "text", model), Map.of("type", "text", "text", state),
									Map.of("type", "text", "text", city), Map.of("type", "text", "text", address),
									Map.of("type", "text", "text", dateTime),
									Map.of("type", "text", "text", customerName),
									Map.of("type", "text", "text", customerPhone),
									Map.of("type", "text", "text", description),
									Map.of("type", "text", "text", googleMapsLink),
									Map.of("type", "text", "text", status),
									Map.of("type", "text", "text", paymentStatus) }) }));

			sendMessageNewBooking(payload);
		} catch (Exception e) {
			throw new RuntimeException();
//            e.printStackTrace();
		}
	}

	public static void sendMessageNewBooking(Map<String, Object> payload) {
		try {
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.APPLICATION_JSON);
			headers.setBearerAuth(WHATSAPP_API_TOKEN);

			HttpEntity<Map<String, Object>> entity = new HttpEntity<>(payload, headers);

			ResponseEntity<String> response = restTemplate.exchange(WHATSAPP_API_URL, HttpMethod.POST, entity,
					String.class);

			if (!response.getStatusCode().is2xxSuccessful()) {
				throw new HttpClientErrorException(response.getStatusCode(),
						"Failed to send message: " + response.getBody());
			}

			System.out.println("Message sent successfully: " + response.getBody());
		} catch (HttpClientErrorException e) {
			System.err.println("HTTP Error: " + e.getStatusCode() + " - " + e.getResponseBodyAsString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void sendTemplateMessageRescheduled(String recipientNumber, String bookingId, String serviceType,
			String brand, String model, String state, String city, String address, String dateTime, String customerName,
			String customerPhone, String description, String googleMapsLink, String status) {
		try {

			bookingId = isNullOrEmpty(bookingId) ? "N/A" : bookingId;
			serviceType = isNullOrEmpty(serviceType) ? "N/A" : serviceType;
			brand = isNullOrEmpty(brand) ? "N/A" : brand;
			city = isNullOrEmpty(city) ? "N/A" : city;
			dateTime = isNullOrEmpty(dateTime) ? "N/A" : dateTime;
			customerName = isNullOrEmpty(customerName) ? "N/A" : customerName;
			customerPhone = isNullOrEmpty(customerPhone) ? "N/A" : customerPhone;
			description = isNullOrEmpty(description) ? "N/A" : description;
			address = isNullOrEmpty(address) ? "N/A" : address;
			googleMapsLink = isNullOrEmpty(googleMapsLink) ? "https://maps.google.com" : googleMapsLink;
			status = isNullOrEmpty(status) ? "N/A" : status;
			state = isNullOrEmpty(state) ? "N/A" : state;
			model = isNullOrEmpty(model) ? "N/A" : model;

			Map<String, Object> payload = new HashMap<>();
			payload.put("messaging_product", "whatsapp");
			payload.put("to", recipientNumber);
			payload.put("type", "template");
			payload.put("template", Map.of("name", "rescheduledbooking1", "language", Map.of("code", "en_US"),
					"components",
					new Object[] {
							Map.of("type", "header", "parameters",
									new Object[] { Map.of("type", "image", "image",
											Map.of("link", baseUrl + "/images/rescheduled.jpg")) }),
							Map.of("type", "body", "parameters", new Object[] {
									Map.of("type", "text", "text", bookingId),
									Map.of("type", "text", "text", serviceType), Map.of("type", "text", "text", brand),
									Map.of("type", "text", "text", model), Map.of("type", "text", "text", state),
									Map.of("type", "text", "text", city), Map.of("type", "text", "text", address),
									Map.of("type", "text", "text", dateTime),
									Map.of("type", "text", "text", customerName),
									Map.of("type", "text", "text", customerPhone),
									Map.of("type", "text", "text", description),
									Map.of("type", "text", "text", googleMapsLink),
									Map.of("type", "text", "text", status) }) }));

			sendMessageNewBooking(payload);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void sendTemplateMessageCanceled(String recipientNumber, String bookingId, String serviceType,
			String brand, String model, String state, String city, String address, String dateTime, String customerName,
			String customerPhone, String description, String googleMapsLink, String status, String cancellationReason) {
		try {

			bookingId = isNullOrEmpty(bookingId) ? "N/A" : bookingId;
			serviceType = isNullOrEmpty(serviceType) ? "N/A" : serviceType;
			brand = isNullOrEmpty(brand) ? "N/A" : brand;
			city = isNullOrEmpty(city) ? "N/A" : city;
			dateTime = isNullOrEmpty(dateTime) ? "N/A" : dateTime;
			customerName = isNullOrEmpty(customerName) ? "N/A" : customerName;
			customerPhone = isNullOrEmpty(customerPhone) ? "N/A" : customerPhone;
			description = isNullOrEmpty(description) ? "N/A" : description;
			address = isNullOrEmpty(address) ? "N/A" : address;
			googleMapsLink = isNullOrEmpty(googleMapsLink) ? "https://maps.google.com" : googleMapsLink;
			status = isNullOrEmpty(status) ? "N/A" : status;
			cancellationReason = isNullOrEmpty(status) ? "N/A" : cancellationReason;
			state = isNullOrEmpty(state) ? "N/A" : state;

			Map<String, Object> payload = new HashMap<>();
			payload.put("messaging_product", "whatsapp");
			payload.put("to", recipientNumber);
			payload.put("type", "template");
			payload.put("template",
					Map.of("name", "cancelbooking1", "language", Map.of("code", "en_US"), "components", new Object[] {
							Map.of("type", "header", "parameters",
									new Object[] { Map.of("type", "image", "image",
											Map.of("link", baseUrl + "/images/cancelled.jpg")) }),
							Map.of("type", "body", "parameters", new Object[] {
									Map.of("type", "text", "text", bookingId),
									Map.of("type", "text", "text", serviceType), Map.of("type", "text", "text", brand),
									Map.of("type", "text", "text", model), Map.of("type", "text", "text", state),
									Map.of("type", "text", "text", city), Map.of("type", "text", "text", address),
									Map.of("type", "text", "text", dateTime),
									Map.of("type", "text", "text", customerName),
									Map.of("type", "text", "text", customerPhone),
									Map.of("type", "text", "text", description),
									Map.of("type", "text", "text", googleMapsLink),
									Map.of("type", "text", "text", status),
									Map.of("type", "text", "text", cancellationReason) }) }));

			sendMessageNewBooking(payload);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void sendTemplateMessageThankyou(String recipientNumber, String bookingId, String serviceType,
			String amount) {
		try {

			bookingId = isNullOrEmpty(bookingId) ? "N/A" : bookingId;
			serviceType = isNullOrEmpty(serviceType) ? "N/A" : serviceType;
			amount = isNullOrEmpty(amount) ? "N/A" : amount;

			Map<String, Object> payload = new HashMap<>();
			payload.put("messaging_product", "whatsapp");
			payload.put("to", recipientNumber);
			payload.put("type", "template");
			payload.put("template",
					Map.of("name", "paymentthankyou1", "language", Map.of("code", "en_US"), "components",
							new Object[] {
									Map.of("type", "header", "parameters",
											new Object[] { Map.of("type", "image", "image",
													Map.of("link", baseUrl + "/images/thankyou.png")) }),
									Map.of("type", "body", "parameters",
											new Object[] { Map.of("type", "text", "text", serviceType),
													Map.of("type", "text", "text", bookingId),
													Map.of("type", "text", "text", amount),

											}) }));

			sendMessageNewBooking(payload);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void sendTemplateMessagePaymentReceived(String recipientNumber, String bookingId, String serviceType,
			String amount, String contact) {
		try {
			bookingId = isNullOrEmpty(bookingId) ? "N/A" : bookingId;
			serviceType = isNullOrEmpty(serviceType) ? "N/A" : serviceType;
			amount = isNullOrEmpty(amount) ? "N/A" : amount;
			contact = isNullOrEmpty(contact) ? "N/A" : contact;

			Map<String, Object> payload = new HashMap<>();
			payload.put("messaging_product", "whatsapp");
			payload.put("to", recipientNumber);
			payload.put("type", "template");
			payload.put("template",
					Map.of("name", "paymentreceived1", "language", Map.of("code", "en_US"), "components", new Object[] {
							Map.of("type", "header", "parameters",
									new Object[] { Map.of("type", "image", "image",
											Map.of("link", baseUrl + "/images/paid.jpg")) }),
							Map.of("type", "body", "parameters", new Object[] {

									Map.of("type", "text", "text", serviceType),
									Map.of("type", "text", "text", bookingId), Map.of("type", "text", "text", amount),
									Map.of("type", "text", "text", contact),

							}) }));

			sendMessageNewBooking(payload);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void sendReminderMessageTemplate(String recipientNumber, String bookingId, String serviceType,
			String amount, String contact, String paymentUrl) {
		try {
			bookingId = isNullOrEmpty(bookingId) ? "N/A" : bookingId;
			serviceType = isNullOrEmpty(serviceType) ? "N/A" : serviceType;
			amount = isNullOrEmpty(amount) ? "N/A" : amount;
			contact = isNullOrEmpty(contact) ? "N/A" : contact;

			Map<String, Object> payload = new HashMap<>();
			payload.put("messaging_product", "whatsapp");
			payload.put("to", recipientNumber);
			payload.put("type", "template");
			payload.put("template",
					Map.of("name", "payment_reminder", "language", Map.of("code", "en_US"), "components",
							new Object[] {
									Map.of("type", "header", "parameters",
											new Object[] { Map.of("type", "image", "image",
													Map.of("link", baseUrl + "/images/reminder.jpg")) }),
									Map.of("type", "body", "parameters",
											new Object[] { Map.of("type", "text", "text", serviceType),
													Map.of("type", "text", "text", bookingId),
													Map.of("type", "text", "text", amount),
													Map.of("type", "text", "text", contact) }),
									Map.of("type", "button", "sub_type", "url", "index", "0", "parameters",
											new Object[] { Map.of("type", "text", "text", "Pay Now"),
													Map.of("type", "url", "text", paymentUrl) }) }));

			sendMessageNewBooking(payload);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}