<?php

use ATWS\AutotaskObjects\Entity;

class APIFunctions
{
   public $username;
   public $password;
   public $integrationCode;

   function __construct()
   {
      require_once __DIR__ . '/src/autoload.php';
      require_once 'security_credentials.php';

      $this->username = $APIUsernameSandbox;
      $this->password = $APIPasswordSandbox;
      $this->integrationCode = $APIIntegrationIdentifierSandbox;
   }

   public function autoTaskAuth($username, $password, $integrationCode)
   {
      $authWsdl = 'https://webservices.autotask.net/atservices/1.5/atws.wsdl';
      $opts = array('trace' => 1);
      $client = new ATWS\Client($authWsdl, $opts);
      $zoneInfo = $client->getZoneInfo($username);
      $authOpts = array(
         'login' => $username,
         'password' => $password,
         'trace' => 1,   // Allows us to debug by getting the XML requests sent
      );
      $wsdl = str_replace('.asmx', '.wsdl', $zoneInfo->getZoneInfoResult->URL);
      $client = new ATWS\Client($wsdl, $authOpts);
      $client->setIntegrationCode($integrationCode);

      return $client;
   }

   public function createClient($clientName, $clientType = 1, $clientManager = 29682886, $clientPhoneNumber)
   {
      //create account object - account refers to client
      $account = new ATWS\AutotaskObjects\Account();
      //required fields
      $account->id = 0;
      $account->AccountName = $clientName;
      $account->AccountType = $clientType;
      $account->OwnerResourceID = $clientManager;
      $account->Phone = $clientPhoneNumber;

      $client = $this->autoTaskAuth($this->username, $this->password, $this->integrationCode);
      $result = $client->create($account);

      $clientID = $result->createResult->EntityReturnInfoResults->EntityReturnInfo->EntityId;
      return array("clientID" => $clientID, "result" => $result->createResult);
   }

   public function updateClient($clientID, $clientName, $clientType = 1, $clientManager = 29682886, $clientPhoneNumber)
   {
      //create account object - account refers to client
      $account = new ATWS\AutotaskObjects\Account();
      //required fields
      $account->id = $clientID;
      $account->AccountName = $clientName;
      $account->AccountType = $clientType;
      $account->OwnerResourceID = $clientManager;
      $account->Phone = $clientPhoneNumber;

      $client = $this->autoTaskAuth($this->username, $this->password, $this->integrationCode);
      $result = $client->update($account);

      $clientID = $result->createResult->EntityReturnInfoResults->EntityReturnInfo->EntityId;
      return array("clientID" => $clientID, "result" => $result->updateResult);
   }

   public function customQuery($queryEntity, $queryField, $userdefinedField = false, $queryOperator, $queryExpressionValue)
   {
      //different operators
      //Equals, NotEqual, GreaterThan, LessThan, GreaterThanorEquals, LessThanOrEquals, BeginsWith, EndsWith, Contains, IsNotNull, IsNull, IsThisDay, Like, NotLike

      $client = $this->autoTaskAuth($this->username, $this->password, $this->integrationCode);

      //query building process
      $query = new ATWS\AutotaskObjects\Query($queryEntity); //the entity(table) you want to query from (FROM)
      $querySpecs = new ATWS\AutotaskObjects\QueryField($queryField, $userdefinedField); //the field(column) in the entity(table) you want to query (SELECT)
      $querySpecs->addExpression($queryOperator, $queryExpressionValue); //basically the equavalent of the where clause in sql statments (WHERE)
      $query->addField($querySpecs);

      $result = $client->query($query);

      return $result->queryResult;
   }

   public function queryClient($clientName)
   {
      $blnResult = "";

      $rst = $this->customQuery("Account", 'AccountName', null, 'Equals', $clientName);

      if (empty($rst->EntityResults->Entity)) {
         $blnResult =  false;
      } else {
         $blnResult =  true;
      }

      return array("clientID" => $rst->EntityResults->Entity->id, "blnResult" => $blnResult, "result" => $rst->EntityResults);
   }

   public function createOpportunity($ownerResourceID, $clientAccountID, $eitQuoteNumber, $contactID)
   {
      //create opportunity object
      //required fields
      $opportunity = new ATWS\AutotaskObjects\Opportunity();
      $opportunity->id = 0;
      $opportunity->AccountID = $clientAccountID; //the company we are creating this opportunity/quote fpr
      $opportunity->ContactID = $contactID; //the company we are creating this opportunity/quote fpr
      $opportunity->Amount = 0;
      $opportunity->Cost = 0;
      $opportunity->Title = "EIT Opportunity:" . $eitQuoteNumber;
      $opportunity->CreateDate = date("Y/m/d"); //default create date will always be the day the opportunity is created
      $opportunity->ProjectedCloseDate =  date("Y-m-d", strtotime("+30 days")); //do we need to add this field to quotes as well or set default to month from create date?  
      $opportunity->OwnerResourceID = $ownerResourceID; //OpportunityOwner
      $opportunity->Stage = 29682769; //"new lead" stage int
      $opportunity->Status = 1; // default opportunity will be active
      $opportunity->Probability = 0; //default 0
      $opportunity->UseQuoteTotals = true;

      $client = $this->autoTaskAuth($this->username, $this->password, $this->integrationCode);

      $result = $client->create($opportunity);

      if (isset($result->createResult->Errors->ATWSError->Message)) { //if error message exists
         return array("result" => "Error: " . $result->createResult->Errors->ATWSError->Message, "blnError" => 1);
      } else {
         $createdOpportunityID = $result->createResult->EntityReturnInfoResults->EntityReturnInfo->EntityId;
         return array("createdOpportunityID" => $createdOpportunityID, "result" => $result->createResult, "blnError" => 0);
      }
   }

   public function createQuote($opportunityID, $eitQuoteNumber, $contactID, $billToLocationID = 1, $shipToLocationID = 1, $soldToLocationID = 1, $comment = "n/a")
   {
      //create quote object
      $quote = new ATWS\AutotaskObjects\Quote();
      //set fields to send to autotask
      $quote->id = 0;
      $quote->OpportunityID = $opportunityID; //a quote is linked to an opportunity
      //I think ContactID is the person we contact on the client side 
      //ContactID needs to be linked to the ClientID so if company is 1fortheroad for example then the ContactID must be someone at 1FortheRoad
      $quote->ContactID = $contactID;
      $quote->BillToLocationID = $billToLocationID; // Autotask needs an ID for the BillToLocation and not string like in eit quotes
      $quote->ShipToLocationID = $shipToLocationID; // Autotask needs an ID for the ShipToLocation and not string like in eit quotes
      $quote->SoldToLocationID = $soldToLocationID; // Autotask needs an ID for the SoldToLocation and not string like in eit quotes
      $quote->EffectiveDate = date("Y/m/d"); //default effective date will always be the day the quote is created
      $quote->ExpirationDate = date("Y-m-d", strtotime("+30 days")); //do we need to add this field to quotes as well or set default to month from create date?  
      $quote->Name = "EIT Quote:" . $eitQuoteNumber;;
      $quote->Description = "General";
      $quote->Comment = $comment; //I think Comment is the equivalent of notes section in eit quotes
      $quote->eQuoteActive = true; //needs to be true or else quote wont display

      $client = $this->autoTaskAuth($this->username, $this->password, $this->integrationCode);

      $result = $client->create($quote);

      if (isset($result->createResult->EntityReturnInfoResults->EntityReturnInfo->EntityId)) {
         $createdQuoteID = $result->createResult->EntityReturnInfoResults->EntityReturnInfo->EntityId;
         return array("createdQuoteID" => $createdQuoteID, "result" => $result->createResult, "blnError" => 0);
      } else {
         return array("result" => "Error: " . $result->createResult->Errors->ATWSError->Message, "blnError" => 1);
      }
   }

   public function createQuoteItem($quoteID, $name, $quantity, $type, $description, $periodType = "one-time")
   {
      //create quote item object
      $quoteItem = new ATWS\AutotaskObjects\QuoteItem();
      //set fields to send to autotask
      $quoteItem->id = 0;
      $quoteItem->QuoteID = $quoteID; //a quoteitem is linked to a quote
      $quoteItem->Name = $name;
      $quoteItem->IsOptional = false;
      $quoteItem->LineDiscount = 0;
      $quoteItem->PercentageDiscount = 0;
      $quoteItem->Quantity = $quantity;
      $quoteItem->Type = $type;
      $quoteItem->UnitDiscount = 0;
      $quoteItem->UnitPrice = 16;
      $quoteItem->PeriodType = $periodType;
      $quoteItem->Description = $description;
      // $quoteItem->MarkupRate = 8.0 //doesn't seem to work
      // $quoteItem->ServiceID = 1; // ServiceID only needed if quoteItem is Type: service

      $client = $this->autoTaskAuth($this->username, $this->password, $this->integrationCode);

      $result = $client->create($quoteItem);
      return array("result" => $result);
   }

   public function createQuoteLocation($address1, $address2 = null, $city = null, $postalCode = null, $state = null)
   {
      //create quote item object
      $quoteLocation = new ATWS\AutotaskObjects\QuoteLocation();
      //set fields to send to autotask
      $quoteLocation->id = 0;
      $quoteLocation->Address1 = $address1;
      $quoteLocation->Address2 = $address2;
      $quoteLocation->City = $city;
      $quoteLocation->PostalCode = $postalCode;
      $quoteLocation->State = $state;

      $client = $this->autoTaskAuth($this->username, $this->password, $this->integrationCode);

      $result = $client->create($quoteLocation);

      if (isset($result->createResult->EntityReturnInfoResults->EntityReturnInfo->EntityId)) {
         $createdQuoteLocationID = $result->createResult->EntityReturnInfoResults->EntityReturnInfo->EntityId;
         return array("createdQuoteLocationID" => $createdQuoteLocationID, "result" => $result->createResult, "blnError" => 0);
      } else {
         return array("result" => "Error: " . $result->createResult->Errors->ATWSError->Message, "blnError" => 1);
      }
   }

   public function generateAutoTaskQuote($emailFromEitQuotes, $nameFromEitQuotes, $eitQuoteNumber, $eitBillToAddress, $eitShipToAddress, $clientName, $comment)
   {
      //ini
      $contactID = 0;
      $billToLocationID = 1;
      $shipToLocationID = 1;
      $soldToLocationID = 1;
      $message = "";
      $errors = array();

      //break address from eit quotes into tokens 
      $eitBillToAddressTokens = explode(",", $eitBillToAddress);
      $this->print_rr($eitBillToAddressTokens);

      //get all locations that match first eit address token 
      //depending on how people entered address in eit quotes we may need to check in both Address1 and Address2 fields for match
      $rstBillToPhysicalLocation1 = $this->customQuery("QuoteLocation", 'Address1', null, 'Contains', $eitBillToAddressTokens[0]);
      // $this->print_rr($rstBillToPhysicalLocation1);

      $physicalLocation = "";
      $physicalLocationID = 0;
      $physicalLocationArr = array();
      if (isset($rstBillToPhysicalLocation1->EntityResults->Entity)) { //check if first query result contains data else make second query to check if Address2 field contains eitaddress
         // $this->print_rr("first query success");
         $physicalLocation = $rstBillToPhysicalLocation1->EntityResults->Entity;
      } else {
         // $this->print_rr("run second query");
         $rstBillToPhysicalLocation2 = $this->customQuery("QuoteLocation", 'Address2', null, 'Contains', $eitBillToAddressTokens[0]);
         if (isset($rstBillToPhysicalLocation2->EntityResults->Entity)) {
            $physicalLocation = $rstBillToPhysicalLocation2->EntityResults->Entity;
         } else { //if both result in no data then create new location and get id
            $message = "create new location and get id";
            //get and set new physicalLocationID
            // $physicalLocationID = 0;
         }
      }

      //only get here if there is unfiltered address data
      //in here we will filter and check the data and create a new location after filtering and checking is concluded and the address doesn't exist
      if ($physicalLocationID === 0) {
         if (isset($physicalLocation)) {
            if (gettype($physicalLocation) === "array") { //if it's an array there will be more than one address else there will only be one and we need to get the matching address id
               // $this->print_rr("test2");

               for ($i = 0; $i < count($physicalLocation); $i++) {
                  // $this->print_rr("test3");
                  // $this->print_rr($physicalLocation[$i]->Address1);
                  if (strpos($eitBillToAddress, $physicalLocation[$i]->Address1) !== false) {
                     array_push($physicalLocationArr, $physicalLocation[$i]->id);
                  } else { //if eit address string doesn't contain adresses from autotask then create new location and get id
                     $this->print_rr("create new location and get id");
                  }
               }
            } elseif (gettype($physicalLocation) === "object") {
               // $this->print_rr("test5");
               if (strpos($eitBillToAddress, $physicalLocation->Address1) !== false) {
                  array_push($physicalLocationArr, $physicalLocation->id);
               } else { //if eit address string doesn't contain adresses from autotask then create new location and get id
                  $this->print_rr("create new location and get id");
               }
            }

            if (!empty($physicalLocationArr)) {
               $billToLocationID = $physicalLocationArr[0];
               $shipToLocationID = $physicalLocationArr[0];
               $soldToLocationID = $physicalLocationArr[0];
            }
         }
      }

      die;

      //get OwnerResourceId based on user creating quote's name/email
      $rstUserName = $this->customQuery("Resource", 'FirstName', null, 'Like', $nameFromEitQuotes);
      // $rstUserEmail = $this->customQuery("Resource", 'Email', null, 'Like', $userEmailFromEITQuotes);
      $ownerResourceID = $rstUserName->EntityResults->Entity->id;

      //check if client exists using their name, can't use ID cause the id's in quotes and autotask are not the same
      $clientCheckResult = $this->queryClient($clientName);
      // $this->print_rr($clientCheckResult);

      if ($clientCheckResult["blnResult"] === true) { //if client exists create opportunity and quote, quoteitem(s) linked to it

         //get contact info of client using clientID
         $contactCheckResult = $this->customQuery("Contact", 'AccountID', null, 'Equals', $clientCheckResult['clientID']);

         if (gettype($contactCheckResult->EntityResults->Entity) === "array") { //use first contact if there is more than one for that specific client
            $contactID = $contactCheckResult->EntityResults->Entity[0]->id;
         } else if (gettype($contactCheckResult->EntityResults->Entity) === "object") { //if its only one, use that one
            $contactID = $contactCheckResult->EntityResults->Entity->id;
         }

         //create opportunity
         $opportunityCreateResult = $this->createOpportunity($ownerResourceID, $clientCheckResult['clientID'], $eitQuoteNumber, $contactID);
         // $this->print_rr($opportunityCreateResult);

         if ($opportunityCreateResult["blnError"] !== 1) { //if there are not errors in creating opportunity create quote

            //create quote
            $quoteCreateResult = $this->createQuote($opportunityCreateResult["createdOpportunityID"], $eitQuoteNumber, $contactID, $billToLocationID, $shipToLocationID, $soldToLocationID, $comment);
            // $this->print_rr($quoteCreateResult);

            if ($quoteCreateResult["blnError"] !== 1) {
               print_r("create quote items");
               $message = "Quote Has Been Successfully created in Autotask.";
            } else {
               $message = $quoteCreateResult["result"];
            }
         } else {  //if there are errors in creating opportunity display error message
            $message = $opportunityCreateResult["result"];
         }
      } else { //if client doesn't exist 
         $message = "client does not exist";
      }

      return $message;
   }



   /*-----------------------------------------------------------------util functions------------------------------------------------------------------*/
   /*------------------------------------------------------------------------------------------------------------------------------------------------*/
   public function print_rr($value, $blnString = false)
   {
      echo "<PRE>";
      print_r($value, $blnString);
      echo "</PRE>";
   }
}
