package com.hepl.tunefortwo.service.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.stream.Collectors;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ResponseStatusException;

import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import com.hepl.tunefortwo.config.exceptions.FieldException;
import com.hepl.tunefortwo.dto.FormRequestDto;
import com.hepl.tunefortwo.dto.FormRequestDtoCoAdmin;
import com.hepl.tunefortwo.dto.IsMandatory;
import com.hepl.tunefortwo.dto.OrderPosition;
import com.hepl.tunefortwo.dto.OrderTrackerDto;
import com.hepl.tunefortwo.entity.FileType;
import com.hepl.tunefortwo.entity.Filed;
import com.hepl.tunefortwo.entity.Form;
import com.hepl.tunefortwo.mapper.FormMapper;
import com.hepl.tunefortwo.repository.FiledRepository;
import com.hepl.tunefortwo.repository.FormRepository;
import com.hepl.tunefortwo.service.FileService;
import com.hepl.tunefortwo.service.FormService;
import com.hepl.tunefortwo.service.MailService;
import com.hepl.tunefortwo.service.MasterPaymentService;
import com.hepl.tunefortwo.service.OtpService;
import com.hepl.tunefortwo.service.TemplateService;
import com.hepl.tunefortwo.utils.AppMessages;

import jakarta.mail.MessagingException;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class FormServiceImpl implements FormService {
  
	private final FormRepository formRepository;
    private final FormMapper formMapper;
    private final MailService mailService;
	private final TemplateService templateService;
	private final FiledRepository filedRepository;
	private final FileServiceImpl fileServiceImpl;
	private final FileService fileService;
	private final PhoneNumberUtil phoneNumberUtil;
	private final OtpService otpService;
	
    private final String Pending_Stage = "Pending in stage of ";
    private final String Delivered_Stage = "Delivered! Song sent to your email";
    private static final Logger logger = LoggerFactory.getLogger(FormService.class);
    @Value("${baseUrl.orderTracker}")
    public String trackorderLink;
    @Autowired
    private MongoTemplate mongoTemplate;

	
    public FormServiceImpl(FormRepository formRepository, FormMapper formMapper
    	,	MailService mailService,TemplateService templateService, FileServiceImpl fileServiceImpl, FiledRepository filedRepository, FileService fileService, PhoneNumberUtil phoneNumberUtil,OtpService otpService ) {
		this.formRepository = formRepository;
		this.formMapper = formMapper;
		this.templateService = templateService;
		this.mailService = mailService;
		this.fileServiceImpl = fileServiceImpl;
		this.filedRepository = filedRepository ;
		this.fileService = fileService;
		this.phoneNumberUtil = phoneNumberUtil;
		this.otpService = otpService;
	}
    @Override
    public Form saveForm(FormRequestDto form) throws MessagingException {
    	Boolean name ,mail,phoneNumber, language, artist ,instrument,
    	mood , songto, songfrom, occasion, story, clips, mixing , deliveyDate = false, selectedlanguageamount,selectedinstrumentamount,selecteddeliverydateamount,selectedmasterrequestamount ;
        log.info("Form service");
        Form data = new Form();
        List<Filed> filed = filedRepository.findAll();	
        List<String> filedNames = filed.stream()
        		.map(x->x.getName()).collect(Collectors.toList());
        Map<String , String > map = new HashMap<>();
        map.put("name", "Name");
        map.put("mail", "Email id");
        map.put("phoneNumber", "Mobile Number");
        map.put("language", "Language");
        map.put("instrument", "Instrument");
        map.put("artist", "Artist");
        map.put("mood", "Mood");
        map.put("songto", "Who is the song to ?");
        map.put("songfrom", "Who is the song  from ?");
        map.put("occasion", "What is the Occasion ?");
        map.put("story", "Tell us your story");
        map.put("clips", "Record your story audio");
        map.put("Mixing", "Select an mixing mastering");
        //map.put("deliveyDate", "Song Delivery");
           
        name = validate(map.get("name"), form.getName());
        mail = validate(map.get("mail"), form.getMail());
        phoneNumber = validate(map.get("phoneNumber"), form.getPhonenumber());
        language = validate(map.get("language"),form.getLanuage());
        artist = validate(map.get("artist"), form.getArtist());
        instrument = validate(map.get("instrument"), form.getInstrument());
        mood = validate(map.get("mood"), form.getMood());
        songto = validate(map.get("songto"), form.getSongto());
        songfrom = validate(map.get("songfrom"), form.getSongfrom());
        occasion = validate(map.get("songfrom"), form.getOccasion());
        story = validate(map.get("story"), form.getStory());
        clips = validate(map.get("clips"), form.getClipPath());
        mixing = validate(map.get("Mixing"), form.getMasterRequest()==null? "" :form.getMasterRequest().toString());
        //deliveyDate = validate(map.get("deliveyDate"), form.getDeliveryDate()==null? "":form.getDeliveryDate().toString());
        if(!otpService.isEmailVerified(form.getMail())) {
			throw new MessagingException("Email Not Verified");
		}
        System.out.println("name "+name.toString());
        data.setName(form.getName());
        data.setMail(form.getMail());
        data.setPhonenumber(form.getPhonenumber());
        data.setLanuage(form.getLanuage());
        data.setArtist(form.getArtist());
        data.setInstrument(form.getInstrument());
        data.setMood(form.getMood());
        data.setSongto(form.getSongto());
        data.setSongfrom(form.getSongfrom());
        data.setOccasion(form.getOccasion());
        data.setStory(form.getStory());
        data.setClipPath(form.getClipPath());
        data.setOrderTotal(form.getOrderTotal());

        List<OrderTrackerDto> orderTrackerDtos = new ArrayList<>();
        OrderTrackerDto orderTrackerDto = new OrderTrackerDto();
        orderTrackerDto.setOrderPosition(OrderPosition.ORDER_SAVED.toString());
        String orderNumberString = getNextOrderNumber();
        System.out.println(orderNumberString);
        orderTrackerDto.setOrderNumber(orderNumberString);
        orderTrackerDto.setUpdatedDate(LocalDateTime.now());
        orderTrackerDtos.add(orderTrackerDto);
        data.setOrderPosition(orderTrackerDtos);
        data.setCustomerDeliveryDate(form.getCustomerDeliveryDate());
        data.setOrderNumber(orderNumberString);
        data.setStatus(OrderPosition.ORDER_SAVED.toString());
        data.setClipDuration(form.getClipDuration());
        data.setMixtureMaster(form.getMasterRequest() == null ? "" : form.getMasterRequest().toString());
        data.setDurationInMMSS(form.getDurationInMMSS());

//        data.setDeliveryDate(form.getCustomerDeliveryDate());

        Map<String, String> errors = new HashMap<>();


        if (name) {
            errors.put("Name", AppMessages.NAME_REQUIRED);
        }
        if (mail) {
            errors.put("Mail", AppMessages.MAIL_REQUIRED);
        }
        if (phoneNumber) {
            errors.put("Phonenumber", AppMessages.PHONENUMBER_REQUIRED);
        }
        if (language) {
            errors.put("Language", AppMessages.LANGUAGE_REQUIRED);
        }
        if (artist) {
            errors.put("Artist", AppMessages.ARTIST_REQUIRED);
        }
        if (instrument) {
            errors.put("Instrument", AppMessages.INSTRUMENT_REQUIRED);
        }
        if (mood) {
            errors.put("Mood", AppMessages.MOOD_REQUIRED);
        }
        if (songto) {
            errors.put("Songto", AppMessages.SONGTO_REQUIRED);
        }
        if (songfrom) {
            errors.put("Songfrom", AppMessages.SONGFROM_REQUIRED);
        }
        if (occasion) {
            errors.put("Occasion", AppMessages.OCCASION_REQUIRED);
        }
        if (story) {
            errors.put("Story", AppMessages.STORY_REQUIRED);
        }
        if (clips) {
            errors.put("Clips", AppMessages.CLIPS_REQUIRED);
        }
        if (mixing) {
            errors.put("Mixing", AppMessages.MIXING_REQUIRED);
        }
//        if (deliveryDate) {
//            errors.put("DeliveryDate", AppMessages.DELIVERYDATE_REQUIRED);
//        }

        if (!errors.isEmpty()) {
            throw new FieldException("", errors);
        }

        // Uncomment if mail service is required
        // mailService.sendMailByTemplate(templateService.getAccountSetupTemlate(form.getName()), form.getMail(), "Order Confirmed");

        return formRepository.save(data);
    }

    private boolean validate(String filed, String dto) {
        Filed filedName = filedRepository.findByName(filed);
        System.out.println("hi = " + filedName.getIsMandatory());
        if (filedName.getIsMandatory().equals(IsMandatory.Mandatory.toString())) {
            return dto == null || dto.isEmpty();
        }
        return false;
    }

    private String getNextOrderNumber() {
        Optional<Form> formOptional = formRepository.findFirstByOrderByCreatedDateDesc();
        String lastOrderNumber = formOptional.map(Form::getOrderNumber).orElse(null);
        log.info("Form service getNextOrderNumber ");
        if (lastOrderNumber != null) {
            String numericPart = lastOrderNumber.substring(2);
            int incrementedValue = Integer.parseInt(numericPart) + 1;
            return "MS" + incrementedValue;
        } else {
            return "MS1";
        }
    }
    @Override
    public Map<String, Object> allForms(Pageable pageable, boolean isAdmin, String query) {
    	
    	if(isAdmin) {
    	if (query != null && !query.isEmpty()) {
            // Create regex search term
            String regexSearchTerm = ".*" + query + ".*";

            // Define the search criteria
            Criteria criteria = new Criteria().orOperator(
                Criteria.where("name").regex(regexSearchTerm, "i"),
                Criteria.where("mail").regex(regexSearchTerm, "i"),
                Criteria.where("phonenumber").regex(regexSearchTerm, "i"),
                Criteria.where("orderNumber").regex(regexSearchTerm, "i")
                // Add more fields if necessary
            );

            // Define the aggregation pipeline
            Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.project()
                    .and("_id").as("id")
                    .and("name").as("name")
                    .and("mail").as("mail")
                    .and("phonenumber").as("phonenumber")
                    .and("instrument").as("instrument")
                    .and("mood").as("mood")
                    .and("lanuage").as("lanuage")
                    .and("artist").as("artist")
                    .and("songto").as("songto")
                    .and("songfrom").as("songfrom")
                    .and("occasion").as("occasion")
                    .and("story").as("story")
                    .and("clipPath").as("clipPath")
                    .and("adminClipPath").as("adminClipPath")
                    .and("clipDuration").as("clipDuration")
                    .and("status").as("status")
                    .and("orderNumber").as("orderNumber")
                    .and("mixtureMaster").as("mixtureMaster")
                    .and("comments").as("comments")
                    .and("orderPosition").as("orderPosition")
                    .and("createdDate").as("createdDate")
                    .and("customerDeliveryDate").as("customerDeliveryDate")
                    .and("review").as("review")
                    .and("rating").as("rating")
                    .and("images").as("images")
                    .and("video").as("video")
                    .and("deliveryDate").as("deliveryDate")
                    .and("durationInMMSS").as("durationInMMSS")
                    .and("orderTotal").as("orderTotal")
                    .and("activeStatus").as("activeStatus")
                    .and("paymentId").as("paymentId")
            );

            // Execute the aggregation
            AggregationResults<Form> results = mongoTemplate.aggregate(aggregation, "Form", Form.class);
            List<Form> forms = results.getMappedResults();

            // Handle pagination
            int start = (int) pageable.getOffset();
            int end = Math.min(start + pageable.getPageSize(), forms.size());
            List<Form> pagedForms = forms.subList(start, end);

            // Map to DTOs and create response
            Map<String, Object> result = new HashMap<>();
            if (isAdmin) {
                List<FormRequestDto> allForms = pagedForms.stream()
                    .map(formMapper::toDto)
                    .collect(Collectors.toList());
                result.put("forms", allForms);
            } else {
                List<FormRequestDtoCoAdmin> allForms = pagedForms.stream()
                    .map(formMapper::toDtoCoAdmin)
                    .collect(Collectors.toList());
                result.put("forms", allForms);
            }
            result.put("totalElements", forms.size());

            return result;
        } 
    	}
    	if(!isAdmin) {
    	if (query != null && !query.isEmpty() && !isAdmin) {
            // Create regex search term
            String regexSearchTerm = ".*" + query + ".*";

            // Define the search criteria
            Criteria criteria = new Criteria().orOperator(
                Criteria.where("name").regex(regexSearchTerm, "i"),
//                Criteria.where("mail").regex(regexSearchTerm, "i"),
//                Criteria.where("phonenumber").regex(regexSearchTerm, "i"),
                Criteria.where("orderNumber").regex(regexSearchTerm, "i")
                // Add more fields if necessary
            );

            // Define the aggregation pipeline
            Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.project()
                    .and("_id").as("id")
                    .and("name").as("name")
                    .and("mail").as("mail")
                    .and("phonenumber").as("phonenumber")
                    .and("instrument").as("instrument")
                    .and("mood").as("mood")
                    .and("lanuage").as("lanuage")
                    .and("artist").as("artist")
                    .and("songto").as("songto")
                    .and("songfrom").as("songfrom")
                    .and("occasion").as("occasion")
                    .and("story").as("story")
                    .and("clipPath").as("clipPath")
                    .and("adminClipPath").as("adminClipPath")
                    .and("clipDuration").as("clipDuration")
                    .and("status").as("status")
                    .and("orderNumber").as("orderNumber")
                    .and("mixtureMaster").as("mixtureMaster")
                    .and("comments").as("comments")
                    .and("orderPosition").as("orderPosition")
                    .and("createdDate").as("createdDate")
                    .and("customerDeliveryDate").as("customerDeliveryDate")
                    .and("review").as("review")
                    .and("rating").as("rating")
                    .and("images").as("images")
                    .and("video").as("video")
                    .and("deliveryDate").as("deliveryDate")
                    .and("durationInMMSS").as("durationInMMSS")
                    .and("orderTotal").as("orderTotal")
                    .and("activeStatus").as("activeStatus")
                    .and("paymentId").as("paymentId")
            );

            // Execute the aggregation
            AggregationResults<Form> results = mongoTemplate.aggregate(aggregation, "Form", Form.class);
            List<Form> forms = results.getMappedResults();

            // Handle pagination
            int start = (int) pageable.getOffset();
            int end = Math.min(start + pageable.getPageSize(), forms.size());
            List<Form> pagedForms = forms.subList(start, end);

            // Map to DTOs and create response
            Map<String, Object> result = new HashMap<>();
            if (isAdmin) {
                List<FormRequestDto> allForms = pagedForms.stream()
                    .map(formMapper::toDto)
                    .collect(Collectors.toList());
                result.put("forms", allForms);
            } else {
                List<FormRequestDtoCoAdmin> allForms = pagedForms.stream()
                    .map(formMapper::toDtoCoAdmin)
                    .collect(Collectors.toList());
                result.put("forms", allForms);
            }
            result.put("totalElements", forms.size());

            return result;
        }
    	}
    	
        log.info("Get all forms");
        List<Form> totalForms = formRepository.findAll();
    	int totalCount = totalForms.size();
        if (isAdmin) {
//            if (pageable.isEmpty()) {
//                List<FormRequestDto> allForms = formRepository.findAll(pageable).stream()
//                        .map(formMapper::toDto)
//                        .collect(Collectors.toList());
//                
//                int count = allForms.size();
//                Map<String, Object> result = new HashMap<>();
//                result.put("forms", allForms);
//                result.put("totalElements", count);
//                return result;
//            } else {
//                List<FormRequestDto> allFormsElse = formRepository.findAllByTextSearch(query, sort).stream()
//                        .map(formMapper::toDto)
//                        .collect(Collectors.toList());
//                
//                int count = allFormsElse.size();
//                Map<String, Object> resultElse = new HashMap<>();
//                resultElse.put("forms", allFormsElse);
//                resultElse.put("totalElements", count);
//                return resultElse;
        	
        	 List<FormRequestDto> allForms = formRepository.findAll(pageable).stream()
                     .map(formMapper::toDto)
                     .collect(Collectors.toList());
             
             int count = allForms.size();
             Map<String, Object> result = new HashMap<>();
             result.put("forms", allForms);
             result.put("totalElements", totalCount);
             return result;
//            }
        } else {
//            if (query.isEmpty()) {
//                List<FormRequestDtoCoAdmin> allForms = formRepository.findAll(sort).stream()
//                        .map(formMapper::toDtoCoAdmin)
//                        .collect(Collectors.toList());
//                
//                int count = allForms.size();
//                Map<String, Object> resultForCoAdmin = new HashMap<>();
//                resultForCoAdmin.put("forms", allForms);
//                resultForCoAdmin.put("totalElements", count);
//                return resultForCoAdmin;
//            } else {
//                List<FormRequestDtoCoAdmin> allFormsElse = formRepository.findAllByTextSearch(query, sort).stream()
//                        .map(formMapper::toDtoCoAdmin)
//                        .collect(Collectors.toList());
//                
//                int count = allFormsElse.size();
//                Map<String, Object> resultElseForCoAdmin = new HashMap<>();
//                resultElseForCoAdmin.put("forms", allFormsElse);
//                resultElseForCoAdmin.put("totalElements", count);
//                return resultElseForCoAdmin;
        	 List<FormRequestDtoCoAdmin> allForms = formRepository.findAll(pageable).stream()
                     .map(formMapper::toDtoCoAdmin)
                     .collect(Collectors.toList());
             
             int count = allForms.size();
             Map<String, Object> resultForCoAdmin = new HashMap<>();
             resultForCoAdmin.put("forms", allForms);
             resultForCoAdmin.put("totalElements", totalCount);
             return resultForCoAdmin;
//            }
        }
    }



	
	@Override
	public FormRequestDto getFormById(String id) {
		log.info("Get  form by : "+ id);
		Form optionalForm = formRepository.findById(id)
				.orElseThrow(()->new ResponseStatusException(HttpStatus.NOT_FOUND,
						AppMessages.SONG_NOT_FOUND+ "with ID: " + id));
			return formMapper.toDto(optionalForm);
		
	}
	 
	@Override
	public Map<String, Object> getFormsByOrderPosition(OrderPosition position, Sort sort,boolean isAdmin) {
        log.info("Get all forms by OrderPosition");
        List<Form> forms = formRepository.findFormsByLastOrderPosition(position.toString(), sort);
        if(isAdmin == true) {
        List<FormRequestDto> formDtos = forms.stream()
                .map(formMapper::toDto)
                .collect(Collectors.toList());
        int count = formDtos.size();
        
        Map<String, Object> result = new HashMap<>();
        result.put("forms", formDtos);
        result.put("count", count);
        return result;
        }
        else {
        	List<FormRequestDtoCoAdmin> formDtos = forms.stream()
                    .map(formMapper::toDtoCoAdmin)
                    .collect(Collectors.toList());
            int count = formDtos.size();
            
            Map<String, Object> result = new HashMap<>();
            result.put("forms", formDtos);
            result.put("count", count);
            return result;
        	
        }
    }
    
	@Override

	public String updateOrderPosition(OrderPosition orderPosition, String id, String filePath) throws MessagingException {

	    log.info("Update the orderPostion By id = " + id);
	    Optional<Form> optionalForm = formRepository.findById(id);
	    if (optionalForm.isPresent()) {
	        Form form = optionalForm.get();

//	        List<OrderTrackerDto> currentOrderPositions = form.getOrderPosition();
//	        if (currentOrderPositions == null) {
//	            currentOrderPositions = new ArrayList<>();
//	        }
//	        currentOrderPositions.stream()
//            .limit(currentOrderPositions.size())
//            .forEach(dto -> dto.setComments("confirmed"));
	        
	        List<OrderTrackerDto> currentOrderPositions = form.getOrderPosition();
	        if (currentOrderPositions == null) {
	            currentOrderPositions = new ArrayList<>();
	        }
	        OrderPosition lastOrderPosition = null;
	        if (!currentOrderPositions.isEmpty()) {
	            OrderTrackerDto lastOrderTracker = currentOrderPositions.get(currentOrderPositions.size() - 1);
	            lastOrderPosition = OrderPosition.valueOf(lastOrderTracker.getOrderPosition());
	        }
 
	       
	        if (lastOrderPosition != null && !isValidTransition(lastOrderPosition, orderPosition)) {
	            throw new MessagingException("Invalid transition from " + lastOrderPosition + " to " + orderPosition);
	        }
 
	        for (int i = 0; i < currentOrderPositions.size(); i++) {
	            OrderTrackerDto dto = currentOrderPositions.get(i);
	            
	            if (dto.getOrderPosition().equals(orderPosition.toString())) {
	                throw new MessagingException("Order position already present: " + orderPosition.toString());
	            }
	            
//	            String previousComment = Pending_Stage + dto.getOrderPosition();
//	            log.info("Dynamic comments --------------------------------------------------" + previousComment);
//	            log.info("Old Comments --------------------------------------------------" + dto.getComments());
//	            
//	            
//	            if (i == currentOrderPositions.size() - 1 && dto.getComments().equals(previousComment)) {
//	                log.info("Updating comments to Success");
//	                dto.setComments("Success");
//	            }
	        }
    
//	        currentOrderPositions.setComments("order pending in - " + orderTrackingDto.getOrderPosition());
//    orderTrackingList.add(orderTrackingDto);
	        
	        OrderTrackerDto orderTrackerDto = new OrderTrackerDto();
	        orderTrackerDto.setOrderPosition(orderPosition.toString());
	        orderTrackerDto.setUpdatedDate(LocalDateTime.now());
	        if(!orderPosition.toString().equals(OrderPosition.DELIVERED.toString())) {
	        	orderTrackerDto.setComments(Pending_Stage + orderPosition);	
	        }
	       
//	        if(orderPosition.toString().equals(OrderPosition.DELIVERED.toString())) {
//	        	orderTrackerDto.setComments(Delivered_Stage);
//	        }
	        orderTrackerDto.setOrderNumber(form.getOrderNumber());

	        currentOrderPositions.add(orderTrackerDto);
	        form.setOrderPosition(currentOrderPositions);
	        form.setStatus(orderPosition.toString());
	        
	        System.out.println("Implementation: formdata" + form.getStatus());
	        if (filePath != null ) {
	            form.setAdminClipPath(filePath);
	        }
	        String songTitle = form.getAdminClipPath().replaceAll("^\\d+-", ""); 

	        Form updatedForm = formRepository.save(form);

	        log.info("OrderPosition updated successfully for id = {}", id);
	        LocalDate dateForDeliveryEmail = null;
	        
	      

	        if (orderPosition == OrderPosition.DELIVERED) {
	        	Optional<Form> optionalFormForDeliveryDate = formRepository.findById(id);
	    	    if (optionalFormForDeliveryDate.isPresent()) {
	    	        Form formForDeliveryDate = optionalFormForDeliveryDate.get();
	        	
	    	        LocalDateTime currentDateTime = LocalDateTime.now();
	    	        
	    	        LocalDate currentDate = currentDateTime.toLocalDate();
	    	        
	    	        Date deliveryDate = new Date(); // Replace with your actual date

	    	        // Convert Date to LocalDate
	    	        LocalDate localDate = deliveryDate.toInstant()
	    	                                          .atZone(ZoneId.systemDefault())
	    	                                          .toLocalDate();

	    	        // Add one day
	    	        LocalDate nextDay = localDate.plusDays(1);

	    	        // Convert LocalDate back to Date
	    	        Date updatedDeliveryDate = Date.from(nextDay.atStartOfDay(ZoneId.systemDefault()).toInstant());
	    	        
	    	        formForDeliveryDate.setDeliveryDate(deliveryDate);
	    	        Form savedData = formRepository.save(formForDeliveryDate);
	    	        logger.debug("Saved  : {}", savedData);
	    	    }
	    	    dateForDeliveryEmail= LocalDate.now();
	            String deliverySongPath = MailServiceImpl.BACKEND_BASE_URL + filePath;
	            String reviewLink = MailServiceImpl.FRONTEND_BASE_URL + "#/addReview/" + id;
	            mailService.sendMailByTemplate(
	                templateService.getOrderConfirmTemplate(deliverySongPath, reviewLink,form.getOrderNumber(),form.getName(),form.getArtist(),form.getInstrument(),form.getCreatedDate().toLocalDate(),songTitle,dateForDeliveryEmail), 
	                form.getMail(), 
	                "Order Delivery Email"
	            );
	        }

	        return updatedForm.getStatus();
	    } 
	        
	   
	    else {

	        throw new ResponseStatusException(HttpStatus.NOT_FOUND, AppMessages.SONG_NOT_FOUND + " with ID: " + id);
	    }
	}
 
	
	@Override
	public void updateForm(FormRequestDto dto , String id) throws IOException, MessagingException {
		log.info("Update the form By id = "+id);
		Form optionalForm = formRepository.findById(id)
				.orElseThrow(()->new ResponseStatusException(HttpStatus.NOT_FOUND,
						AppMessages.SONG_NOT_FOUND+ "with ID: " + id));
		if(dto.getName()!=null) {
		optionalForm.setName(dto.getName());
		}
		if(dto.getPhonenumber()!=null) {
		optionalForm.setPhonenumber(dto.getPhonenumber());
		}
		
		optionalForm.setMail(dto.getMail());
		optionalForm.setLanuage(dto.getLanuage());
		if(dto.getArtist()!=null) {
		optionalForm.setArtist(dto.getArtist());
		}
		if(dto.getInstrument()!=null) {
		optionalForm.setInstrument(dto.getInstrument());
		}
		if(dto.getMood()!=null) {
		optionalForm.setMood(dto.getMood());
		}
		if(dto.getSongto()!=null) {
		optionalForm.setSongto(dto.getSongto());
		}
		if(dto.getSongfrom()!=null) {
		optionalForm.setSongfrom(dto.getSongfrom());
		}
		if(dto.getOccasion()!=null) {
		optionalForm.setOccasion(dto.getOccasion());
		}
		if(dto.getStory()!=null) {
		optionalForm.setStory(dto.getStory());
		}
		if(dto.getOrderTotal()!=null) {
			optionalForm.setOrderTotal(dto.getOrderTotal());
		}
		if(dto.getClip()!=null) {
			  String originalFilename = dto.getClip().getOriginalFilename();
              if (originalFilename != null) {
                  String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
                  List<String> allowedExtensions = Arrays.asList("mp3", "wav","OGG","AAC");
                  if (!allowedExtensions.contains(fileExtension.toLowerCase())) {
                      throw new MessagingException("Only MP3,AAC, and WAV files are allowed");
                  }
              }
           
     	String filename=fileService.uploadFile(dto.getClip() , FileType.CLIP);
     	Resource file = fileService.loadAsResource(filename, FileType.CLIP);
        dto.setClipPath(filename);    
        Path filePath = Paths.get(file.getURI());
		optionalForm.setClipPath(fileServiceImpl.uploadFile(dto.getClip(),FileType.CLIP));
		
		}
		if(dto.getClipDuration() !=null) {
			 
	           long durationRoundOne = (long)Math.floor(dto.getClipDuration());
	           long inMinutes = durationRoundOne/60;
	           long inSeconds = durationRoundOne%60;
	           String inFormattedTime = String.format("%02d:%02d", inMinutes, inSeconds);
	           optionalForm.setClipDuration(dto.getClipDuration());
	           optionalForm.setDurationInMMSS(inFormattedTime);
		}
		if(dto.getMasterRequest()!=null) {
		optionalForm.setMixtureMaster(dto.getMasterRequest().toString());
		}
		if(dto.getCustomerDeliveryDate()!=null) {
			optionalForm.setCustomerDeliveryDate(dto.getCustomerDeliveryDate());
		}

//        optionalForm.setDeliveryDate(dto.getDeliveryDate());	

		formRepository.save(optionalForm);
	}
	
//	@Override
//    public List<OrderTrackerDto> trackerOrder(String number, String orderId){
//        log.info("track order : "+ number);
//        Form phone = formRepository.findByPhonenumber(number)
//        		.orElseThrow(()-> new ResponseStatusException(HttpStatus.NOT_FOUND,AppMessages.MOBILE_NUMBER_NOT_FOUND));
//        Form order = formRepository.findByOrderNumber(orderId)
//        		.orElseThrow(()-> new ResponseStatusException(HttpStatus.NOT_FOUND,AppMessages.ORDER_NUMBER_NOT_FOUND));
//        Map<String , String  > mapForTracker = new HashMap<>();
//        int length = order.getOrderNumber().length();
//        mapForTracker.put("OrderNumber",formRepository.findOrderPositionByPhonenumberAndOrderNumber(number, orderId).toString());
//        mapForTracker.put("Comment",order.getComments());
//        mapForTracker.put("UpdatedDate",order.getCreatedDate().toString());       
//        return formRepository.findOrderPositionByPhonenumberAndOrderNumber(number, orderId);
//    } 
	@Override
	public List<Object> trackerOrder(String number, String orderId) {
	    log.info("Track order: " + number);

	    Form order = formRepository.findByPhonenumberAndOrderNumber(number, orderId)
        .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, AppMessages.ORDER_NUMBER_NOT_FOUND));
	    List<Object> orderPositions = formRepository.findOrderPositionByPhonenumberAndOrderNumber(number, orderId);
        System.out.println(orderPositions.toString());
	    if (orderPositions.isEmpty()) {
	        throw new ResponseStatusException(HttpStatus.NOT_FOUND, AppMessages.MOBILE_NUMBER_NOT_FOUND);
	    }
	    return orderPositions;
	}


    private boolean isValidInput(String number, String orderId) {
        return !StringUtils.isEmpty(number) && !StringUtils.isEmpty(orderId);
    }
	
    @Override
    public void addScreenShot (String orderId , String path) {
    	Form formDetails = formRepository.findByOrderNumber(orderId).orElseThrow(()->new ResponseStatusException(HttpStatus.NOT_FOUND,
				AppMessages.SONG_NOT_FOUND+ "with OrderNumber: " + orderId));
    	formDetails.setScreenshot(path);
    	formRepository.save(formDetails);
    	
    }
    
    @Override
    public void addcomment (String orderId , String comment , LocalDate deliveryDate,String orderNumber) throws MessagingException {
//    	System.out.println("admininput"+comment+"orderNumber"+orderId+"adminDeliveryDate"+deliveryDate);
    	LocalDate dateForConfirmationEmail =null;
//    	String trackorderLink = "https://tunefor2.com/trackOrder/";
    	Form formDetails = formRepository.findByOrderNumber(orderId).orElseThrow(()->new ResponseStatusException(HttpStatus.NOT_FOUND,
				AppMessages.SONG_NOT_FOUND+ "with OrderNumber: " + orderId));
    	System.out.println("queryresult" + (formDetails.getId() != null ? formDetails.getId() : ""));

    	//formDetails.setComments(comment);
    	if(deliveryDate==null ) {
    		dateForConfirmationEmail= formDetails.getCustomerDeliveryDate();
    	}else {
    		dateForConfirmationEmail = deliveryDate;
    	}
//    	formDetails.setDeliveryDate(deliveryDate);
    	//formDetails.setOrderNumber(orderNumber);
//    	formDetails.setOrderPosition(Collections.singletonList(OrderPosition.ORDER_CONFIRMED.toString()));
    	List<OrderTrackerDto> currentOrderPositions = formDetails.getOrderPosition();
    	OrderTrackerDto lastOrderPosition = currentOrderPositions.get(currentOrderPositions.size() - 1);
    	String deliveredPosition = lastOrderPosition.getOrderPosition();
    	
    	if(comment != null && comment !="") {
    		lastOrderPosition.setComments(comment);
    	} else
    		if(!lastOrderPosition.getOrderPosition().equals(OrderPosition.DELIVERED.toString())) {
    			lastOrderPosition.setComments(Pending_Stage + lastOrderPosition.getOrderPosition().toString().replace("_", " "));
    		}
			
    	if (deliveredPosition.equals(OrderPosition.DELIVERED.toString())) {
    		
    		String finalComment = lastOrderPosition.getComments();
//    		if (!finalComment.isEmpty()) {
//    		    finalComment += System.lineSeparator();
//    		    finalComment += Delivered_Stage;
//    		}
//    		finalComment = Delivered_Stage;
    		if (finalComment == null) {
    		    finalComment = Delivered_Stage; // Assign Delivered_Stage if finalComment is null
    		} else if (finalComment.isEmpty()) {
    		    finalComment = Delivered_Stage; // Assign Delivered_Stage if finalComment is empty
    		} else {
    		    finalComment += System.lineSeparator();
    		    finalComment += Delivered_Stage; // Append Delivered_Stage if finalComment is not empty
    		}


    	    lastOrderPosition.setComments(finalComment);
    	}

    	
//    	List<OrderTrackerDto> orderTrackerDtos = new ArrayList<>();
//    	OrderTrackerDto orderTrackerDto = new OrderTrackerDto();
//	    orderTrackerDto.setOrderPosition(OrderPosition.ORDER_CONFIRMED.toString());
//	    orderTrackerDto.setUpdatedDate(LocalDateTime.now());
//	    orderTrackerDto.setComments(Pending_Stage + OrderPosition.ORDER_CONFIRMED.toString());
//	    orderTrackerDto.setOrderNumber(formDetails.getOrderNumber());
//	    orderTrackerDtos.add(orderTrackerDto);
//    	formDetails.setOrderPosition(orderTrackerDtos);
    	System.out.println("appendedcomment" + (formDetails.getComments() != null ? formDetails.getComments() : ""));
     	formRepository.save(formDetails);
    	if (deliveredPosition.equals(OrderPosition.ORDER_CONFIRMED.toString())) {
    			mailService.sendMailByTemplate(templateService.getAccountSetupTemlate(formDetails.getName(),formDetails.getCreatedDate().toLocalDate(),formDetails.getArtist(),formDetails.getInstrument(),dateForConfirmationEmail,orderNumber,trackorderLink+formDetails.getId()), formDetails.getMail(), "Order Confirmed");
    	}
    }
    	
    	
//    @Override
//    public void updateRatingAndReview(int rating, String review, String id,String video,String image) {
//        Form formDetails = formRepository.findById(id)
//                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,
//                        AppMessages.SONG_NOT_FOUND + " with ID: " + id));
//        formDetails.setRating(rating);
//        formDetails.setReview(review);
//        formDetails.setVideo(video);
//        formDetails.setImage(image);
//        formRepository.save(formDetails);
//    }
    @Override
    public void updateRatingAndReview(int rating, String review, String id,List<String> image,String video) {
        Form formDetails = formRepository.findById(id)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,
                        AppMessages.SONG_NOT_FOUND + " with ID: " + id));
        formDetails.setRating(rating);
        formDetails.setReview(review);
        formDetails.setVideo(video);
        if(image!=null && image.size() > 0) {
        	
        	formDetails.setImages(image);
        	}
        
        formRepository.save(formDetails);
    }
    
	@Override
	public void addReview(String orderId, String summary, int star, String image, String video) {
		// TODO Auto-generated method stub		
	}
//	@Override
//	public FormRequestDto getByOrderNumber(String orderNumber) {
//		
//		System.out.println("formservice Implementation start---"+orderNumber);
//		 Form order = formRepository.findByOrderNumber(orderNumber)
//				 .orElseThrow(()->new ResponseStatusException(HttpStatus.NOT_FOUND,
//							AppMessages.SONG_NOT_FOUND+ "with orderNumber: " + orderNumber));
//				return formMapper.toDto(order);
//	
//	}
//	@Override
//	public int updateComment(String orderId, String comment, LocalDate deliveryDate) throws MessagingException {
//		System.out.println("admininput"+comment+"orderNumber"+orderId+"adminDeliveryDate"+deliveryDate);
//    
//    	 int result=formRepository.updateCommentsAndDeliveryDateByOrderNumber(comment, deliveryDate, orderId);
//		return result;
//	}
	@Override
	public FormRequestDto getRatingandReview( String id) {
		log.info("Get  RatingandReview by : "+ id);
		Form optionalForm = formRepository.findById(id)
				.orElseThrow(()->new ResponseStatusException(HttpStatus.NOT_FOUND,
						AppMessages.SONG_NOT_FOUND+ "with ID: " + id));
		
			return formMapper.toDto(optionalForm);
		
	}
	@Override
	public boolean isValidTransition(OrderPosition currentOrderPosition, OrderPosition newOrderPosition) {
	    switch (currentOrderPosition) {
	        case ORDER_SAVED:
	            return newOrderPosition == OrderPosition.ORDER_CONFIRMED;
	        case ORDER_CONFIRMED:
	            return newOrderPosition == OrderPosition.SONG_COMPOSING;
	        case SONG_COMPOSING:
	            return newOrderPosition == OrderPosition.SONG_RECORDING;
	        case SONG_RECORDING:
	            return newOrderPosition == OrderPosition.DELIVERED;
	        case DELIVERED:
	         
	            return false;
	        default:
	            return false;
	    }
	}
	
	@Override
	public FormRequestDto rejectAFormByItsId(String id, String activestatus) {
		
		log.info("Reject form By id = "+id);
		Form formTobeRejectOrUpdated = formRepository.findById(id)
				.orElseThrow(()->new ResponseStatusException(HttpStatus.NOT_FOUND,
						AppMessages.SONG_NOT_FOUND+ "with ID: " + id));
		
		formTobeRejectOrUpdated.setActiveStatus(activestatus);
		if("inactive".equals(activestatus)) {
			formTobeRejectOrUpdated.setStatus("REJECTED");
		}
		if("active".equals(activestatus)) {
			formTobeRejectOrUpdated.setStatus(OrderPosition.ORDER_SAVED.toString());
		}
		formRepository.save(formTobeRejectOrUpdated);
		
		FormRequestDto optionalFormUpdated = formMapper.toDto(formTobeRejectOrUpdated);
		return optionalFormUpdated;
	}
	@Override
	public Map<String,Object> getAllRejectedForms(String activestatus) {
	    
	    List<Form> activeOrInactiveForms = formRepository.findByActiveStatus(activestatus);

	    
	    if (activeOrInactiveForms.isEmpty()) {
	       
	        throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Forms not found for the given status");
	    }

	    
	    
	    List<FormRequestDto>allAvailableForms = activeOrInactiveForms.stream()
	            .map(formMapper::toDto)
	            .collect(Collectors.toList());
	     int newCount = allAvailableForms.size();
	     Map<String, Object> result = new HashMap<>();
	        result.put("forms", allAvailableForms);
	        result.put("count", newCount);
	        return result;
	}
	@Override
	public void exportToExcel(LocalDate startDate, LocalDate endDate, OutputStream outputStream) throws IOException {
//		List<Form> forms = formRepository.findByCreatedDateBetween(startDate, endDate);
//	    Workbook workbook = new XSSFWorkbook();
//	    Sheet sheet = workbook.createSheet("Forms");
//
//	    // Create header row
//	    Row headerRow = sheet.createRow(0);
//	    String[] headers = {"ID", "Name", "Mail", "Phone Number", "Instrument", "Mood", "Language", "Artist", "Song To", "Song From", "Occasion", "Story", "Clip Path", "Admin Clip Path", "Clip Duration", "Status", "Order Number", "Mixture Master", "Comments", "Screenshot", "Order Position", "Created Date", "Customer Delivery Date", "Review", "Rating", "Images", "Video", "Delivery Date", "Duration In MMSS", "Order Total", "Active Status"};
//	    for (int i = 0; i < headers.length; i++) {
//	        Cell cell = headerRow.createCell(i);
//	        cell.setCellValue(headers[i]);
//	    }
//
//	    // Create data rows
//	    int rowNum = 1;
//	    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // Optional: adjust date format
//
//	    for (Form form : forms) {
//	        Row row = sheet.createRow(rowNum++);
//
//	        row.createCell(0).setCellValue(form.getId() != null ? form.getId() : "");
//	        row.createCell(1).setCellValue(form.getName() != null ? form.getName() : "");
//	        row.createCell(2).setCellValue(form.getMail() != null ? form.getMail() : "");
//	        row.createCell(3).setCellValue(form.getPhonenumber() != null ? form.getPhonenumber() : "");
//	        row.createCell(4).setCellValue(form.getInstrument() != null ? form.getInstrument() : "");
//	        row.createCell(5).setCellValue(form.getMood() != null ? form.getMood() : "");
//	        row.createCell(6).setCellValue(form.getLanuage() != null ? form.getLanuage() : "");
//	        row.createCell(7).setCellValue(form.getArtist() != null ? form.getArtist() : "");
//	        row.createCell(8).setCellValue(form.getSongto() != null ? form.getSongto() : "");
//	        row.createCell(9).setCellValue(form.getSongfrom() != null ? form.getSongfrom() : "");
//	        row.createCell(10).setCellValue(form.getOccasion() != null ? form.getOccasion() : "");
//	        row.createCell(11).setCellValue(form.getStory() != null ? form.getStory() : "");
//	        row.createCell(12).setCellValue(form.getClipPath() != null ? form.getClipPath() : "");
//	        row.createCell(13).setCellValue(form.getAdminClipPath() != null ? form.getAdminClipPath() : "");
//	        row.createCell(14).setCellValue(form.getClipDuration() != null ? form.getClipDuration() : 0.0);
//	        row.createCell(15).setCellValue(form.getStatus() != null ? form.getStatus() : "");
//	        row.createCell(16).setCellValue(form.getOrderNumber() != null ? form.getOrderNumber() : "");
//	        row.createCell(17).setCellValue(form.getMixtureMaster() != null ? form.getMixtureMaster() : "");
//	        row.createCell(18).setCellValue(form.getComments() != null ? form.getComments() : "");
//	        row.createCell(19).setCellValue(form.getScreenshot() != null ? form.getScreenshot() : "");
//
//	        // Handle orderPosition list
//	        String orderPositionString = form.getOrderPosition() != null
//	            ? form.getOrderPosition().toString()
//	            : "";
//	        row.createCell(20).setCellValue(orderPositionString);
//
//	        row.createCell(21).setCellValue(form.getCreatedDate() != null
//	            ? form.getCreatedDate().format(dateFormatter)
//	            : "");
//	        row.createCell(22).setCellValue(form.getCustomerDeliveryDate() != null
//	            ? form.getCustomerDeliveryDate().format(dateFormatter)
//	            : "");
//	        row.createCell(23).setCellValue(form.getReview() != null ? form.getReview() : "");
//	        row.createCell(24).setCellValue(form.getRating()); // Default rating is 0 if it's not set
//	        row.createCell(25).setCellValue(form.getImages() != null ? form.getImages().toString() : "");
//	        row.createCell(26).setCellValue(form.getVideo() != null ? form.getVideo() : "");
//	        row.createCell(27).setCellValue(form.getDeliveryDate() != null
//	            ? form.getDeliveryDate().format(dateFormatter)
//	            : "");
//	        row.createCell(28).setCellValue(form.getDurationInMMSS() != null ? form.getDurationInMMSS() : "");
//	        row.createCell(29).setCellValue(form.getOrderTotal() != null ? form.getOrderTotal() : 0.0);
//	        row.createCell(30).setCellValue(form.getActiveStatus() != null ? form.getActiveStatus() : "");
//
//	    }
//
//	    workbook.write(outputStream);
//	    workbook.close();
	}
	@Override
	public boolean validateMobileNumber(String countryCode, String mobileNumber) {
		try {
			String fullNumber = countryCode+mobileNumber;
			Phonenumber.PhoneNumber phoneNumber = phoneNumberUtil.parse(fullNumber, null);
			return phoneNumberUtil.isValidNumber(phoneNumber);
		} catch(NumberParseException ex) {
			ex.printStackTrace();
			return false;			
		}
	}
	@Override
	public String getNumberInfo(String countryCode, String mobileNumber) {
		try {
	        String fullNumber = countryCode + mobileNumber;
	        Phonenumber.PhoneNumber phoneNumber = phoneNumberUtil.parse(fullNumber, null);

	        if (phoneNumberUtil.isValidNumber(phoneNumber)) {
	            String region = phoneNumberUtil.getRegionCodeForNumber(phoneNumber);
	            PhoneNumberUtil.PhoneNumberType numberType = phoneNumberUtil.getNumberType(phoneNumber);
	            return String.format("Valid number. Region: %s, Type: %s", region, numberType);
	        } else {
	            return "Invalid number";
	        }
	    } catch (NumberParseException e) {
	        e.printStackTrace();
	        return "Error parsing number: " + e.getMessage();
	    }
	}
	@Override
	public String[] extractCountryCodeAndNationalNumber(String phoneNumber) {
	    try {	        
	        Phonenumber.PhoneNumber number = phoneNumberUtil.parse(phoneNumber, null);	        
	        int countryCode = number.getCountryCode();	        
	        String nationalNumber = String.valueOf(number.getNationalNumber());	        
	        String formattedCountryCode = "+" + countryCode;
	        return new String[]{formattedCountryCode, nationalNumber};
	    } catch (NumberParseException e) {
	        return new String[]{null, null};
	    }
	}
	@Override
	public Map<String, Object> genericFormSearch(String query, boolean isAdmin) {
		 String regexSearchTerm = ".*" + query + ".*";

	       
	        Criteria criteria = new Criteria().orOperator(
	            Criteria.where("name").regex(regexSearchTerm, "i"),
	            Criteria.where("mail").regex(regexSearchTerm, "i"),
	            Criteria.where("phonenumber").regex(regexSearchTerm, "i"),
	            Criteria.where("orderNumber").regex(regexSearchTerm, "i")
//	            Criteria.where("_id").is(new ObjectId(query)) 
	        );

	        Aggregation aggregation = Aggregation.newAggregation(
	            Aggregation.match(criteria),
	            Aggregation.project()
	            	.and("_id").as("id") 
	                .and("name").as("name")
	                .and("mail").as("mail")
	                .and("phonenumber").as("phonenumber")
	                .and("instrument").as("instrument")
	                .and("mood").as("mood")
	                .and("lanuage").as("lanuage")
	                .and("artist").as("artist")
	                .and("songto").as("songto")
	                .and("songfrom").as("songfrom")
	                .and("occasion").as("occasion")
	                .and("story").as("story")
	                .and("clipPath").as("clipPath")
	                .and("adminClipPath").as("adminClipPath")
	                .and("clipDuration").as("clipDuration")
	                .and("status").as("status")
	                .and("orderNumber").as("orderNumber")
	                .and("mixtureMaster").as("mixtureMaster")
	                .and("comments").as("comments")
	                .and("orderPosition").as("orderPosition")
	                .and("createdDate").as("createdDate")
	                .and("customerDeliveryDate").as("customerDeliveryDate")
	                .and("review").as("review")
	                .and("rating").as("rating")
	                .and("images").as("images")
	                .and("video").as("video")
	                .and("deliveryDate").as("deliveryDate")
	                .and("durationInMMSS").as("durationInMMSS")
	                .and("orderTotal").as("orderTotal")
	                .and("activeStatus").as("activeStatus")
	                .and("paymentId").as("paymentId")
	        );

	        AggregationResults<Form> results = mongoTemplate.aggregate(aggregation, "Form", Form.class);

	        List<Form> forms = results.getMappedResults();
	        if (isAdmin) {
	        List<FormRequestDto> allForms = forms.stream()
                    .map(formMapper::toDto)
                    .collect(Collectors.toList());
            
            int count = allForms.size();
            Map<String, Object> result = new HashMap<>();
            result.put("forms", allForms);
            result.put("totalElements", count);
            return result;
	        }else {
	        	
	        	 List<FormRequestDtoCoAdmin> allForms = forms.stream()
	                     .map(formMapper::toDtoCoAdmin)
	                     .collect(Collectors.toList());
	             
	             int count = allForms.size();
	             Map<String, Object> resultForCoAdmin = new HashMap<>();
	             resultForCoAdmin.put("forms", allForms);
	             resultForCoAdmin.put("totalElements", count);
	             return resultForCoAdmin;
	        }
	        
//	        logger.debug("Full Aggregation Results: {}", forms);
//
//	        if (forms.isEmpty()) {
//	            logger.debug("No results found for the query: {}", query);
//	        }
//	        int count = forms.size();
//            Map<String, Object> result = new HashMap<>();
//            result.put("forms", forms);
//            result.put("totalElements", count);
//            return result;
	}
	

	

	
	
	
	
}

