<?php
/**
 * Gets the value from the row based on the mapped columns.
 *
 * @param  array  $mapped_columns Map of columns to attendee field values.
 * @param  string $key            The key we are trying to retrieve a value for.
 * @param  array  $row            The array of column values for a given row.
 * @return string                 Either an empty string or the value for the row.
 */
function rsvp_pro_retrieve_mapped_value( $mapped_columns, $key, $row ) {
	if ( isset( $mapped_columns[ $key ] ) ) {
		return trim( $row[ $mapped_columns[ $key ] ] );
	}

	return '';
}

/**
 * Handles the importing of attendees for a given event.
 *
 * @param  array $row            An array of columns values for a specific row.
 * @param  array $mapped_columns A mapping of the columns and what attendee fields they should go to.
 * @param  int   $count          Keeps count of how many attendees have been imported.
 * @param  int   $event_id       The event ID.
 */
function rsvp_pro_handle_import_row( $row, $mapped_columns, &$count, $event_id ) {
	global $wpdb;

	$group_id = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'group_id', $row );

	$passcode_length = 6;
	if ( rsvp_pro_get_event_option( $event_id, RSVP_PRO_OPTION_PASSWORD_LENGTH ) > 0 ) {
		$passcode_length = rsvp_pro_get_event_option( $event_id, RSVP_PRO_OPTION_PASSWORD_LENGTH );
	}
	$salutation = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'salutation', $row );
	$first_name = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'first_name', $row );
	$first_name = rsvp_pro_smart_quote_replace( rsvp_pro_handle_text_encoding( $first_name ) );

	$last_name = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'last_name', $row );
	$last_name = rsvp_pro_smart_quote_replace( rsvp_pro_handle_text_encoding( $last_name ) );

	$suffix = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'suffix', $row );
	$email  = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'email', $row );

	$personal_greeting  = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'custom_message', $row );
	$passcode           = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'passcode', $row );
	$alternate_passcode = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'alternate_passcode', $row );
	$rsvp_status        = 'NoResponse';

	$tmp_status = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'rsvp_status', $row );
	if ( rsvp_pro_is_allowed_status( $tmp_status ) ) {
		$rsvp_status = $tmp_status;
	}
	$rsvp_status = rsvp_pro_format_rsvp_status_for_database( $rsvp_status );

	$num_guests = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'num_guests', $row );
	if ( ! empty( $num_guests ) && ! is_numeric( $num_guests ) ) {
		$num_guests = '';
	}

	$note             = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'note', $row );
	$primary_attendee = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'primary_attendee', $row );
	$primary_attendee = ( 'Y' === strtoupper( $primary_attendee ) ) ? 'Y' : 'N';
	$attendee_id      = 0;
	if ( ! empty( $first_name ) || ! empty( $last_name ) ) {
		$sql = 'SELECT id, email, passcode FROM ' . PRO_ATTENDEES_TABLE . '
				WHERE firstName = %s AND lastName = %s AND rsvpEventID = %d AND ((email = %s OR passcode = %s) OR (email = \'\' and passcode = \'\')) ';
		if ( ! empty( $group_id ) ) {
			$sql .= ' AND group_id = %s';
			$res  = $wpdb->get_results( $wpdb->prepare( $sql, $first_name, $last_name, $event_id, $email, $passcode, $group_id ) );
		} else {
			$res = $wpdb->get_results( $wpdb->prepare( $sql, $first_name, $last_name, $event_id, $email, $passcode ) );
		}

		if ( count( $res ) == 0 ) {
			if ( '' === $passcode ) {
				$passcode = rsvp_pro_generate_passcode( $passcode_length );
			}

			$wpdb->insert(
				PRO_ATTENDEES_TABLE,
				array(
					'firstName'          => $first_name,
					'lastName'           => $last_name,
					'email'              => $email,
					'personalGreeting'   => $personal_greeting,
					'passcode'           => $passcode,
					'alternate_passcode' => $alternate_passcode,
					'salutation'         => $salutation,
					'suffix'             => $suffix,
					'rsvpEventID'        => $event_id,
					'rsvpStatus'         => $rsvp_status,
					'note'               => $note,
					'primaryAttendee'    => $primary_attendee,
				),
				array(
					'%s', // firstName.
					'%s', // lastName.
					'%s', // email.
					'%s', // personalGreeting.
					'%s', // passcode.
					'%s', // alternate_passcode.
					'%s', // salutation.
					'%s', // suffix.
					'%d', // rsvpEventID.
					'%s', // rsvpStatus.
					'%s', // note.
					'%s', // primaryAttendee.
				)
			);
			$attendee_id = $wpdb->insert_id;

			if ( ! empty( $group_id ) ) {
				$wpdb->update(
					PRO_ATTENDEES_TABLE,
					array( 'group_id' => $group_id ),
					array( 'id' => $attendee_id ),
					array( '%s' ),
					array( '%d' )
				);
			}
			$count++;
		} elseif ( empty( $res->email ) && empty( $res->passcode ) ) {
			if ( '' === $passcode ) {
				$passcode = rsvp_pro_generate_passcode( $passcode_length );
			}

			$attendee_id = $res[0]->id;

			// More than likely the attendee was inserted via an associated attendee and we will want to update this record...
			$wpdb->update(
				PRO_ATTENDEES_TABLE,
				array(
					'email'              => $email,
					'personalGreeting'   => $personal_greeting,
					'passcode'           => $passcode,
					'alternate_passcode' => $alternate_passcode,
					'salutation'         => $salutation,
					'suffix'             => $suffix,
					'rsvpStatus'         => $rsvp_status,
					'numGuests'          => $num_guests,
					'note'               => $note,
					'primaryAttendee'    => $primary_attendee,
				),
				array( 'id' => $attendee_id ),
				array(
					'%s', // email.
					'%s', // personalGreeting.
					'%s', // passcode.
					'%s', // alternate_passcode.
					'%s', // salutation.
					'%s', // suffix.
					'%s', // rsvpStatus.
					'%d', // numGuests.
					'%s', // note.
					'%s', // primaryAttendee.
				),
				array( '%d' )
			);
		}

		// We do this because in certain collations (like utf8_bin) an empty string for the number.
		// will be inserted as zero which causes problems with allowed number of guests.
		if ( is_numeric( $num_guests ) && ( $num_guests >= 0 ) ) {
			$wpdb->update(
				PRO_ATTENDEES_TABLE,
				array(
					'numGuests' => $num_guests,
				),
				array(
					'id' => $attendee_id,
				),
				array( '%d' ),
				array( '%d' )
			);
		}

		if ( RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID === $event_id ) {
			$sql    = 'SELECT id, eventName FROM ' . PRO_EVENT_TABLE . ' WHERE (parentEventID IS NULL OR parentEventID = 0) AND id != %d';
			$events = $wpdb->get_results( $wpdb->prepare( $sql, RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID ) );
			foreach( $events as $e ) {
				$se_num_guests = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'num_guests_' . $e->id, $row );
				if ( ! empty( $se_num_guests ) && is_numeric( $se_num_guests ) ) {
					$se = Rsvp_Pro_Attendee_Subevent::load_subevent_for_attendee( $e->id, $attendee_id );
					$se->set_num_guests( $se_num_guests );
					$se->save();
				}
			}
		}

		if ( isset( $mapped_columns['associated_attendees'] ) ) {

			$associated_attendees = rsvp_pro_retrieve_mapped_value( $mapped_columns, 'associated_attendees', $row );
			if ( ( $attendee_id > 0 ) && ! empty( $associated_attendees ) ) {
				$wpdb->delete(
					PRO_ASSOCIATED_ATTENDEES_TABLE,
					array( 'attendeeID' => $attendee_id ),
					array( '%d' )
				);

				$wpdb->delete(
					PRO_ASSOCIATED_ATTENDEES_TABLE,
					array( 'associatedAttendeeID' => $attendee_id ),
					array( '%d' )
				);

				$user_id = $attendee_id;

				// Deal with the assocaited users...
				$associated_attendees = explode( ',', $associated_attendees );
				if ( is_array( $associated_attendees ) ) {
					foreach ( $associated_attendees as $au ) {
						$user = explode( ' ', trim( $au ), 2 );
						// Three cases, they didn't enter in all of the information, user exists or doesn't.
						// If user exists associate the two users.
						// If user does not exist add the user and then associate the two.
						if ( is_array( $user ) && ( count( $user ) == 2 ) ) {
							$sql = 'SELECT id FROM ' . PRO_ATTENDEES_TABLE .
								' WHERE firstName = %s AND lastName = %s AND rsvpEventID = %d';
							if ( ! empty( $group_id ) ) {
								$sql     .= ' AND group_id = %s';
								$user_res = $wpdb->get_row( $wpdb->prepare( $sql, rsvp_pro_handle_text_encoding( trim( $user[0] ) ), rsvp_pro_handle_text_encoding( trim( $user[1] ) ), $event_id, $group_id ) );
							} else {
								$user_res = $wpdb->get_row( $wpdb->prepare( $sql, rsvp_pro_handle_text_encoding( trim( $user[0] ) ), rsvp_pro_handle_text_encoding( trim( $user[1] ) ), $event_id ) );
							}

							if ( $user_res ) {
								$new_user_id = $user_res->id;
							} else {
								// Insert them and then we can associate them...
								$wpdb->insert(
									PRO_ATTENDEES_TABLE,
									array(
										'firstName'   => rsvp_pro_smart_quote_replace( rsvp_pro_handle_text_encoding( trim( $user[0] ) ) ),
										'lastName'    => rsvp_pro_smart_quote_replace( rsvp_pro_handle_text_encoding( trim( $user[1] ) ) ),
										'rsvpEventID' => $event_id,
									),
									array( '%s', '%s', '%d' )
								);
								$new_user_id = $wpdb->insert_id;
								if ( ! empty( $group_id ) ) {
									$attendee_id = $wpdb->insert_id;
									$wpdb->update(
										PRO_ATTENDEES_TABLE,
										array( 'group_id' => $group_id ),
										array( 'id' => $new_user_id ),
										array( '%s' ),
										array( '%d' )
									);
								}
								$count++;
							}

							$wpdb->insert(
								PRO_ASSOCIATED_ATTENDEES_TABLE,
								array(
									'attendeeID'           => $new_user_id,
									'associatedAttendeeID' => $user_id,
								),
								array( '%d', '%d' )
							);

							$wpdb->insert(
								PRO_ASSOCIATED_ATTENDEES_TABLE,
								array(
									'attendeeID'           => $user_id,
									'associatedAttendeeID' => $new_user_id,
								),
								array( '%d', '%d' )
							);
						} // if(is_array($user)...
					} // foreach($associated..
				} // if(is_array...
			} // if((count($res) > 0)...
		}

		$private_questions = array();
		$question_values   = array();
		$subevents         = array();
		foreach ( $mapped_columns as $key => $value ) {
			$pqid = str_replace( 'pq_', '', $key );
			if ( is_numeric( $pqid ) && rsvp_pro_custom_question_exists( $pqid, $event_id ) ) {
				$private_questions[ $value ] = $pqid;
			}

			$cqid = str_replace( 'cq_', '', $key );
			if ( is_numeric( $cqid ) && rsvp_pro_custom_question_exists( $cqid, $event_id ) ) {
				$question_values[ $value ] = $cqid;
			}

			$seid = str_replace( 'se_', '', $key );
			if ( is_numeric( $seid ) && ( $seid > 0 ) ) {
				$subevents[ $value ] = $seid;
			}
		}

		if ( ( 0 < count( $private_questions ) ) || ( 0 < count( $question_values ) ) ) {
			if ( $attendee_id > 0 ) {
				$user_id = $attendee_id;

				if ( 0 < count( $private_questions ) ) {
					$wpdb->delete(
						PRO_QUESTION_ATTENDEES_TABLE,
						array( 'attendeeID' => $user_id ),
						array( '%d' )
					);
				}

				if ( 0 < count( $question_values ) ) {
					$wpdb->delete(
						PRO_ATTENDEE_ANSWERS,
						array( 'attendeeID' => $user_id ),
						array( '%d' )
					);
				}

				foreach ( $private_questions as $key => $val ) {
					if ( 'Y' === strToUpper( $row[ $key ] ) ) {
						$wpdb->insert(
							PRO_QUESTION_ATTENDEES_TABLE,
							array(
								'attendeeID' => $user_id,
								'questionID' => $val,
							),
							array( '%d', '%d' )
						);
					}
				}

				foreach ( $question_values as $key => $val ) {
					$wpdb->insert(
						PRO_ATTENDEE_ANSWERS,
						array(
							'attendeeID' => $user_id,
							'questionID' => $val,
							'answer'     => trim( $row[ $key ] ),
						),
						array( '%d', '%d', '%s' )
					);
				}
			}
		}

		foreach ( $subevents as $key => $val ) {
			if ( 'Y' === strtoupper( $row[ $key ] ) ) {
				if ( $attendee_id > 0 ) {
					$wpdb->replace(
						PRO_EVENT_ATTENDEE_TABLE,
						array(
							'rsvpEventID'    => $val,
							'rsvpAttendeeID' => $attendee_id,
						),
						array( '%d', '%d' )
					);
				}
			}
		}
	}
}
