package com.saas.tenant.service;

import com.saas.admin.entity.User;
import com.saas.admin.repository.UserRepository;
import com.saas.shared.util.PasswordGeneratorUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * Service for provisioning users in the tenant database when doctors are
 * created
 * 
 * When a doctor is created, this service automatically creates a corresponding
 * user
 * account with auto-generated password
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserProvisioningService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    /**
     * Create a user account for a doctor in the tenant database
     * 
     * @param firstName Doctor's first name
     * @param lastName  Doctor's last name
     * @param email     Doctor's email
     * @return Generated password (should be displayed in modal for sharing)
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, transactionManager = "adminTransactionManager")
    public String provisionDoctorUser(String firstName, String lastName, String email) {
        log.info("📋 Provisioning user account for doctor: {} {} ({})", firstName, lastName, email);

        // Check if user already exists
        if (userRepository.findByEmail(email).isPresent()) {
            log.warn("⚠️ User already exists with email: {}", email);
            throw new IllegalArgumentException("User with email " + email + " already exists");
        }

        // Generate secure password
        String generatedPassword = PasswordGeneratorUtil.generateSecurePassword();

        // Create user entity
        User user = new User();
        user.setEmail(email);
        user.setFirstName(firstName);
        user.setLastName(lastName);
        user.setPassword(passwordEncoder.encode(generatedPassword));
        user.setStatus("ACTIVE");
        user.setRole("DOCTOR");

        // Save to database
        userRepository.save(user);
        log.info("✅ User account created successfully for: {}", email);

        // Return plain text password (only displayed once in modal)
        return generatedPassword;
    }

    /**
     * Update user account details (e.g. email change)
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW, transactionManager = "adminTransactionManager")
    public void updateDoctorUser(String oldEmail, String newEmail, String firstName, String lastName) {
        log.info("📋 Updating user account for doctor: {} -> {}", oldEmail, newEmail);

        userRepository.findByEmail(oldEmail).ifPresent(user -> {
            user.setEmail(newEmail);
            user.setFirstName(firstName);
            user.setLastName(lastName);
            userRepository.save(user);
            log.info("✅ Admin User account updated successfully for: {}", newEmail);
        });
    }

    /**
     * Check if user exists by email
     */
    public boolean userExists(String email) {
        return userRepository.findByEmail(email).isPresent();
    }
}
