package Cyber::GroupProcessedAPI;
use strict;
use warnings;

use Data::Dumper;
use String::Random;
use POSIX 'strftime';
use Encode;
use JSON;
use LWP::UserAgent;
use IO::Compress::Gzip qw(gzip);
use IO::Uncompress::Gunzip qw( gunzip );
use Cyber::Database;
use Date::Simple qw(date);
no warnings "uninitialized";
use HTTP::BrowserDetect;
use HTML::Entities;
use PHP::Serialization qw(unserialize);

#Constructor
sub new {
	my $class = shift;
	
	my $obj = {};
	
	my $obj_database = new Cyber::Database;
	$obj->{'obj_database'} = $obj_database;
	
	bless $obj, $class;
	
	return $obj;
}

#Authenticate User
sub get_property_detail {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $class->{'hotel_id'};

	#Check user name
	my $hotel_detail = $class->{'obj_database'}->get({
		'table'  => 'hotels',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'id' => $hotel_id
		}
	});
	
	if ( scalar @$hotel_detail ) {
		my $hotel_detail_data = $hotel_detail->[0];
		$class->{'hotel_detail'} = $hotel_detail_data;

		return 1;
	}
	else {
		$class->{'hotel_detail'} = {};
	}
	
	return 0;
}

sub get_group_detail {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $group_id   = $cgi_params->{'group_id'};

	#Check user name
	my $group_detail = $class->{'obj_database'}->get({
		'table'  => 'hotel_groups',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'id' => $group_id
		}
	});
	
	if ( scalar @$group_detail ) {
		my $group_detail_data = $group_detail->[0];
		$class->{'group_detail'} = $group_detail_data;

		return 1;
	}
	else {
		$class->{'group_detail'} = {};
	}
	
	return 0;
}

sub get_room_type_list {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $class->{'hotel_id'};

	my $room_type_list = $class->{'obj_database'}->get_record_with_limit({
		'table'  => 'room_types',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'hotel_id' => $hotel_id
		},
		'key' => 'id'
	});

	if ( defined $room_type_list ) {
		$class->{'room_type_list'} = $room_type_list;
	}
	else {
		$class->{'room_type_list'} = {};
	}
	return 1;
}

sub get_rate_type_list {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $class->{'hotel_id'};

	my $rate_type_list = $class->{'obj_database'}->get_record_with_limit({
		'table'  => 'rate_types',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'hotel_id' => $hotel_id
		},
		'key' => 'id'
	});

	if ( defined $rate_type_list ) {
		$class->{'rate_type_list'} = $rate_type_list;
	}
	else {
		$class->{'rate_type_list'} = {};
	}
	return 1;
}

sub get_rate_plan_list {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $class->{'hotel_id'};

	my $rate_plan_list = $class->{'obj_database'}->get_record_with_limit({
		'table'  => 'rate_plans',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'hotel_id' => $hotel_id
		},
		'key' => 'room_type_id'
	});

	if ( defined $rate_plan_list ) {
		$class->{'rate_plan_list'} = $rate_plan_list;
	}
	else {
		$class->{'rate_plan_list'} = {};
	}
	return 1;
}

sub get_master_room_facilities {
	my $class = shift;

	my $master_facility_list = $class->{'obj_database'}->get_record_with_limit({
		'table'  => 'room_facilities',
		'hash'   => 1,
		'select' => '*',
		'key' => 'id'
	});

	if ( defined $master_facility_list ) {
		$class->{'master_facility_list'} = $master_facility_list;
	}
	else {
		$class->{'master_facility_list'} = {};
	}
	return 1;
}

sub get_inventory {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $class->{'hotel_id'};
	my $check_in   = $cgi_params->{'check_in'};
	my $check_out  = $cgi_params->{'check_out'};

	my $whr->{'hotel_id'} = $hotel_id;
	if ( exists $cgi_params->{'room_type_id'} && $cgi_params->{'room_type_id'} !~ /^\s*$/ ) {
		$whr->{'room_type_id'} = $cgi_params->{'room_type_id'};
	}

	$whr = [
		$whr,
		'AND',
		"date BETWEEN '$check_in' AND '$check_out'"
	];

	my $inventory_data = undef;
	eval {
		$inventory_data = $class->{'obj_database'}->get({
			'table'  => 'inventory_masters',
			'hash'   => 1,
			'select' => 'date, room_type_id, availability',
			'where'  => $whr
		});
	};

	if ( defined $inventory_data && scalar @$inventory_data ) {
		my $inventory_data_hash = {};
		foreach my $data ( @$inventory_data ) {
			$inventory_data_hash->{$data->{'room_type_id'}}->{$data->{'date'}} = $data->{'availability'};
		}
		$class->{'inventory_data_hash'} = $inventory_data_hash;
	}
	else {
		$class->{'inventory_data_hash'} = {};
	}
	return 1;
}

sub check_inventory {
	my $class = shift;

	my $hotel_id   = shift;
	my $check_in   = shift;
	my $check_out  = shift;
	my $room_type_id = shift;
	my $no_of_room = shift;

	my $whr->{'hotel_id'} = $hotel_id;
	$whr->{'room_type_id'} = $room_type_id;
	
	$whr = [
		$whr,
		'AND',
		"date >= '$check_in' AND date < '$check_out'"
	];

	my $inventory_data = undef;
	eval {
		$inventory_data = $class->{'obj_database'}->get({
			'table'  => 'inventory_masters',
			'hash'   => 1,
			'select' => 'date, room_type_id, availability',
			'where'  => $whr
		});
	};

	if ( defined $inventory_data && scalar @$inventory_data ) {
		my $is_available = 1;
		foreach my $data ( @$inventory_data ) {
			if ( $data->{'availability'} < $no_of_room ) {
				$is_available = 0;
				last;
			}
		}
		
		$class->{'is_available'} = $is_available;
	}
	else {
		$class->{'is_available'} = 0;
	}
	
	return 1;
}

sub reduce_inventory {
	my $class = shift;

	my $hotel_id   = shift;
	my $check_in   = shift;
	my $check_out  = shift;
	my $room_type_id = shift;
	my $no_of_room = shift;

	my $whr->{'hotel_id'} = $hotel_id;
	$whr->{'room_type_id'} = $room_type_id;
	
	$whr = [
		$whr,
		'AND',
		"date >= '$check_in' AND date < '$check_out'"
	];

	my $inventory_data = undef;
	eval {
		$inventory_data = $class->{'obj_database'}->get({
			'table'  => 'inventory_masters',
			'hash'   => 1,
			'select' => 'id, date, room_type_id, availability',
			'where'  => $whr
		});
	};

	if ( defined $inventory_data && scalar @$inventory_data ) {
		foreach my $data ( @$inventory_data ) {
			my $current_inventory = $data->{'availability'};
			my $available_inventory = $current_inventory - $no_of_room;
			if ( $available_inventory < 0 ) {
				$available_inventory = 0;
			}

			$class->{'obj_database'}->set(
				'table' => 'inventory_masters',
				'update' => {
					'availability'  => $available_inventory,
					'updated_at'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
				},
				'where' => {
					'id' => $data->{'id'}
				}
			);
		}
	}

	return 1;
}

sub replenish_inventory {
	my $class = shift;

	my $hotel_id   = shift;
	my $check_in   = shift;
	my $check_out  = shift;
	my $room_type_id = shift;
	my $no_of_room = shift;

	my $whr->{'hotel_id'} = $hotel_id;
	$whr->{'room_type_id'} = $room_type_id;
	
	$whr = [
		$whr,
		'AND',
		"date >= '$check_in' AND date < '$check_out'"
	];

	my $inventory_data = undef;
	eval {
		$inventory_data = $class->{'obj_database'}->get({
			'table'  => 'inventory_masters',
			'hash'   => 1,
			'select' => 'id, date, room_type_id, availability',
			'where'  => $whr
		});
	};

	if ( defined $inventory_data && scalar @$inventory_data ) {
		foreach my $data ( @$inventory_data ) {
			my $current_inventory = $data->{'availability'};
			my $available_inventory = $current_inventory + $no_of_room;
			if ( $available_inventory < 0 ) {
				$available_inventory = 0;
			}

			$class->{'obj_database'}->set(
				'table' => 'inventory_masters',
				'update' => {
					'availability'  => $available_inventory,
					'updated_at'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
				},
				'where' => {
					'id' => $data->{'id'}
				}
			);
		}
	}

	return 1;
}

sub get_rate_restriction {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $class->{'hotel_id'};
	my $check_in   = $cgi_params->{'check_in'};
	my $check_out  = $cgi_params->{'check_out'};

	my $whr->{'hotel_id'} = $hotel_id;
	if ( exists $cgi_params->{'rate_plan_id'} && $cgi_params->{'rate_plan_id'} !~ /^\s*$/ ) {
		$whr->{'rate_plan_id'} = $cgi_params->{'rate_plan_id'};
	}

	$whr = [
		$whr,
		'AND',
		"date BETWEEN '$check_in' AND '$check_out'"
	];

	my $rate_restriction_data = undef;
	eval {
		$rate_restriction_data = $class->{'obj_database'}->get({
			'table'  => 'rate_restriction_masters',
			'hash'   => 1,
			'select' => '*',
			'where'  => $whr
		});
	};

	if ( defined $rate_restriction_data && scalar @$rate_restriction_data ) {
		my $rate_data_hash = {};
		foreach my $data ( @$rate_restriction_data ) {
			delete( $data->{'created_at'} );
			delete( $data->{'updated_at'} );
			$rate_data_hash->{$data->{'rate_plan_id'}}->{$data->{'date'}} = $data;
		}
		$class->{'rate_data_hash'} = $rate_data_hash;
	}
	else {
		$class->{'rate_data_hash'} = {};
	}
	
	return 1;
}

sub get_all_offers {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $cgi_params->{'hotel_id'};
	
	my $is_mobile = 0;
	my $bw = HTTP::BrowserDetect->new(); 
	if ( $bw->mobile ) {
		$is_mobile = 1;
	}

	my $whr->{'hotel_id'} = $hotel_id;
	if ( $is_mobile ) {
		$whr->{'mobile_offer'} = 'on';
	}
	# else {
	# 	$whr = [
	# 		$whr,
	# 		"AND",
	# 		"mobile_offer != 'on'"
	# 	];
	# }

	my $today_date = ::get_today_day();
	if ( $whr ) {
		$whr = [
			$whr,
			"AND",
			"'$today_date' between valid_from and valid_to"
		];
	}
	# print Dumper $whr;
	my $offers_list = undef;

	$offers_list = $class->{'obj_database'}->get({
		'table'  => 'offers',
		'hash'   => 1,
		'select' => '*',
		'where'  => $whr
	});
	
	# print Dumper $decided_room_offers;
	my $new_list = [];
	if ( defined $offers_list ) {
		foreach my $x ( @$offers_list ) {
			my $offer_image = $x->{'image'};
			my $image_path = $::config{'base_url'}->{'image_base_offer'}.$offer_image;

			$x->{'image'} = $image_path;

			if ( $is_mobile ) {
				push @$new_list, $x;
			}
			else {
				if ( $x->{'mobile_offer'} !~ /on/i ) {
					push @$new_list, $x;
				}
			}
		}
	}
	
	$class->{'all_offers_list'} = $offers_list;

	return 1;
}

sub get_offers {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $class->{'hotel_id'};
	
	my $is_mobile = 0;
	my $bw = HTTP::BrowserDetect->new(); 
	if ( $bw->mobile ) {
		$is_mobile = 1;
	}

	my $whr->{'hotel_id'} = $hotel_id;
	if ( $is_mobile ) {
		$whr->{'mobile_offer'} = 'on';
	}

	my $offers_list = undef;

	$offers_list = $class->{'obj_database'}->get({
		'table'  => 'offers',
		'hash'   => 1,
		'select' => '*',
		'where'  => $whr
	});
	# print Dumper $offers_list;
	
	my $no_of_adult = $cgi_params->{'no_of_adult'};
	my $no_of_child = $cgi_params->{'no_of_child'};
	my $today_date = ::get_today_day();
	my $check_in  = $cgi_params->{'check_in'};
	my $check_out = $cgi_params->{'check_out'};
	my $dow_num = ::get_day_of_week( $check_in );
	$dow_num =~ s/^0//;

	my $dow_string = $::single_digit_dow->{$dow_num};

	my $adv_days = ::get_delta_days( $today_date, $check_in );

	my $no_of_room = $cgi_params->{'no_of_room'};

	my $decided_room_offers = undef;
	if ( defined $offers_list && scalar @$offers_list ) {
		foreach my $offer ( @$offers_list ) {

			for (my $r = 1; $r <= $no_of_room; $r++) {
				my $no_of_adult = $cgi_params->{'no_of_adult'.$r};
				my $no_of_child = $cgi_params->{'no_of_child'.$r};
				my $pas_key = $no_of_adult.'A'.$no_of_child.'C';

				my $valid_from     = $offer->{'valid_from'};
				my $valid_to       = $offer->{'valid_to'};
				my $exclusive_days = $offer->{'exclusive_days'};
				my $days_of_week   = $offer->{'days_of_week'};
				my $disc           = $offer->{'discount_percentage'};

				my $min_adult = $offer->{'min_no_of_adults'};
				my $max_adult = $offer->{'max_no_of_adults'};
				my $min_child = $offer->{'min_no_of_child'};
				if ( !defined $min_child || $min_child =~ /^\s*$/ || $min_child =~ /null/i ) {
					$min_child = 0;
				}
				my $max_child = $offer->{'max_no_of_child'};
				if ( !defined $max_child || $max_child =~ /^\s*$/ || $max_child =~ /null/i ) {
					$max_child = 0;
				}
				my $min_adv_days = $offer->{'min_days_in_advance'};
				if ( !defined $min_adv_days || $min_adv_days =~ /^\s*$/ || $min_adv_days =~ /null/i ) {
					$min_adv_days = 0;
				}
				my $max_adv_days = $offer->{'max_days_in_advance'};
				if ( !defined $max_adv_days || $max_adv_days =~ /^\s*$/ || $max_adv_days =~ /null/i ) {
					$max_adv_days = 0;
				}

				if ( $check_in ge $valid_from && $check_in le $valid_to ) {
					my $exclude_dates = from_json( $exclusive_days );

					##check exclude dates
					# print "1\n";
					my $is_exclude = 0;
					foreach my $ex ( @$exclude_dates ) {
						if ( $ex->{'exclusive_days'} eq $check_in ) {
							$is_exclude = 1;
							last;
						}
					}

					if ( $is_exclude ) {
						next;
					}
					# print "2\n";
					##check applicable day
					my $is_day_matched = 0;
					my $days_of_week_list = from_json( $days_of_week );
					if ( defined $days_of_week_list && scalar @$days_of_week_list ) {
						foreach my $d ( @$days_of_week_list ) {
							if ( $d->{'days_of_week'} =~ /$dow_string/i ) {
								$is_day_matched = 1;
							}
						}
					}

					unless ( $is_day_matched ) {
						next;
					}
					# print "3\n";
					# print $no_of_adult.'--'.$min_adult;
					if ( defined $min_adult && $min_adult !~ /^\s*$/ && $min_adult > 0 ) {
						if ( $no_of_adult < $min_adult ) {
							next;
						}
					}
					# print $no_of_adult.'--'.$max_adult;
					# print "4\n";
					if ( defined $max_adult && $max_adult !~ /^\s*$/ && $max_adult > 0 ) {
						if ( $no_of_adult > $max_adult ) {
							next;
						}
					}

					if ( defined $min_child && $min_child !~ /^\s*$/ && $min_child > 0 ) {
						if ( $no_of_child < $min_child ) {
							next;
						}
					}
					# print "5\n";
					if ( defined $max_child && $max_child !~ /^\s*$/ && $max_child > 0 ) {
						if ( $no_of_child > $max_child ) {
							next;
						}
					}
					# print "6\n";
					if ( defined $min_adv_days && $min_adv_days !~ /^\s*$/ && $min_adv_days > 0 ) {
						if ( $adv_days < $min_adv_days ) {
							next;
						}
					}
					# print "7\n";
					if ( defined $max_adv_days && $max_adv_days !~ /^\s*$/ && $max_adv_days > 0 ) {
						if ( $adv_days > $max_adv_days ) {
							next;
						}
					}
					# print "8\n";
					if ( defined $decided_room_offers && scalar keys %$decided_room_offers ) {
						my $offer_rooms = $offer->{'room_list'};

						my $current_room_list = from_json( $offer_rooms );

						foreach my $x (@$current_room_list) {
							my $room_id = $x->{'room_list'};

							if ( exists $decided_room_offers->{$room_id}->{$pas_key} ) {
								if ( $offer->{'discount_percentage'} > $decided_room_offers->{$room_id}->{$pas_key}->{'discount_percentage'} ) {
									$decided_room_offers->{$room_id}->{$pas_key} = {
										'name' => $offer->{'name'},
										'name_it' => $offer->{'name_it'},
										'name_fr' => $offer->{'name_fr'},
										'name_es' => $offer->{'name_es'},
										'name_de' => $offer->{'name_de'},

										'description' => $offer->{'description'},
										'image' => $::config{'base_url'}->{'image_base_offer'}.$offer->{'image'},
										'discount_percentage' => $offer->{'discount_percentage'}
									};
								}
							}
							else {
								$decided_room_offers->{$room_id}->{$pas_key} = {
									'name' => $offer->{'name'},
									'name_it' => $offer->{'name_it'},
									'name_fr' => $offer->{'name_fr'},
									'name_es' => $offer->{'name_es'},
									'name_de' => $offer->{'name_de'},
									'description' => $offer->{'description'},
									'image' => $::config{'base_url'}->{'image_base_offer'}.$offer->{'image'},
									'discount_percentage' => $offer->{'discount_percentage'}
								};
							}
						}
					}
					else {
						my $offer_rooms = $offer->{'room_list'};

						my $current_room_list = from_json( $offer_rooms );
						foreach my $x (@$current_room_list) {
							my $room_id = $x->{'room_list'};

							$decided_room_offers->{$room_id}->{$pas_key} = {
								'name' => $offer->{'name'},
								'name_it' => $offer->{'name_it'},
								'name_fr' => $offer->{'name_fr'},
								'name_es' => $offer->{'name_es'},
								'name_de' => $offer->{'name_de'},
								'description' => $offer->{'description'},
								'image' => $::config{'base_url'}->{'image_base_offer'}.$offer->{'image'},
								'discount_percentage' => $offer->{'discount_percentage'}
							};
						}
					}
				}
			}
		}
	}
	
	# print Dumper $decided_room_offers;
	$class->{'decided_room_offers'} = $decided_room_offers;

	return 1;
}

sub get_coupon_detail {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $class->{'hotel_id'};
	my $promo_code = $cgi_params->{'promo_code'};
	my $today_date = ::get_today_day();

	my $whr->{'hotel_id'} = $hotel_id;
	$whr->{'code'} = $promo_code;
	
	$whr = [
		$whr,
		'AND',
		"'$today_date' BETWEEN valid_from AND valid_to"
	];

	my $coupon_data = undef;
	eval {
		$coupon_data = $class->{'obj_database'}->get({
			'table'  => 'coupons',
			'hash'   => 1,
			'select' => '*',
			'where'  => $whr
		});
	};

	if ( defined $coupon_data && scalar @$coupon_data ) {
		$class->{'coupon_detail'} = $coupon_data->[0];
	}
	else {
		$class->{'coupon_detail'} = {};
	}
	
	return 1;
}

sub check_param_validation {
	my $class = shift;
	
	my $cgi_params  = $class->{'cgi_params'};
	my $check_in    = $cgi_params->{'check_in'};
	if ( !defined $check_in || $check_in =~ /^\s*$/ ) {
		if ( exists $cgi_params->{'t-start'} && $cgi_params->{'t-start'} !~ /^\s*$/ ) {
			$check_in = $cgi_params->{'t-start'};
			$cgi_params->{'check_in'} = $cgi_params->{'t-start'};
		}
	}

	my $check_out   = $cgi_params->{'check_out'};
	if ( !defined $check_out || $check_out =~ /^\s*$/ ) {
		if ( exists $cgi_params->{'t-end'} && $cgi_params->{'t-end'} !~ /^\s*$/ ) {
			$check_out = $cgi_params->{'t-end'};
			$cgi_params->{'check_out'} = $cgi_params->{'t-end'};
		}
	}

	my $search_params = $class->{'search_params'};

	##if checkin date not found
	if ( !$check_in || $check_in =~ /^\s*$/ ) {
		if ( exists $search_params->{'check_in'} && $search_params->{'check_in'} !~ /^\s*$/ ) {
			$check_in = $search_params->{'check_in'};
		}
		else {
			$check_in = ::get_today_day();
		}
		$cgi_params->{'check_in'} = $check_in;
	}
	if ( !$check_out || $check_out =~ /^\s*$/ ) {
		if ( exists $search_params->{'check_out'} && $search_params->{'check_out'} !~ /^\s*$/ ) {
			$check_out = $search_params->{'check_out'};
		}
		else {
			my $today_date = ::get_today_day();
			$check_out = ::add_one_day( $today_date );
		}
		
		$cgi_params->{'check_out'} = $check_out;
	}

	my $today_date = ::get_today_day();
	my $past_days  = ::get_delta_days( $today_date, $check_in );

	my $is_valid = 1;
	my $error_message = '';
	if ( $past_days < 0 ) {
		$error_message .= "Check In date should greater then today date";
		$error_message .= "<br/>";
		$is_valid = 0;
	}

	my $day_diff = ::get_delta_days( $check_in, $check_out );

	if ( $day_diff < 0 ) {
		$error_message .= "Please select proper Check In & Check Out date";
		$error_message .= "<br/>";
		$is_valid = 0;
	}
	if ( $error_message !~ /^\s*$/ ) {
		$error_message =~ s/<br\/>$//;
	}
	$cgi_params->{'no_of_night'} = $day_diff;

	$class->{'is_valid'} = $is_valid;
	$class->{'error_message'} = $error_message;

	$cgi_params->{'check_in_string'} = ::convert_date_to_string( $check_in, $cgi_params->{'lang'} );
	$cgi_params->{'check_out_string'} = ::convert_date_to_string( $check_out, $cgi_params->{'lang'} );
	
	return;
}

sub get_hotel_detail {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id = $cgi_params->{'hotel_id'} ;

	my $hotel_detail = undef;
	my $whr->{'hotel_code'} = $hotel_id;

	eval {
		$hotel_detail = $class->{'obj_database'}->get({
			'table'  => 'hotels',
			'hash'   => 1,
			'select' => '*',
			'where'  => $whr
		});
	};

	if ( defined $hotel_detail && scalar @$hotel_detail ) {
		$class->{'hotel_detail'} = $hotel_detail->[0];
	}
	else {
		$class->{'hotel_detail'} = {};
	}

	return 1;
}

sub get_extra_list {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $cgi_params->{'hotel_id'};

	my $extra_list = undef;
	eval {
		$extra_list = $class->{'obj_database'}->get({
			'table'  => 'extras',
			'hash'   => 1,
			'select' => '*',
			'where'  => {
				'hotel_id' => $hotel_id
			}
		});
	};

	if ( defined $extra_list && scalar @$extra_list ) {

		foreach my $extra ( @$extra_list ) {
			$extra->{'image'} = $::config{'base_url'}->{'image_base_extra'}.$extra->{'image'};
		}

		$class->{'extra_list'} = $extra_list;
	}
	else {
		$class->{'extra_list'} = [];
	}
	return;
}

sub store_booking_master {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};

	my $search_params      = $class->{'search_params'};
	my $final_room_details = $class->{'final_room_details'};
	my $selected_extras    = $class->{'selected_extras'};
	my $hotel_detail       = $class->{'hotel_detail'};

	my $no_of_room  = $search_params->{'no_of_room'};
	my $no_of_adult = $search_params->{'no_of_adult'};
	my $no_of_child = $search_params->{'no_of_child'};
	my $child_ages = '';
	if ( $no_of_child > 0 ) {
		for (my $i = 1; $i <= $no_of_child; $i++) {
			$child_ages .= $search_params->{'child_age_'.$i};
			$child_ages .= ", ";
		}
	}
	$child_ages =~ s/\,\s$//g;

	my $no_of_night = $search_params->{'no_of_night'};
	my $check_in    = $search_params->{'check_in'};
	my $check_out   = $search_params->{'check_out'};
	my $hotel_id    = $search_params->{'hotel_id'};

	my $first_name   = $cgi_params->{'first_name'};
	my $last_name   = $cgi_params->{'last_name'};
	my $email       = $cgi_params->{'email'};
	my $phone       = $cgi_params->{'phone'};
	my $arrival_time       = $cgi_params->{'arrival_time'};

	my $country     = $cgi_params->{'country'};
	my $category        = $cgi_params->{'card_type'};
	my $category_number      = $cgi_params->{'card_number'};
	my $category_name   = $cgi_params->{'card_holder'};
	my $category_code         = $cgi_params->{'card_cvv'};
	my $last_date = $cgi_params->{'card_expiry_date'};
	my $guest_comment    = $cgi_params->{'guest_note'};
	my $payment_type = $cgi_params->{'payment_type'};
	
	my $twin_double = $cgi_params->{'twin_double'};
	if ( defined $twin_double && $twin_double !~ /^\s*$/ ) {
        $guest_comment .= " You have requested a ".$twin_double." Bed";
	}

	$first_name =~ s/^\s*//g;
	$first_name =~ s/\s*$//g;
	$last_name =~ s/^\s*//g;
	$last_name =~ s/\s*$//g;
	$email =~ s/^\s*//g;
	$email =~ s/\s*$//g;
	$guest_comment =~ s/^\s*//g;
	$guest_comment =~ s/\s*$//g;

	$category_number =~ s/^\s*//g;
	$category_number =~ s/\s*$//g;
	$category_name =~ s/^\s*//g;
	$category_name =~ s/\s*$//g;
	$category_code =~ s/^\s*//g;
	$category_code =~ s/\s*$//g;
	$last_date =~ s/^\s*//g;
	$last_date =~ s/\s*$//g;

	my $ipaddr = $ENV{'REMOTE_ADDR'};

	my $total_extra_cost = 0;
	if ( defined $selected_extras && ref $selected_extras eq 'ARRAY' ) {
		foreach my $extra ( @$selected_extras ) {
			$total_extra_cost += $extra->{'total_price'};
		}
	}

	my $extras_json = undef;
	eval {
		$extras_json = to_json( $selected_extras );
	};

	my $gross_amount = 0;
	my $total_base_amount = 0;
	my $total_extra_person_amount = 0;
	my $total_discount = 0;
	foreach my $x (@$final_room_details) {
		$total_base_amount += $x->{'rate_segment'}->{'base_room_rate'};
		$total_extra_person_amount += $x->{'rate_segment'}->{'extra_adult_rate'};
		$total_extra_person_amount += $x->{'rate_segment'}->{'extra_child_rate'};
		$total_discount += $x->{'rate_segment'}->{'total_discount'};
	}
	$gross_amount = $total_base_amount + $total_extra_person_amount + $total_extra_cost;
	$gross_amount -= $total_discount;
	
	##booking status 0: before booking attempt status, 1: confirm, 2: cancel
	eval {
		$class->{'obj_database'}->set(
			'table' => 'booking_master',
			'insert' => {
				'hotel_id'         => $search_params->{'hotel_id'},
				'first_name'       => $first_name,
				'last_name'        => $last_name,
				'email'            => $email,
				'phone'            => $phone,
				'arrival_time'     => $arrival_time,
				'country'          => $country,
				'no_of_adult'      => $no_of_adult,
				'no_of_child'      => $no_of_child,
				'child_ages'       => to_json($search_params->{'child_ages'}),
				'guest_comment'    => $guest_comment,
				'check_in_date'    => $check_in,
				'check_out_date'   => $check_out,
				'ip_address'        => $ipaddr,
				'booking_status'    => 1,
				'total_base_amount' => $total_base_amount,
				'total_extra_person_amount' => $total_extra_person_amount,
				'currency'          => 'EUR',
				'total_discount'    => $total_discount,
				'extra_amount'      => $total_extra_cost,
				'gross_amount'      => $gross_amount,
				'category'          => $category,
				'category_name'     => $category_name,
				'numbers'           => $category_number,
				'last_date'         => $last_date,
				'category_code'     => $category_code,
				'selected_room_type' => to_json( $final_room_details ),
				'selected_extras'  => to_json( $selected_extras ),
				't_type'         => $payment_type,
				'create_date'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
				'modify_date'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
			},
		);

		$class->{'system_booking_id'} = $class->{'obj_database'}->last_insert_id();
	};
	if ( $@ ) {
		::log($@);
	}

	return 1;
}

sub cancel_booking {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};

	my $booking_ref_id = $cgi_params->{'booking_ref_id'};
	my $email = $cgi_params->{'email'};

	my $ipaddr = $ENV{'REMOTE_ADDR'};

	##booking status 0: before booking attempt status, 1: confirm, 2: cancel
	eval {
		$class->{'obj_database'}->set(
			'table' => 'booking_master',
			'update' => {
				'ip_address'        => $ipaddr,
				'booking_status'    => 2,
				'is_posted'         => 0,
				'attempt'           => 0,
				'modify_date'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
			},
			'where' => {
				'id' => $booking_ref_id
			}
		);
	};
	if ( $@ ) {
		return 0;
	}

	return 1;
}

sub fetch_booking_master_data {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $booking_ref_id = $cgi_params->{'booking_ref_id'};
	my $email          = $cgi_params->{'email'};

	##special condition for search booking external via guest or via user
	my $whr = {};
	$whr->{'id'} = $booking_ref_id;
	$whr->{'email'} = $email;

	my $get_booking_master_data = $class->{'obj_database'}->get({
		'table'  => 'booking_master',
		'hash'   => 1,
		'select' => '*',
		'where'  => $whr,
	});

	if ( defined $get_booking_master_data ) {
		$class->{'booking_master_data'} = $get_booking_master_data->[0];
	}
	else {
		$class->{'booking_master_data'} = {};
	}

	return 1;
}

sub get_agent_detail {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};

	my $user_id = $class->{'booking_master_data'}->{'agent_id'};
	if ( !defined $user_id || $user_id =~ /^\s*$/ ) {
		$user_id = $class->{'user_id'};
	}

	my $agent_detail = $class->{'obj_database'}->get({
		'table'  => 'user_master',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'id' => $user_id,
		}
	})->[0];

	if ( defined $agent_detail ) {
		$class->{'agent_detail'} = $agent_detail;
	}
	else {
		$class->{'agent_detail'} = {};
	}
	
	return 1;
}

sub send_email {
	my $class = shift;

	my $hotel_detail = $class->{'hotel_detail'};
	my $hotel_name = $hotel_detail->{'name'};
	my $hotel_email = $hotel_detail->{'reservation_email'};

	my $credential = $::config{'credential'};

    my $smtpserver   = $credential->{'EMAIL_HOST'};
	my $smtpport     = $credential->{'EMAIL_PORT'};
	my $smtpuser     = $credential->{'EMAIL_USER'};
	my $smtppassword = $credential->{'EMAIL_PASS'};

	use Email::Sender::Simple qw(sendmail);
	use Email::Sender::Transport::SMTPS ();
	use Email::Simple ();
	use Email::Simple::Creator ();
	use Email::MIME;

	my $transport = Email::Sender::Transport::SMTPS->new({
	 	host => $smtpserver,
	 	port => $smtpport,
	  	ssl  => "starttls",
	  	sasl_username => $smtpuser,
	  	sasl_password => $smtppassword,
	});

	my $booking_status = 'Confirmed';
	if ( $class->{'booking_master_data'}->{'booking_status'} == 2 ) {
		$booking_status = 'Cancelled';
	}

	my $from = $hotel_name." booking engine <".$credential->{'EMAIL_FROM'}.">";
	my $to = [ $class->{'booking_master_data'}->{'email'} ];

	if ( defined $hotel_email && $hotel_email !~ /^\s*$/ ) {
		push @$to, $hotel_email;
	}
	my $cc = $::config{'reservationemail'}->{'cc'};
	my $subject = "$booking_status Booking Voucher: #".$class->{'booking_master_data'}->{'id'};
	use Encode;
	my $body = Encode::decode( "utf8", $class->{'email_content'} );

	my @parts = (
	    Email::MIME->create(
	        attributes => {
	            content_type => "text/html",
	            disposition  => "attachment",
	            charset      => "UTF-8",
	            encoding     => "base64",
	        },
	        body_str => $body,
	    ),
	);

	my $email = Email::MIME->create(
	    header_str => [
	        From => $from,
	        To => $to,
	        Cc => $cc,
	        Subject => $subject,
	    ],
	    parts      => [ @parts ],
	);
	# my $email = Email::Simple->create(
	# 	header => [
	# 		To      => $to,
	# 		From    => $from,
	# 		Subject => $subject,
	# 	],
	# 	body => 'Testing',
	# );
	# $email->header_set( 'content-type' => 'text/html' );
	$email->charset_set( 'UTF-8' );
	$email->content_type_set( 'text/html' );
	eval {
		sendmail($email, { transport => $transport });
	};
	if ( $@ ) {
		print $@;
	}
}

sub send_request_email {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $guest_email = $cgi_params->{'email'};

	my $hotel_detail = $class->{'hotel_detail'};
	my $hotel_name = $hotel_detail->{'name'};
	my $hotel_email = $hotel_detail->{'reservation_email'};

	my $credential = $::config{'credential'};

    my $smtpserver   = $credential->{'EMAIL_HOST'};
	my $smtpport     = $credential->{'EMAIL_PORT'};
	my $smtpuser     = $credential->{'EMAIL_USER'};
	my $smtppassword = $credential->{'EMAIL_PASS'};

	use Email::Sender::Simple qw(sendmail);
	use Email::Sender::Transport::SMTPS ();
	use Email::Simple ();
	use Email::Simple::Creator ();
	use Email::MIME;

	my $transport = Email::Sender::Transport::SMTPS->new({
	 	host => $smtpserver,
	 	port => $smtpport,
	  	ssl  => "starttls",
	  	sasl_username => $smtpuser,
	  	sasl_password => $smtppassword,
	});

	my $from = $hotel_name." booking engine <".$hotel_email.">";
	my $to = [ $class->{'booking_master_data'}->{'email'} ];

	if ( defined $hotel_email && $hotel_email !~ /^\s*$/ ) {
		push @$to, $hotel_email;
	}
	my $cc = $::config{'reservationemail'}->{'cc'};
	my $subject = "Availability Inquiry Form";
	my $body = $class->{'email_content'};

	my @parts = (
	    Email::MIME->create(
	        attributes => {
	            content_type => "text/html",
	            disposition  => "attachment",
	            charset      => "UTF-8",
	            encoding     => "base64",
	        },
	        body_str => $body,
	    ),
	);

	my $email = Email::MIME->create(
	    header_str => [
	        From => $from,
	        To => $to,
	        Cc => $cc,
	        'Reply-To' => $guest_email,
	        Subject => $subject,
	    ],
	    parts      => [ @parts ],
	);
	# my $email = Email::Simple->create(
	# 	header => [
	# 		To      => $to,
	# 		From    => $from,
	# 		Subject => $subject,
	# 	],
	# 	body => 'Testing',
	# );
	# $email->header_set( 'content-type' => 'text/html' );
	$email->content_type_set( 'text/html' );
	eval {
		sendmail($email, { transport => $transport });
	};
	if ( $@ ) {
		print $@;
	}
}

sub get_currency_conversion_ratio {
	my $class = shift;

	my $currency_ratio = undef;
	eval {
		$currency_ratio = $class->{'obj_database'}->get_record_with_limit({
			'table'  => 'currency_converter_master',
			'hash'   => 1,
			'select' => '*',
			'key' => 'source'
		});
	};
	
	if ( defined $currency_ratio ) {
		$class->{'currency_ratio_list'} = $currency_ratio;
	}
	else {
		$class->{'currency_ratio_list'} = {};
	}

	return 1;
}

sub get_commission_list {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $params_data = $class->{'params_data'};

	my $start_date = $cgi_params->{'check_in_date'} || $params_data->{'check_in_date'};
	my $end_date   = $cgi_params->{'check_out_date'} || $params_data->{'check_out_date'};
	
	my $whr->{'is_active'} = 'Y';

	my $get_commission_data = undef;
	eval {
		$get_commission_data = $class->{'obj_database'}->get({
			'table'  => 'commission',
			'hash'   => 1,
			'select' => 'start_date, end_date, addition, percentage',
			'where'  => $whr
		});
	};
	if ($@) {
		# handle failure...
	}

	my $day_diff = date($end_date) - date($start_date);
	
	my $commission_date_hash = {};
	my $is_all_commission_set = 0;
	my $higher_percentage_commission = 0;
	if ( scalar @$get_commission_data ) {
		foreach my $data ( @$get_commission_data ) {
			my $db_start_date = $data->{'start_date'};
			my $db_end_date   = $data->{'end_date'};

			$db_start_date =~ s/-//g;
			$db_end_date   =~ s/-//g;

			for( my $i = 0; $i < $day_diff; $i++ ) {
				my $stay_date = date($start_date) + $i;

				my $temp_date = $stay_date;
				$temp_date =~ s/-//g;
				
				if ( $temp_date >= $db_start_date && $temp_date <= $db_end_date ) {
					$commission_date_hash->{$stay_date}->{'addition'} += $data->{'addition'};
					$commission_date_hash->{$stay_date}->{'percentage'} += $data->{'percentage'};
				}

				if ( $higher_percentage_commission < $data->{'percentage'} ) {
					$higher_percentage_commission = $data->{'percentage'};
				}
			}

			if ( $data->{'destination_code'} =~ /^ALL$/ ) {
				$is_all_commission_set = 1;
			}
		}
	}

	##if global commission is not set then default 10
	# unless ( $is_all_commission_set ) {
	# 	for( my $i = 0; $i < $day_diff; $i++ ) {
	# 		my $stay_date = date($start_date) + $i;

	# 		$commission_date_hash->{$stay_date}->{'addition'} += 0;
	# 		$commission_date_hash->{$stay_date}->{'percentage'} += 10;
	# 	}
	# }	

	# print Dumper $commission_date_hash;
	$class->{'commission_data'} = $commission_date_hash;
	$class->{'higher_percentage_commission'} = $higher_percentage_commission;
}

sub get_provider_community_id {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};

	#Fetch Hotel list
	if ( defined $cgi_params->{'community'} && $cgi_params->{'community'} !~ /^\s*$/ ) {
		my $community_detail = $class->{'obj_database'}->get({
			'table'  => 'community_master',
			'hash'   => 1,
			'select' => 'community_id, global_community_id',
			'where'  => {
				'id' => $cgi_params->{'community'},
			}
		})->[0];

		if ( defined $community_detail ) {
			if ( defined $community_detail->{'community_id'} && $community_detail->{'community_id'} !~ /^\s*$/ && $community_detail->{'community_id'} !~ /null/i ) {
				$cgi_params->{'ciirus_community_id'} = $community_detail->{'community_id'};	
			}
			else {
				$cgi_params->{'ciirus_community_id'} = '';
			}

			if ( defined $community_detail->{'global_community_id'} && $community_detail->{'global_community_id'} !~ /^\s*$/ && $community_detail->{'global_community_id'} !~ /null/i ) {
				$cgi_params->{'global_community_id'} = $community_detail->{'global_community_id'};	
			}
			else {
				$cgi_params->{'global_community_id'} = '';
			}
		}
	}
	else {
		$cgi_params->{'ciirus_community_id'} = '';
		$cgi_params->{'global_community_id'} = '';
	}
	
	return 1;
}

sub get_next_prev_available_rooms {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $cgi_params->{'hotel_id'};
	my $check_in   = $cgi_params->{'check_in'};
	my $check_out  = $cgi_params->{'check_out'};
	my $no_of_night = $cgi_params->{'no_of_night'};

	my $today_date = ::get_today_day();
	my $before_check_in_days = ::get_delta_days( $today_date, $check_in );
	
	my $calendar_start_date = '';
	my $calendar_end_date = '';
	if ( $before_check_in_days > 9 ) {
		$calendar_start_date = ::add_number_of_day( $check_in, -9 );
		$calendar_end_date   = ::add_number_of_day( $check_out, 9 );
	}
	else {
		$calendar_start_date = $today_date;
		my $total = 20 - $no_of_night - $before_check_in_days;
		$calendar_end_date   = ::add_number_of_day( $check_out, $total );
	}

	my $covered_month_hash = {};
	my $calendar_days = [];

	my $temp_date_hash = {};
	my $inventory_data_hash = {};
	if ( $calendar_start_date && $calendar_end_date ) {
		my $whr->{'hotel_id'} = $hotel_id;

		$whr = [
			$whr,
			'AND',
			"date >= '$calendar_start_date' AND date <= '$calendar_end_date'"
		];

		my $inventory_data = undef;
		eval {
			$inventory_data = $class->{'obj_database'}->get({
				'table'  => 'inventory_masters',
				'hash'   => 1,
				'select' => 'date, room_type_id, availability',
				'where'  => $whr
			});
		};

		if ( defined $inventory_data && scalar @$inventory_data ) {
			my $is_set = 0;
			foreach my $data ( @$inventory_data ) {
				my ( $y, $m, $d ) = split('-', $data->{'date'});
				$covered_month_hash->{$m} = {
					'm' => $m,
					'y' => $y
				};

				my $dow = ::get_day_of_week( $data->{'date'} );

				$temp_date_hash->{$data->{'room_type_id'}}->{$data->{'date'}} = {
					'date' => $data->{'date'},
					'day'  => $::single_digit_dow_single_char->{$dow},
					'inventory' => $data->{'availability'}
				};
			}
		}
	}

	my $calendar_day_diff = ::get_delta_days( $calendar_start_date, $calendar_end_date );
	for (my $i = 0; $i < $calendar_day_diff; $i++) {
		my $stay_date = ::add_number_of_day( $calendar_start_date, $i );

		my ( $y, $m, $d ) = split('-', $stay_date);
		my $dow = ::get_day_of_week( $stay_date );

		push @$calendar_days, {
			'day'  => $::single_digit_dow_single_char->{$dow},
			'date' => $d
		};
	}
	
	my $avail_room_date_group = {};
	my $distinct_room_ids = '';
	foreach my $room_type_id ( keys %$temp_date_hash ) {
		my $dates = $temp_date_hash->{$room_type_id};

		my $avail_segment = [];
		my $temp_group = [];
		my $prev_date = undef;
		for (my $i = 0; $i < $calendar_day_diff; $i++) {
			my $stay_date = ::add_number_of_day( $calendar_start_date, $i );
			my $dow = ::get_day_of_week( $stay_date );

			if ( exists $temp_date_hash->{$room_type_id}->{$stay_date} ) {
				push @{$inventory_data_hash->{$room_type_id}}, {
					'date' => $stay_date,
					'day'  => $::single_digit_dow_single_char->{$dow},
					'inventory' => $temp_date_hash->{$room_type_id}->{$stay_date}->{'inventory'}
				};
			}
			else {
				push @{$inventory_data_hash->{$room_type_id}}, {
					'date' => $stay_date,
					'day'  => $::single_digit_dow_single_char->{$dow},
					'inventory' => 0
				};
			}

			if ( $temp_date_hash->{$room_type_id}->{$stay_date}->{'inventory'} > 0 ) {
				if ( scalar @$temp_group ) {
					my $f_date = $temp_group->[0];
					my $l_date = $temp_group->[scalar @$temp_group - 1];

					my $day_diff = ::get_delta_days( $l_date, $stay_date );
					if ( $day_diff == 1 ) {
						push @$temp_group, $stay_date;

						if ( scalar @$temp_group == $no_of_night ) {
							push @$avail_segment, $temp_group;
							$temp_group = [];
						}
					}
				}
				else {
					push @$temp_group, $stay_date;
					if ( scalar @$temp_group == $no_of_night ) {
						push @$avail_segment, $temp_group;
						$temp_group = [];
					}
				}
			}
		}

		$distinct_room_ids .= $room_type_id.",";
		$avail_room_date_group->{$room_type_id} = $avail_segment;
	}
	$class->{'calendar_inventory_data_hash'} = $inventory_data_hash;
	$distinct_room_ids =~ s/,$//g;

	my $final_avail_segment = [];
	my $min_price = undef;
	if ( defined $distinct_room_ids && $distinct_room_ids !~ /^\s*$/ ) {
		my $whr->{'hotel_id'} = $hotel_id;
		$whr = [
			$whr,
			"AND",
			"room_type_id IN ($distinct_room_ids)"
		];

		eval {
			$min_price = $class->{'obj_database'}->get({
				'table'  => 'rate_plans',
				'select' => 'min(room_price)',
				'where'  => $whr
			})->[0]->[0];
		};
	}

	foreach my $room_type_id ( keys %$avail_room_date_group ) {
		my $seg = $avail_room_date_group->{$room_type_id};
		if ( scalar @$seg >= 2 ) {
			##seg 1
			my $sd = $seg->[0]->[0];
			my $dow = ::get_day_of_week( $sd );
			my $sdw = $::single_digit_dow_short->{$dow};

			my $ed = $seg->[0]->[-1];
			$ed = ::add_one_day( $ed );
			$dow = ::get_day_of_week( $ed );
			my $edw = $::single_digit_dow_short->{$dow};

			my ( $y, $m, $d ) = split('-', $sd);
			$sd = $d." ".$::single_digit_month->{$m};

			( $y, $m, $d ) = split('-', $ed);
			$ed = $d." ".$::single_digit_month->{$m};

			my $n = scalar @{$seg->[0]};
			push @$final_avail_segment, {
				'price' => $min_price,
				'date_string' => $sd." - ".$ed,
				'night' => $n,
				'day' => $sdw.'-'.$edw
			};

			#seg last
			$sd = $seg->[-1]->[0];
			$dow = ::get_day_of_week( $sd );
			$sdw = $::single_digit_dow_short->{$dow};

			$ed = $seg->[-1]->[-1];
			$ed = ::add_one_day( $ed );
			$dow = ::get_day_of_week( $ed );
			$edw = $::single_digit_dow_short->{$dow};

			( $y, $m, $d ) = split('-', $sd);
			$sd = $d." ".$::single_digit_month->{$m};

			( $y, $m, $d ) = split('-', $ed);
			$ed = $d." ".$::single_digit_month->{$m};

			$n = scalar @{$seg->[-1]};
			push @$final_avail_segment, {
				'price' => $min_price,
				'date_string' => $sd." - ".$ed,
				'night' => $n,
				'day' => $sdw.'-'.$edw
			};
		}

		last if scalar @$final_avail_segment >= 2;
	}

	my $covered_month = [];
	foreach my $m ( sort keys %$covered_month_hash ) {
		my $month = $::single_digit_month->{$m};
		my $year  = $covered_month_hash->{$m}->{'y'};
		$year =~ s/(\d{2})(\d{2})/$2/;

		push @$covered_month, "$month $year";
	}
	$class->{'covered_month'} = $covered_month;
	$class->{'calendar_days'} = $calendar_days;
	$class->{'final_avail_segment'} = $final_avail_segment;

	return 1;
}

sub booking_param_validation {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};

	my $params = [{
			'caption' => 'first_name',
			'label'   => 'First Name'
		},
		{
			'caption' => 'email',
			'label'   => 'Email'
		},
		{
			'caption' => 'phone',
			'label'   => 'Phone'
		}
	];

	if ( $cgi_params->{'payment_type'} =~ /^cc$/i ) {
		push @$params, {
			'caption' => 'card_number',
			'label'   => 'Card Number'
		};
		push @$params, {
			'caption' => 'card_expiry_date',
			'label'   => 'Card Expiry Date'
		};
		push @$params, {
			'caption' => 'card_holder',
			'label'   => 'Card Holder'
		};
	}

	# print Dumper $cgi_params;

	my $string = '';
	foreach my $rec ( @$params ) {
		my $param = $rec->{'caption'};
		my $label = $rec->{'label'};

		if ( !defined $cgi_params->{$param} || $cgi_params->{$param} =~ /^\s*$/ ) {
			$string .= "$label is missing <br/>";
		}
		if ( $param =~ /email/i ) {
			if ( $cgi_params->{$param} !~ /.*?\@.*/ ) {
				$string .= "$label is Wrong <br/>";
			}
		}
		if ( $param =~ /phone/i ) {
			if ( length($cgi_params->{$param}) < 10 ) {
				$string .= "$label is Wrong <br/>";
			}
		}
		if ( $param =~ /card_number/i ) {
			if ( length($cgi_params->{$param}) < 16 ) {
				$string .= "$label is Wrong <br/>";
			}
		}
	}

	if ( $string !~ /^\s*$/ ) {
		$class->{'error_string'} = $string;
		return 0;
	}

	return 1;
}

1;
