<?php
namespace SabaiApps\Directories\Component\Calendar\FakerGenerator;

use SabaiApps\Directories\Component\Faker\Generator\AbstractGenerator;
use SabaiApps\Directories\Component\Field\IField;
use SabaiApps\Directories\Component\Entity\Type\IEntity;
use SabaiApps\Directories\Component\Calendar\FieldType\SlotFieldType;

class SlotFakerGenerator extends AbstractGenerator {

	protected function _fakerGeneratorInfo() {
		return array(
			'field_types'      => array( $this->_name ),
			'add_probability'  => true,
			'default_settings' => array(
				'range' => array(
					time(),
					time() + 86400 * 365 * 1, // 1 year from now
				),
				'max'   => 5,
			),
		);
	}

	public function fakerGeneratorSettingsForm( IField $field, array $settings, $mode, array $parents = array() ) {
		return array(
			'range' => $this->_getTimestampSettingForm( $settings['range'] ),
			'max'   => $this->_getMaxNumItemsSettingForm( $field, $settings['max'] ),
		);
	}

	public function fakerGeneratorGenerate( IField $field, array $settings, array &$formStorage, ?IEntity $entity = null ) {
		$field_settings   = $field->getFieldSettings();
		$enable_recurring = ! empty( $field_settings['enable_recurring'] );
		$enable_title     = ! empty( $field_settings['enable_title'] );
		$enable_booking   = ! empty( $field_settings['enable_booking'] );

		$ret                = array();
		$count              = $this->_getMaxNumItems( $field, $settings['max'] );
		$time_options       = array_keys( $this->_application->System_Util_timeOptions() );
		$time_options_count = count( $time_options );
		$date_range         = $settings['range'];
		$start_date_range   = array( $date_range[0], ( $date_range[1] - $date_range[0] ) / 2 + $date_range[0] );
		for ( $i = 0; $i < $count; ++$i ) {
			$data   = array();
			$repeat = '';
			$rrule  = $repeat_end_after = null;
			if ( $enable_recurring
				&& random_int( 1, 10 ) <= 5
			) {
				$repeat_types = array( 'daily', 'weekly', 'monthly', 'yearly' );
				$repeat       = $repeat_types[ array_rand( $repeat_types ) ];
				$repeat_data  = array();
			}
			$start_date = $this->_application->Form_Validate_date( date( 'Y-m-d 00:00:00', $this->_generateTimestamp( $start_date_range ) ), array( '#required' => true ), null, 'Y-m-d H:i:s' );
			if ( $repeat !== '' ) {
				switch ( $repeat ) {
					case 'daily':
						$repeat_end_after = random_int( 10, 50 );
						break;
					case 'weekly':
						$repeat_data['days'] = array();
						$num_days            = random_int( 1, 6 );
						while ( count( $repeat_data['days'] ) < $num_days ) {
							$day = random_int( 1, 7 );
							if ( ! in_array( $day, $repeat_data['days'], true ) ) {
								$repeat_data['days'][] = $day;
							}
						}
						$repeat_end_after = random_int( 5, 20 );
						break;
					case 'monthly':
						if ( random_int( 1, 10 ) <= 7 ) {
							$repeat_data['monthday'] = random_int( 1, 31 );
						} else {
							$repeat_data['week'] = array(
								'day'     => random_int( 1, 7 ),
								'day_pos' => random_int( -1, 4 ),
							);
						}
						$repeat_end_after = random_int( 3, 12 );
						break;
					case 'yearly':
						$repeat_end_after = random_int( 2, 5 );
						break;
				}
				$rrule = SlotFieldType::getRrule( $repeat, $repeat_data );
			}
			if ( $enable_booking ) {
				if ( random_int( 1, 10 ) <= 8 ) {
					$data['booking_allow']      = true;
					$data['booking_max_spaces'] = random_int( 1, 20 ) * 5;
				}
			}
			$ret[] = array(
				'title'            => $enable_title ? $this->generateTitle() : '',
				'start_date'       => $start_date,
				'start_time'       => $time_options[ rand( 0, round( $time_options_count / 2 ) - 1 ) ],
				'end_time'         => $time_options[ rand( round( $time_options_count / 2 ), $time_options_count - 1 ) ],
				'repeat'           => $repeat,
				'rrule'            => $rrule,
				'repeat_end_after' => $repeat_end_after,
				'all_day'          => random_int( 1, 10 ) === 1,
				'data'             => $data,
			);
		}
		return empty( $ret ) ? null : $ret;
	}

	public function generateTitle() {
		$prefixes = array(
			'Annual',
			'Global',
			'Local',
			'Future',
			'Digital',
			'Sustainable',
			'Creative',
			'Advanced',
			'Open',
			'Monthly',
			'Winter',
			'Summer',
			'Urban',
			'Strategic',
			'Community',
		);
		$topics   = array(
			'Blockchain',
			'AI',
			'Startup',
			'Design',
			'Jazz',
			'Craft Beer',
			'Yoga',
			'Wellness',
			'Marketing',
			'FinTech',
			'Coding',
			'SaaS',
			'Photography',
			'Food',
			'Gaming',
			'Web3',
			'E-Commerce',
			'Music',
			'Art',
		);
		$types    = array(
			'Meetup',
			'Hackathon',
			'Festival',
			'Summit',
			'Workshop',
			'Expo',
			'Conference',
			'Bootcamp',
			'Night',
			'Challenge',
			'Forum',
			'Symposium',
			'Gathering',
			'Lab',
			'Marathon',
			'Carnival',
			'Fair',
		);

		$prefix = $prefixes[ array_rand( $prefixes ) ];
		$topic  = $topics[ array_rand( $topics ) ];
		$type   = $types[ array_rand( $types ) ];

		$pattern = rand( 0, 2 );
		switch ( $pattern ) {
			case 0:
				return "$prefix $topic $type";
			case 1:
				$year = date( 'Y' ) + rand( 0, 1 );
				return "$topic $type $year";
			case 2:
				return "The $topic $type";
		}
	}
}
