package com.realnet.password_generator;

import org.springframework.stereotype.Service;

import java.security.SecureRandom;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
public class PasswordGeneratorService {

    private static final String UPPERCASE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String LOWERCASE_CHARS = "abcdefghijklmnopqrstuvwxyz";
    private static final String NUMBER_CHARS = "0123456789";
    private static final String SYMBOL_CHARS = "!@#$%^&*()-_=+\\[{\]}|;:'\",<.>/?";

    private final SecureRandom secureRandom = new SecureRandom();

    public PasswordGenerationResponse generatePassword(PasswordGenerationRequest request) {
        if (request.getLength() == null || request.getLength() < 8 || request.getLength() > 128) {
            return new PasswordGenerationResponse(null, "Invalid password length. Must be between 8 and 128 characters.", false);
        }

        StringBuilder charPool = new StringBuilder();
        if (request.isIncludeUppercase()) {
            charPool.append(UPPERCASE_CHARS);
        }
        if (request.isIncludeLowercase()) {
            charPool.append(LOWERCASE_CHARS);
        }
        if (request.isIncludeNumbers()) {
            charPool.append(NUMBER_CHARS);
        }
        if (request.isIncludeSymbols()) {
            charPool.append(SYMBOL_CHARS);
        }

        if (charPool.length() == 0) {
            return new PasswordGenerationResponse(null, "At least one character type (uppercase, lowercase, numbers, symbols) must be selected.", false);
        }

        String finalCharPool = charPool.toString();
        if (request.getExcludeCharacters() != null && !request.getExcludeCharacters().isEmpty()) {
            for (char c : request.getExcludeCharacters().toCharArray()) {
                finalCharPool = finalCharPool.replace(String.valueOf(c), "");
            }
        }

        if (finalCharPool.length() == 0) {
            return new PasswordGenerationResponse(null, "Character pool is empty after exclusions. Please adjust your selections or exclusions.", false);
        }

        List<Character> passwordChars = IntStream.range(0, request.getLength())
                .mapToObj(i -> finalCharPool.charAt(secureRandom.nextInt(finalCharPool.length())))
                .collect(Collectors.toList());

        // Shuffle to ensure randomness and avoid predictable patterns
        Collections.shuffle(passwordChars, secureRandom);

        String generatedPassword = passwordChars.stream()
                .map(String::valueOf)
                .collect(Collectors.joining());

        return new PasswordGenerationResponse(generatedPassword, "Password generated successfully.", true);
    }
}