<?php

namespace Drupal\restaurant_bookings\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\restaurant\Form\AppForm;
use Drupal\restaurant\Bookings\Booking;
use Drupal\restaurant\Form\MultipartForm;
use Drupal\restaurant_bookings\Form\FormElements;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;


require_once get_restaurant_path(true) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'PHPMailer' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'PHPMailer.php';
require_once get_restaurant_path(true) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'PHPMailer' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'SMTP.php';
require_once get_restaurant_path(true) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'PHPMailer' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Exception.php';

class Data extends MultipartForm {

  /**
   * Returns a unique string identifying the form.
   *
   * The returned ID should be a unique string that can be a valid PHP function
   * name, since it's used in hook implementation names such as
   * hook_form_FORM_ID_alter().
   *
   * @return string
   *   The unique string identifying the form.
   */
  public function getFormId() {
    return 'bookings_data';
  }


  public function buildForm(array $form, FormStateInterface $form_state)
  {
    if ($this->getSetting('requirelogin')) {

      if (! \Drupal::currentUser()->isAuthenticated()) {
        $this->addMessage($this->t('Login required to make a booking'), 'error')->http_redirect('/user/login');
      }
    }


    $values = [
        'date' => $this->store->get('date'),
        'time' => $this->getParam('time'),
        'value' => 'Submit Booking'
    ];

    $this->getSession()->set('isadmin',  $this->inAdminPath());


    FormElements::Details($form);
    FormElements::BookingDate($form, array('time' => $this->getParam('time')));
    FormElements::Notes($form);
    FormElements::Emailconfirmation($form);
    FormElements::Submit($form);


    return $form;
  }

  public function validateForm(array &$form, FormStateInterface $form_state)
  {
    $url = $this->inAdminPath() ? '/admin/restaurant/bookings/data/' . $this->getParam('time') : '/bookings/data/' . $this->getParam('time');
    if ((empty($form_state->getValue('email'))) && (empty($form_state->getValue('firstname'))) && empty ($form_state->getValue('lastname'))) {
      $this->addMessage("One of either email address, firstname, or lastname is required", "error")->http_redirect($url);
    }
    if ( empty ($form_state->getValue('email')) && (empty($form_state->getValue('phone')))) {
      $this->addMessage("One of either email or phone is required", "error")->http_redirect($url);
    }

  }

  public function submitForm(array &$form, FormStateInterface $form_state)
  {
    $timepart = date('H:i:s', $this->getParam('time'));
    $datepart = $this->store->get('date');
    $bookingtime = $datepart . ' ' . $timepart;

    $data = $_POST;

    $email = (isset ($data['emailconfirmation'])) ? true : false;

    $data['bookingtime'] = $bookingtime;
    $data['guests'] = $this->store->get('guests');
    $remove = array('form_build_id', 'form_token', 'form_id', 'op', 'emailconfirmation');
    foreach ($remove as $val) {
        if (isset ($data[$val])) {
            unset ($data[$val]);
        }
    }

      $req = array();
      if (isset ($_POST['checkrequirements'])) {
          foreach ($_POST['checkrequirements'] as $key => $val) {
              $req[] = $key;
          }
          unset ($_POST['checkrequirements']);
      }
      unset ($data['checkrequirements']);


      $booking = new Booking($this->conn);
      $bookingid = $booking->makeBooking($data, $req);
      $row = $this->conn->query("SELECT * FROM restaurant_bookings WHERE id = ?", array($bookingid))->fetch();

      try {
      	$results  = $booking->getBookingResults($bookingid);
      	$html = $results->getTextEmail();

      	$this->addMessage("Booking successully created");
      } catch (\Exception $e) {
      	$this->addMessage("There was an error in creating your booking " . $e->getMessage(), "error");
      }


      if ($email) {

      	$mailer = new PHPMailer(true);
      	$mailer->isSMTP();
      	$mailer->isHTML(true);
      	$mailer->SMTPDebug  = 0;
			$mailer->SMTPAuth   = TRUE;
			$mailer->Host = $this->service->getSetting('SMTPHost');

			$config = \Drupal::config('system.site');
	    	$sitename = $config->get('name');
	    	$site_email = $config->get('mail');

      	switch ($_SERVER['SERVER_NAME']) {
      		case 'stage.acewebdevelopment.com.au':
      		case 'restauranthq.acewebdevelopment.com.au':
      		case 'restauranthq.acewebdevelopment.local':
			case 'restauranthq.local':
			case 'localhost':

      		if (! file_exists(get_restaurant_path() . '/devel.txt')) {
      			throw new \Exception("Development file devel.txt not present");
      		}
      		$mailer->Username = $this->service->getSetting('SMTPUsername');
      		$mailer->Password = trim(file_get_contents(get_restaurant_path(). '/devel.txt'));
      		$mailer->setFrom('webmaster@acewebdevelopment.com.au', 'Ace Web Development');
      		break;

      		default:
      			if (! empty ($this->service->getSetting('SMTPUsername'))) {
      				$mailer->Username = $this->service->getSetting('SMTPUsername');
      				$mailer->Password = $this->service->getSetting('SMTPPassword');
      			}

      			$mailer->setFrom($site_email, $sitename);
      	}

      	$protocol = $this->service->getSetting('SMTPSecure');
      	if (( $protocol == 'ssl') || ($protocol == 'tls')) {
      		$mailer->SMTPOptions = array(
    				'ssl' => array(
        				'verify_peer' => false,
        				'verify_peer_name' => false,
        				'allow_self_signed' => true
    				)
    			);
      	}
      	$mailer->addAddress($data['email'], $data['firstname']);
      	$mailer->Subject = 'Booking confirmation from ' . $sitename;
      	$mailer->Body = $results->getHtmlEmail();
			$mailer->AltBody = $results->getTextEmail();


			try {

        if ($this->getEnvironment() == 'demonstration') {
          \Drupal::messenger()->addMessage('Email is disabled in demonstration mode');
        } else {
          $mailer->send();
          \Drupal::messenger()->addMessage('Email sent to <strong>' . $data['email'] . '</strong>');
        }

			} catch (\Exception $e) {

				$this->addMessage("An error occured in sending your email. Please contact the system administrator for details" . $e->getMessage(), "error");
			}

			$url = ($this->inAdminPath()) ? '/admin/restaurant/bookings/confirm/id/' . $bookingid : '/bookings/confirm/';
            $this->http_redirect($url);

      }

  }

}
