package Cyber::Service;
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;

#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 = $cgi_params->{'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;
	}
	
	return 0;
}

sub get_service_list {
	my $class = shift;

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

	my $service_list = $class->{'obj_database'}->get_record_with_limit({
		'table'  => 'services',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'hotel_id' => $hotel_id
		},
		'order' => 'display_order'
	});

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

sub store_booking_master {
	my $class = shift;

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

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

	my $hotel_id     = $cgi_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 $country      = $cgi_params->{'country'};

	my $city         = $cgi_params->{'city'};
	my $state        = $cgi_params->{'state'};
	my $street_address = $cgi_params->{'street_address'};
	my $zip          = $cgi_params->{'zip'};
	my $guest_note   = $cgi_params->{'guest_note'};

	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'};

	$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;
	$phone =~ s/^\s*//g;
	$phone =~ s/\s*$//g;

	$city =~ s/^\s*//g;
	$city =~ s/\s*$//g;
	$state =~ s/^\s*//g;
	$state =~ s/\s*$//g;
	$street_address =~ s/^\s*//g;
	$street_address =~ s/\s*$//g;
	$zip =~ s/^\s*//g;
	$zip =~ s/\s*$//g;

	####################
	my $string_gen  = String::Random->new;
    my $dk = $string_gen->randregex('\d{32}');
    $dk =~ s/^\s*//g;
	$dk =~ s/\s*$//g;

	my ( $str1, $str2, $str3 ) = ::encrypt_second_level($dk, $category_number, $category_code );
	####################

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

	my $total_discount = 0;
	my $service_grand_total = 0;
	if ( defined $selected_service_details && ref $selected_service_details eq 'ARRAY' ) {
	    foreach my $x ( @$selected_service_details ) {
	        my $service_price = 0;
	        if ( exists $x->{'price'} && $x->{'price'} > 0 ) {
	            $service_price += sprintf("%.2f", $x->{'price'});
	        }
	        if ( exists $x->{'tax'} && $x->{'tax'} > 0 ) {
	            $service_price += sprintf("%.2f", $x->{'tax'}); 
	        }

	        my $this_service_count = $x->{'no_of_service'};
	        if ( !defined $this_service_count || $this_service_count == 0 ) {
	            $this_service_count = 1;
	        }
	        my $final_service_price = $this_service_count * $service_price;

	        $x->{'final_service_price'} = $final_service_price;

	        $service_grand_total += $final_service_price;
	    }
	}

	my $after_discount_amount = $service_grand_total - $total_discount;
	
	##booking status 0: before booking attempt status, 1: confirm, 2: cancel
	eval {
		$class->{'obj_database'}->set(
			'table' => 'service_booking_master',
			'insert' => {
				'hotel_id'         => $search_params->{'hotel_id'},
				'first_name'       => $first_name,
				'last_name'        => $last_name,
				'email'            => $email,
				'phone'            => $phone,
				'city'             => $city,
				'country'          => $country,
				'state'            => $state,
				'street_address'   => $street_address,
				'zip'              => $zip,
				'category'         => $category,
				'category_name'    => $category_name,
				'category_number'  => $str1,
				'last_date'        => $last_date,
				'ip_address'       => $ipaddr,
				'booking_status'   => 1,
				'currency'         => 'EUR',
				'total_discount'   => $total_discount,
				'grand_amount'     => $service_grand_total,
				'after_discount_amount' => $after_discount_amount,
				'selected_services' => to_json( $selected_service_details ),
				'tt1'         => $dk,
				'tt2'         => $str3,
				'guest_comment'    => $guest_note,
				'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' => 'service_booking_master',
			'update' => {
				'ip_address'     => $ipaddr,
				'booking_status' => 2,
				'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'  => 'service_booking_master',
		'hash'   => 1,
		'select' => '*',
		'where'  => $whr,
	});

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

	return 1;
}

sub get_booking_master_data {
	my $class = shift;

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

	my $get_booking_master_data = $class->{'obj_database'}->get({
		'table'  => 'service_booking_master',
		'hash'   => 1,
		'select' => '*'
		# 'where' => {
		# 	'hotel_id' => 2
		# }
	});

	if ( defined $get_booking_master_data ) {
		$class->{'booking_master_data'} = $get_booking_master_data;
	}

	return 1;
}

sub update_booking_master_data {
	my $class = shift;
	my $booking_ref_id = shift;
	my $tt1 = shift;
	my $tt2 = shift;
	my $str1 = shift;
	my $str2 = shift;

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

	##booking status 0: before booking attempt status, 1: confirm, 2: cancel
	eval {
		$class->{'obj_database'}->set(
			'table' => 'service_booking_master',
			'update' => {
				'tt1' => $tt1,
				'tt2' => $tt2,
				'numbers' => $str1,
				'category_code' => $str2
			},
			'where' => {
				'id' => $booking_ref_id
			}
		);
	};
	if ( $@ ) {
		return 0;
	}

	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;
	}
	
	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;
	}

	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'
		}
	];

	# 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;
