package com.dacrt.SBIABackend.security.service;

import com.dacrt.SBIABackend.security.entity.Roles;
import com.dacrt.SBIABackend.security.entity.Users;
import com.dacrt.SBIABackend.security.repository.RolesRepository;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.transaction.Transactional;

@Service
@Transactional
public class GroupService {
	
	Logger logger = LoggerFactory.getLogger(GroupService.class);

    @Autowired
    private RolesRepository rolesRepository;

    public Map<String, Object> getScimGroups(String filter) {
        List<Roles> rolesList = new ArrayList<>();

        // 1. Manejo del filtro SCIM
        if (filter != null && filter.contains("displayName eq")) {
            Pattern pattern = Pattern.compile("displayName\\s+eq\\s+\"([^\"]+)\"");
            Matcher matcher = pattern.matcher(filter);

            if (matcher.find()) {
                String groupToSearch = matcher.group(1);
                // Buscamos por el nombre exacto de forma segura
                rolesRepository.findByName(groupToSearch).ifPresent(rolesList::add);
                System.out.println("Entro por el filter de name: " + filter);
            }
        } else {
            // Reemplaza la consulta 'WHERE u.id <> 0' buscando todos excepto el id 0
            rolesList = rolesRepository.findByIdNot(0);
            System.out.println("Entro por el list general");
        }

        List<Map<String, Object>> resources = new ArrayList<>();

        // 2. Construcción del cuerpo de la respuesta SCIM
        for (Roles role : rolesList) {
            Map<String, Object> groupScim = new HashMap<>();
            
            groupScim.put("schemas", Collections.singletonList("urn:ietf:params:scim:schemas:core:2.0:Group"));
            groupScim.put("id", role.getId()); 
            groupScim.put("displayName", role.getName());

            List<Map<String, Object>> scimMembers = new ArrayList<>();
            
            // Evaluamos los usuarios mapeados en este Rol
            if (role.getUsers() != null) {
                for (Users user : role.getUsers()) {
                    // Mantenemos tu filtro original: WHERE ref IS NOT NULL
                    if (user.getRef() != null) { 
                        Map<String, Object> member = new HashMap<>();
                        // Cast a String del ID tal como lo hacías en el SQL nativo
                        member.put("value", String.valueOf(user.getId())); 
                        member.put("display", user.getUsr()); // u.usr de tu entidad
                        
                        System.out.println("Armando los members: " + user.getId());
                        scimMembers.add(member);
                    }
                }
            }

            groupScim.put("members", scimMembers);
            resources.add(groupScim);
        }

        // 3. Estructura final ListResponse para Okta
        Map<String, Object> response = new HashMap<>();
        response.put("schemas", Collections.singletonList("urn:ietf:params:scim:api:messages:2.0:ListResponse"));
        response.put("totalResults", resources.size());
        response.put("startIndex", 1);
        response.put("itemsPerPage", resources.size());
        response.put("Resources", resources);
        
        System.out.println("Termino de armar el listado.. Enviando respuesta.");
        return response;
    }
}