<?php

namespace MintyPHP\Service\User;

use MintyPHP\Service\I18n\TranslatesServiceText;

class UserPasswordPolicyService
{
    use TranslatesServiceText;

    private const PASSWORD_MIN_LENGTH = 12;

    public function validate(string $password, string $password2, bool $required, ?string $email): array
    {
        $errors = [];
        if ($required && $password === '') {
            $errors[] = $this->translate('Password cannot be empty');
            return $errors;
        }
        if ($password !== '' && $password !== $password2) {
            $errors[] = $this->translate('Passwords must match');
        }
        if ($password === '') {
            return $errors;
        }
        if (strlen($password) < self::PASSWORD_MIN_LENGTH) {
            $errors[] = $this->translate('Password must be at least %d characters', self::PASSWORD_MIN_LENGTH);
        }
        if (!preg_match('/[A-Z]/', $password)) {
            $errors[] = $this->translate('Password must include an uppercase letter');
        }
        if (!preg_match('/[a-z]/', $password)) {
            $errors[] = $this->translate('Password must include a lowercase letter');
        }
        if (!preg_match('/\d/', $password)) {
            $errors[] = $this->translate('Password must include a number');
        }
        if (!preg_match('/[^a-zA-Z0-9]/', $password)) {
            $errors[] = $this->translate('Password must include a symbol');
        }
        if ($email !== null) {
            $email = trim($email);
            if ($email !== '' && stripos($password, $email) !== false) {
                $errors[] = $this->translate('Password must not contain your email');
            }
        }

        return $errors;
    }

    public function hints(): array
    {
        return [
            ['rule' => 'min', 'text' => $this->translate('At least %d characters', self::PASSWORD_MIN_LENGTH)],
            ['rule' => 'upper', 'text' => $this->translate('At least one uppercase letter')],
            ['rule' => 'lower', 'text' => $this->translate('At least one lowercase letter')],
            ['rule' => 'number', 'text' => $this->translate('At least one number')],
            ['rule' => 'symbol', 'text' => $this->translate('At least one symbol')],
            ['rule' => 'email', 'text' => $this->translate('Must not contain your email')],
        ];
    }

    public function minLength(): int
    {
        return self::PASSWORD_MIN_LENGTH;
    }

}
