<?php

namespace Booktics\Dummy_Data;

use DateTime;
use Exception;

class Generator {
	/**
	 * List of sample words for text generation
	 */
	private $words = array(
		'lorem',
		'ipsum',
		'dolor',
		'sit',
		'amet',
		'consectetur',
		'adipiscing',
		'elit',
		'sed',
		'do',
		'eiusmod',
		'tempor',
		'incididunt',
		'ut',
		'labore',
		'et',
		'dolore',
		'magna',
		'aliqua',
		'enim',
		'ad',
		'minim',
		'veniam',
		'quis',
		'nostrud',
		'exercitation',
		'ullamco',
		'laboris',
		'nisi',
	);

	/**
	 * List of sample first names
	 */
	private $firstNames = array(
		'John',
		'Jane',
		'Michael',
		'Emily',
		'David',
		'Sarah',
		'Robert',
		'Jennifer',
		'William',
		'Elizabeth',
		'James',
		'Patricia',
		'Charles',
		'Linda',
		'Joseph',
		'Barbara',
	);

	/**
	 * List of sample last names
	 */
	private $lastNames = array(
		'Smith',
		'Johnson',
		'Williams',
		'Brown',
		'Jones',
		'Miller',
		'Davis',
		'Garcia',
		'Rodriguez',
		'Wilson',
		'Martinez',
		'Anderson',
		'Taylor',
		'Thomas',
		'Hernandez',
	);

	/**
	 * Get a random element from an array
	 *
	 * @param array $array
	 * @return mixed
	 */
	public function random_element( array $array ) {
		if ( empty( $array ) ) {
			return null;
		}
		return $array[ array_rand( $array ) ];
	}

	/**
	 * Generate a random sentence
	 *
	 * @param int $wordCount Number of words in the sentence
	 * @return string
	 */
	public function sentence( $wordCount = 7 ): string {
		$words = array();
		for ( $i = 0; $i < $wordCount; $i++ ) {
			$words[] = $this->random_element( $this->words );
		}
		return ucfirst( implode( ' ', $words ) ) . '.';
	}

	/**
	 * Generate a random number between min and max
	 *
	 * @param int $min
	 * @param int $max
	 *
	 * @return int
	 */
	public function number_between( int $min = 0, int $max = 100 ): int {
        return wp_rand( $min, $max );
    }

	/**
	 * Get a random name
	 *
	 * @return string
	 */
	public function name(): string {
		return $this->random_element( $this->firstNames ) . ' ' . $this->random_element( $this->lastNames );
	}

	/**
	 * Get a random email
	 *
	 * @return string
	 */
	public function email(): string {
		$domains = array( 'gmail.com', 'yahoo.com', 'outlook.com', 'example.com' );
		$name    = strtolower( str_replace( ' ', '.', $this->name() ) );
		return $name . '@' . $this->random_element( $domains );
	}

	/**
	 * Get a random phone number
	 *
	 * @return string
	 */
	public function phoneNumber(): string {
		return sprintf(
			'(%03d) %03d-%04d',
            wp_rand( 100, 999 ),
            wp_rand( 100, 999 ),
            wp_rand( 1000, 9999 )
        );
	}

	/**
	 * Generate a random date between two dates
	 *
	 * @param string $start Start date (strtotime compatible)
	 * @param string $end End date (strtotime compatible)
	 * @param string $timezone Timezone
	 * @return DateTime
	 */
	public function dateTimeBetween( string $start = '-30 days', string $end = 'now', $timezone = null ): DateTime {
		$start           = new DateTime( $start );
		$end             = new DateTime( $end );
        $randomTimestamp = wp_rand( $start->getTimestamp(), $end->getTimestamp() );
        $date            = new DateTime();
		$date->setTimestamp( $randomTimestamp );
		return $date;
	}

	/**
	 * Optional value generator
	 *
	 * @param float $weight Probability of returning a value (0.0 to 1.0)
	 * @param mixed $default Default value to return when not generating a value
	 * @param mixed $value Value to return when generating a value
	 * @return mixed
	 */
	public function optional( $weight = 0.5, $default = null, $value = null ) {
        return ( wp_rand( 0, 100 ) / 100 ) <= $weight
            ? ( $value ?? $this->sentence() )
			: $default;
	}
}
