package com.ffii.core.user.web;

import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;

import javax.mail.internet.InternetAddress;

import org.apache.commons.text.StringEscapeUtils;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ffii.core.common.ErrorCodes;
import com.ffii.core.common.PasswordRule;
import com.ffii.core.common.mail.pojo.MailRequest;
import com.ffii.core.common.mail.service.MailService;
import com.ffii.core.department.service.DepartmentService;
import com.ffii.core.exception.UnprocessableEntityException;
import com.ffii.core.settings.service.SettingsService;
import com.ffii.core.support.AbstractController;
import com.ffii.core.user.entity.User;
import com.ffii.core.user.req.ForgetPwReq;
import com.ffii.core.user.service.UserService;
import com.ffii.core.utils.LocaleUtils;
import com.ffii.core.utils.PasswordUtils;

@RestController
@RequestMapping("/public/forget-pw")
public class ForgetPwController extends AbstractController {

  private UserService userService;
  private DepartmentService departmentService;
  private SettingsService settingsService;
  private PasswordEncoder passwordEncoder;
  private MailService mailService;
  private MessageSource messageSource;

  public ForgetPwController(UserService userService, DepartmentService departmentService,
      SettingsService settingsService, PasswordEncoder passwordEncoder, MailService mailService,
      MessageSource messageSource) {
    this.userService = userService;
    this.departmentService = departmentService;
    this.settingsService = settingsService;
    this.passwordEncoder = passwordEncoder;
    this.mailService = mailService;
    this.messageSource = messageSource;
  }

  @PostMapping
  public boolean forgetPassword(ForgetPwReq req) throws NoSuchMessageException, UnsupportedEncodingException {
    Optional<User> userOpt = userService.findByUsername(req.getUsername());
    if (userOpt.isEmpty()) {
      throw new UnprocessableEntityException(ErrorCodes.USER_NOT_EXIST);
    }

    User instance = userOpt.get();
    String dept = departmentService.getDeptNameById(instance.getDeptId());
    String randomPassword = PasswordUtils.genPwd(new PasswordRule(settingsService));
    String pwdHash = passwordEncoder.encode(randomPassword);

    instance.setPassword(pwdHash);
    instance = userService.save(instance);

    Locale locale = instance.getLocale() != null ? LocaleUtils.from(instance.getLocale()) : Locale.ENGLISH;

    try {
      mailService.send(
          MailRequest.builder()
              .subject("[MSMS] " + messageSource.getMessage("USER.resetPw.subject", null, locale) + " - " + dept)
              .template("mail/forgetPw")
              .args(Map.of("department", dept, "username", instance.getUsername(), "password",
                  StringEscapeUtils.escapeHtml4(randomPassword)))
              .addTo(new InternetAddress(instance.getEmail(), instance.getName()))
              .build(),
          locale);
      return true;
    } catch (Exception ex) {
      return false;
    }

  }

}
