package com.hepl.tunefortwo.service.impl;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.convert.DurationUnit;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import com.hepl.tunefortwo.dto.ResetPasswordDto;
import com.hepl.tunefortwo.dto.UserDTO;
import com.hepl.tunefortwo.entity.Users;
import com.hepl.tunefortwo.mapper.UserMapper;
import com.hepl.tunefortwo.repository.UserRepository;
import com.hepl.tunefortwo.service.MailService;
import com.hepl.tunefortwo.service.TemplateService;
import com.hepl.tunefortwo.service.UserService;

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

@Service
@Slf4j
public class UserServiceImpl implements UserService {
	
	@Value("${resetPassword.url}")
   	private String resetPasswordUrl;
	
	@Value("${resetTokenExpiration.seconds}")
	@DurationUnit(ChronoUnit.SECONDS)
	private long RESET_TOKEN_EXPIRATION_DURATION_SECONDS;
	
    private final UserRepository userRepository;
    private final UserMapper userMapper;
    private final MailService mailService;
   	private final TemplateService templateService;
//   	private static final long RESET_TOKEN_EXPIRATION_DURATION_SECONDS = 60 * 60;
   	
   


    public UserServiceImpl(UserRepository userRepository, UserMapper userMapper,MailService mailService,TemplateService templateService) {
        this.userRepository = userRepository;
        this.userMapper = userMapper;
        this.mailService = mailService;
        this.templateService = templateService;
    }

    @Override
    public Users saveUser(UserDTO users) {
        log.info("User service");
        Users userToBeInserted = userMapper.toUserEntity(users);
        return userRepository.save(userToBeInserted);
    }

	@Override
	public Users findUserForEmail(String email) {
		Users userForEmail = userRepository.findByEmail(email);		
		return userForEmail;
	}

	@Override
	public String generateResetToken() {
		 return UUID.randomUUID().toString();
	}

	@Override
	public Users setResetToken(Users user, String token) throws MessagingException {
		
		if(token!=null) {
		 user.setResetToken(token);
		 user.setResetTokenCreatedTime(LocalDateTime.now());
		}
		Users updatedToken = userRepository.save(user);
//		String resetPasswordLink = "http://localhost:8042/tune/api/v1/users/reset-password?token=" + token;
//		String resetPasswordLink = "https://testing_demo.cavinkare.in/tune_for_2/#/newpassword/"+token;
		String resetPasswordLink = resetPasswordUrl+token;
//        emailService.sendResetPasswordEmail(user.getEmail(), resetPasswordLink);
		mailService.sendMailByTemplate(templateService.getResetPasswordTemplateNew(updatedToken.getUsername(),resetPasswordLink),updatedToken.getEmail(),"Reset Password Email");
		return updatedToken;
	}

	@Override
	public Users findUserByToken(String token) {
		Users userForToken = userRepository.findByResetToken(token);
		
		return userForToken;
	}

	@Override
	public boolean isResetTokenExpired(Users user) {
	    Users userForTokenValidation = userRepository.findByEmail(user.getEmail());
	    if (userForTokenValidation == null) {
	        throw new IllegalArgumentException("User not found for email: " + user.getEmail());
	    }
	    String resetToken = userForTokenValidation.getResetToken();
	    LocalDateTime tokenCreationTime = userForTokenValidation.getResetTokenCreatedTime();
	    if (resetToken == null || tokenCreationTime == null) {
	        return true; 
	    }
	    LocalDateTime expirationTime = tokenCreationTime.plusSeconds(RESET_TOKEN_EXPIRATION_DURATION_SECONDS);
	    LocalDateTime currentTime = LocalDateTime.now();
	    return currentTime.isAfter(expirationTime);
	}


	@Override
	public ResponseEntity<String> updateNewPassword(ResetPasswordDto newPass) {
	    
	    Users userForEmail = userRepository.findByEmail(newPass.getEmail());
	    
	    if (userForEmail == null) {
	        return ResponseEntity.status(HttpStatus.NOT_FOUND)
	                .body("No user found for email: " + newPass.getEmail());
	    }
	    
	    if (userForEmail.getResetToken() == null || !userForEmail.getResetToken().equals(newPass.getResetToken())) {
	        return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
	                .body("Access denied");
	    }
	    
	    userForEmail.setPassword(newPass.getNewPassword());
	    userForEmail.setResetToken(null);
	    userForEmail.setResetTokenCreatedTime(null);
	    userRepository.save(userForEmail);
	    
	    return ResponseEntity.status(HttpStatus.OK)
	            .body("Password updated successfully");
	}



	
	

}
