<?php

namespace App\Utils;

use Doctrine\Persistence\ObjectManager;

class Utils
{
    // Password length
    const PASSWORD_MIN_LENGTH = 5;
    const PASSWORD_MAX_LENGTH = 50;

    const PERSON_DAMAGE_BASE = 40;
    const PERSON_DAMAGE_INDEX = 4;

    public static $riskFailure = [
        ['sehr niedrig', 5],
        ['niedrig', 10],
        ['mittel', 15],
        ['hoch', 20]
    ];

    public static $riskCosts = [
        ['0 - 5.000 €', 5],
        ['5.001 - 50.000 €', 10],
        ['50.001 - 250.000 €', 15],
        ['> 1 Mio €', 20],
        ['Personenschaden', 0]
    ];

    public static $riskPoints = [
        10 => ['factor' => 1, 'cycle' => 6],
        15 => ['factor' => 0.83, 'cycle' => 8],
        20 => ['factor' => 0.67, 'cycle' => 16],
        25 => ['factor' => 0.5, 'cycle' => 24],
        30 => ['factor' => 0.33, 'cycle' => 32],
        35 => ['factor' => 0.17, 'cycle' => 40],
        40 => ['factor' => 0, 'cycle' => 48]
    ];


    /**
     * Checks email format
     * @param $email
     * @return bool
     */
    public static function isValidEmail($email)
    {
        return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
    }

    /**
     * Checks if an email exists in users, persons or locations
     * @param ObjectManager $em
     * @param $email
     * @return bool
     */
    public static function emailUserExists(\Doctrine\Persistence\ObjectManager $em, $email)
    {
        $existingUserEmail = $em->getRepository('App:User')->findOneBy(['email' => $email]);
        return !is_null($existingUserEmail);
    }

    /**
     * Validates email and checks existence
     * @param ObjectManager $em
     * @param $email
     * @return bool
     */
    public static function validateEmail(ObjectManager $em, $email)
    {
        return self::isValidEmail($email) && !self::emailUserExists($em, $email);
    }

    /**
     * Checks length of password
     * @param $password
     * @return bool
     */
    public static function isValidPasswordLength($password)
    {
        return strlen($password) >= self::PASSWORD_MIN_LENGTH &&
            strlen($password) <= self::PASSWORD_MAX_LENGTH;
    }

    /**
     * Returns sorted array by getter name
     * @param $getterName
     * @param $arr
     * @return array
     */
    public static function getSortedObjects($getterName, $arr)
    {
        $res = [];
        foreach ($arr as $item) {
            $res[$item->{$getterName}()] = $item;
        }
        return $res;
    }

    /**
     * Returns sorted array by getter name
     * @param $arr
     * @return array
     */
    public static function getSortedObjectsById($arr)
    {
        return self::getSortedObjects('getId', $arr);
    }

    /**
     * Returns sorted array by getter name
     * @param $firstGetterName
     * @param $secondGetterName
     * @param $arr
     * @return array
     */
    public static function getSortedMultipleObjects($firstGetterName, $secondGetterName, $arr)
    {
        $res = [];
        foreach ($arr as $item) {
            $res[$item->{$firstGetterName}()][$item->{$secondGetterName}()] = $item;
        }
        return $res;
    }

    /**
     * Returns sorted array by key
     * @param $key
     * @param $arr
     * @return array
     */
    public static function getSortedArray($key, $arr)
    {
        $res = [];
        foreach ($arr as $item) {
            $res[$item[$key]] = $item;
        }
        return $res;
    }

    /**
     * Returns inverted array (values are keys)
     * @param $arr
     * @return array
     */
    public static function getInvertedArray($arr)
    {
        $res = [];
        foreach ($arr as $key => $value) {
            $res[$value] = $key;
        }
        return $res;
    }

    /**
     * Generates strong password
     * https://gist.github.com/tylerhall/521810
     *
     * @param int $length
     * @param false $add_dashes
     * @param string $available_sets
     * @return string
     */
    public static function generateStrongPassword($length = 9, $add_dashes = false, $available_sets = 'luds')
    {
        $sets = array();
        if(strpos($available_sets, 'l') !== false)
            $sets[] = 'abcdefghjkmnpqrstuvwxyz';
        if(strpos($available_sets, 'u') !== false)
            $sets[] = 'ABCDEFGHJKMNPQRSTUVWXYZ';
        if(strpos($available_sets, 'd') !== false)
            $sets[] = '23456789';
        if(strpos($available_sets, 's') !== false)
            $sets[] = '!@#$%&*?';

        $all = '';
        $password = '';
        foreach($sets as $set)
        {
            $password .= $set[array_rand(str_split($set))];
            $all .= $set;
        }

        $all = str_split($all);
        for($i = 0; $i < $length - count($sets); $i++)
            $password .= $all[array_rand($all)];

        $password = str_shuffle($password);

        if(!$add_dashes)
            return $password;

        $dash_len = floor(sqrt($length));
        $dash_str = '';
        while(strlen($password) > $dash_len)
        {
            $dash_str .= substr($password, 0, $dash_len) . '-';
            $password = substr($password, $dash_len);
        }
        $dash_str .= $password;
        return $dash_str;
    }
}