package de.assecutor.votianlt.pages.service;

import de.assecutor.votianlt.model.AppUser;
import de.assecutor.votianlt.repository.AppUserRepository;
import de.assecutor.votianlt.security.SecurityService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
public class AppUserService {

    private final AppUserRepository appUserRepository;
    private final SecurityService securityService;
    private final BCryptPasswordEncoder passwordEncoder;

    @Autowired
    public AppUserService(AppUserRepository appUserRepository, SecurityService securityService) {
        this.appUserRepository = appUserRepository;
        this.securityService = securityService;
        this.passwordEncoder = new BCryptPasswordEncoder();
    }

    public AppUser createAppUser(AppUser appUser) {
        // Hash the password before saving
        if (appUser.getPassword() != null && !appUser.getPassword().isEmpty()) {
            String hashedPassword = passwordEncoder.encode(appUser.getPassword());
            appUser.setPassword(hashedPassword);
        }

        // Set creation and update metadata
        appUser.setErstelltAm(java.time.LocalDateTime.now());
        appUser.setAktualisiertAm(java.time.LocalDateTime.now());

        // Set creator and updater - current user ID is required
        ObjectId currentUserId = securityService.getCurrentUserId();
        appUser.setErstelltVon(currentUserId);
        appUser.setAktualisiertVon(currentUserId);
        appUser.setOwner(currentUserId);

        return appUserRepository.save(appUser);
    }

    public List<AppUser> findAll() {
        return appUserRepository.findAll();
    }

    public List<AppUser> findByCurrentUser() {
        ObjectId currentUserId = securityService.getCurrentUserId();
        return appUserRepository.findByErstelltVon(currentUserId);
    }

    public AppUser findById(ObjectId id) {
        return appUserRepository.findById(id).orElse(null);
    }

    public AppUser findByEmail(String email) {
        return appUserRepository.findByEmail(email);
    }

    public AppUser findByBezeichnung(String bezeichnung) {
        return appUserRepository.findByBezeichnung(bezeichnung);
    }

    public AppUser updateAppUser(AppUser appUser) {
        // Hash the password if it's being updated and not empty
        if (appUser.getPassword() != null && !appUser.getPassword().isEmpty()) {
            // Only hash if it's not already hashed (BCrypt hashes start with $2a$, $2b$, or
            // $2y$)
            if (!appUser.getPassword().startsWith("$2")) {
                String hashedPassword = passwordEncoder.encode(appUser.getPassword());
                appUser.setPassword(hashedPassword);
            }
        }

        appUser.setAktualisiertAm(java.time.LocalDateTime.now());
        appUser.setAktualisiertVon(securityService.getCurrentUserId());
        return appUserRepository.save(appUser);
    }

    /**
     * Verify a plain text password against the stored hashed password
     * 
     * @param plainPassword
     *            The plain text password to verify
     * @param hashedPassword
     *            The stored BCrypt hashed password
     * @return true if the password matches, false otherwise
     */
    public boolean verifyPassword(String plainPassword, String hashedPassword) {
        return passwordEncoder.matches(plainPassword, hashedPassword);
    }

    public void deleteById(ObjectId id) {
        appUserRepository.deleteById(id);
    }
}
