package mx.gob.slp.baseadminweb.application.config;

import mx.gob.slp.baseadminweb.domain.model.AppUser;
import mx.gob.slp.baseadminweb.domain.model.Role;
import mx.gob.slp.baseadminweb.domain.repository.AppUserRepository;
import mx.gob.slp.baseadminweb.domain.repository.RoleRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

@Component
public class InitialDataLoader implements CommandLineRunner {

    private static final String ADMIN_ROLE = "ROLE_ADMIN";
    private static final String SCANNER_ROLE = "ROLE_SCANNER";

    private final RoleRepository roleRepository;
    private final AppUserRepository appUserRepository;
    private final PasswordEncoder passwordEncoder;
    private final String adminUsername;
    private final String adminPassword;
    private final String adminDisplayName;
    private final String scannerUsername;
    private final String scannerPassword;
    private final String scannerDisplayName;

    public InitialDataLoader(RoleRepository roleRepository,
                             AppUserRepository appUserRepository,
                             PasswordEncoder passwordEncoder,
                             @Value("${app.admin.username:admin}") String adminUsername,
                             @Value("${app.admin.password:Admin123*}") String adminPassword,
                             @Value("${app.admin.display-name:Administrador Base}") String adminDisplayName,
                             @Value("${app.scanner.username:scanner}") String scannerUsername,
                             @Value("${app.scanner.password:Scanner123*}") String scannerPassword,
                             @Value("${app.scanner.display-name:Escaneador}") String scannerDisplayName) {
        this.roleRepository = roleRepository;
        this.appUserRepository = appUserRepository;
        this.passwordEncoder = passwordEncoder;
        this.adminUsername = adminUsername;
        this.adminPassword = adminPassword;
        this.adminDisplayName = adminDisplayName;
        this.scannerUsername = scannerUsername;
        this.scannerPassword = scannerPassword;
        this.scannerDisplayName = scannerDisplayName;
    }

    @Override
    public void run(String... args) {
        Role adminRole = roleRepository.findByName(ADMIN_ROLE)
                .orElseGet(() -> roleRepository.save(new Role(ADMIN_ROLE, "Administrador del sistema")));

        appUserRepository.findByUsername(adminUsername).orElseGet(() -> {
            AppUser admin = new AppUser(
                    adminUsername,
                    passwordEncoder.encode(adminPassword),
                    adminDisplayName,
                    true
            );
            admin.addRole(adminRole);
            return appUserRepository.save(admin);
        });

        Role scannerRole = roleRepository.findByName(SCANNER_ROLE)
                .orElseGet(() -> roleRepository.save(new Role(SCANNER_ROLE, "Escaneo de codigos pase")));

        appUserRepository.findByUsername(scannerUsername).orElseGet(() -> {
            AppUser scanner = new AppUser(
                    scannerUsername,
                    passwordEncoder.encode(scannerPassword),
                    scannerDisplayName,
                    true
            );
            scanner.addRole(scannerRole);
            return appUserRepository.save(scanner);
        });
    }
}
