<?php
namespace App\library\classes;

use Exception;
use \Carbon\Carbon;
use Geocoder\Exception\NoResult;
// use Elasticsearch;

class Import {
    public  $limit = 2000; // max limit of records per pull
    public $numDaysBack = 2; // full pull days to go back
    public $pullEnabled = 1;

    public function __construct($days = 1)
    {
        // echo 'This is the Mls Importer Class Constructor; Login: '.env('RETS_USER');
        $this->numDaysBack = $days;
    }

    public function updateListings(){
        echo 'Starting the UpdateListings function '.PHP_EOL;
        $lastUpdatedListing = \App\Listing::orderBy('updateDate', 'desc')->first();

        if($lastUpdatedListing != null) {
            $lastUpdateTime = new Carbon($lastUpdatedListing->updateDate);
            echo 'The updateDate of the last record added (MLS#'.$lastUpdatedListing->mlsNum.') was '.$lastUpdateTime.PHP_EOL;
            $now = Carbon::now(env('RETS_SERVER_TIMEZONE'));
            $startTime = $lastUpdateTime->format('Y-m-d\TH:i:s');
            $endTime = $now->format('Y-m-d\TH:i:s');

            if($startTime < $endTime ){
                echo PHP_EOL.'Performing an incremental update'. PHP_EOL;
                $this->updatePull($startTime,$endTime); // perform an incremental update from start to end
                echo 'Update Completed'. PHP_EOL.PHP_EOL;
            } else if($startTime > $endTime ){
                echo 'The data is up to date from a full pull that covered the time period '. PHP_EOL;
                echo 'startTime = '.$startTime. PHP_EOL;
                echo 'endTime = '.$endTime. PHP_EOL;
                echo 'Last record update date is '.$lastUpdateTime->format('Y-m-d\TH:i:s'). PHP_EOL. PHP_EOL;
            }
        } else {
            echo 'There are no listings in the database! '.PHP_EOL;
        }


    }

    public function updatePull($start,$finish){
        $pull = new \App\Pull;
        $pull->type = 'incremental';
        $pull->started = \Carbon\Carbon::now(env('RETS_SERVER_TIMEZONE'));
        $log = new \Monolog\Logger('PHRETS');
        $config = new \PHRETS\Configuration;
        $config->setLoginUrl(env('RETS_SERVER_URL'));
        $config->setUsername(env('RETS_USER'));
        $config->setPassword(env('RETS_PASSWORD'));
        $config->setRetsVersion(env('RETS_VERSION'));
        $rets = new \PHRETS\Session($config);
        try{
            $connect = $rets->Login();
        } catch(Exception $e){
            echo PHP_EOL.'Unable to connect to RETS Server: '.env('RETS_PROVIDER').PHP_EOL;
        }
        $query = '(L_UpdateDate='.$start.'-'.$finish.'),(L_AskingPrice=0-600000000),(L_Status=|1_0,1_1,1_2,2_0,3_0),(LM_Char10_1=|SanDiego)';
        echo $query.PHP_EOL.PHP_EOL;
        $pull->query = $query;
        $results = $rets->Search('Property', 'RE_1', $query, ['QueryType' => 'DMQL2','Format' => 'COMPACT-DECODED','Limit' => $this->limit]);
        $pull->started = \Carbon\Carbon::now(env('RETS_SERVER_TIMEZONE'));
        $hasRow = $results->count();
        echo 'There were '.$results->count().' total records pulled'. PHP_EOL;
        $pull->numRecords = 0;
        if($hasRow > 0) {
            foreach ($results as $record) {
                $resultArr = $this->importListing($record,$rets);
                if($resultArr['status'] == 'success'){
                    $pull->numRecords++;
                }

            }

            echo 'Added '.$pull->numRecords++.' listings: range: '.$start.' to '.$finish.PHP_EOL;

            $lastUpdatedListing = \App\Listing::orderBy('updateDate', 'desc')->first();
            echo 'Last listing added was MLS#'.$lastUpdatedListing->mlsNum.PHP_EOL;
            $lastUpdateTime = new Carbon($lastUpdatedListing->updateDate);
            $pull->lastRecordUpdatedDate = $lastUpdatedListing->updateDate;
            $pull->lastRecordMlsNum = $lastUpdatedListing->mlsNum;
            $pull->finished = Carbon::now(env('RETS_SERVER_TIMEZONE'));
            $pull->status = 'success';
        }



        $time = 0;
        $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
        echo "Process Time: ".round($time,2).PHP_EOL;
        $pull->elapsed_time = round($time,2);
        $pull->save();

    }



    public function mainPull($start,$finish){

        $limit = 2000;
        $closeRange =  45;
        $startString = $start->format('Y-m-d\TH:i:s');
        $endRangeString = $finish->format('Y-m-d\TH:i:s');
        $pull = new \App\Pull;
        $pull->type = 'full';
        $pull->started = Carbon::now(env('RETS_SERVER_TIMEZONE'));
        $log = new \Monolog\Logger('PHRETS');
        $config = new \PHRETS\Configuration;
        $config->setLoginUrl(env('RETS_SERVER_URL'));
        $config->setUsername(env('RETS_USER'));
        $config->setPassword(env('RETS_PASSWORD'));
        $config->setRetsVersion(env('RETS_VERSION'));
        $rets = new \PHRETS\Session($config);
        try{
            $connect = $rets->Login();
        } catch(Exception $e){
            echo PHP_EOL.'Unable to connect to RETS Server: '.env('RETS_PROVIDER').PHP_EOL;
        }

        $query = '(L_UpdateDate='.$startString.'-'.$endRangeString.'),(L_AskingPrice=0-600000000),(L_Status=|1_0,1_1,1_2,2_0,3_0),(LM_Char10_1=|SanDiego)';
        echo 'Query = '.$query.PHP_EOL;

        $pull->query = $query;
        if($this->pullEnabled == 1){
            $results = $rets->Search('Property', 'RE_1', $query, ['QueryType' => 'DMQL2','Format' => 'COMPACT-DECODED','Limit' => $limit]);
            //  $pull->started = \Carbon\Carbon::now('America/Los_Angeles');
            $hasRow = $results->count();
            $pull->numRecords = 0;
            if($hasRow > 0){
                foreach($results as $record){
                    $resultArr = $this->importListing($record,$rets);
                    if($resultArr['status'] == 'success'){
                        $pull->numRecords++;
                    }

                }
                $lastUpdatedListing = \App\Listing::orderBy('updateDate', 'desc')->first();
                $lastUpdateTime = new Carbon($lastUpdatedListing->updateDate);
                $pull->lastRecordUpdatedDate = $lastUpdatedListing->updateDate;
                $pull->lastRecordMlsNum = $lastUpdatedListing->mlsNum;
                $pull->finished = Carbon::now(env('RETS_SERVER_TIMEZONE'));

            }
        }

        $pull->status = 'success';


        echo 'Added '.$pull->numRecords++.' listings: range: '.$start.' to '.$finish.PHP_EOL.PHP_EOL;
        $time = 0;
        $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
        echo "Process Time: ".round($time,2).PHP_EOL;
        $pull->elapsed_time = round($time,2);
        $pull->save();

    }


    public function fullPull(){
        set_time_limit(0);
        ignore_user_abort(1);
        $dayCount = $this->numDaysBack + 1;

        $now = Carbon::now(env('RETS_SERVER_TIMEZONE'));
        $start = Carbon::now(env('RETS_SERVER_TIMEZONE'));
        $endRange = Carbon::now(env('RETS_SERVER_TIMEZONE'));
        $start->subDays($this->numDaysBack)->startOfDay();
        $endRange->subDays($this->numDaysBack)->endOfDay();

        echo 'Going '.$this->numDaysBack.' days back for pull'.PHP_EOL;
        echo $now.PHP_EOL;
        echo $start.PHP_EOL;


        while($start <= $now){

            $startString = $start->format('Y-m-d\TH:i:s');
            $endRangeString = $endRange->format('Y-m-d\TH:i:s');
            echo PHP_EOL.'Performing a Full Data Pull from '.env('RETS_PROVIDER').' RETS SERVER'.PHP_EOL;
            echo 'Retrieving Records for Date Range: '.$startString.' and '.$endRangeString.PHP_EOL;
            echo 'Starting '.$this->numDaysBack.' days back '.PHP_EOL;
            $this->mainPull($start,$endRange);
            $endRange->addDay();
            $start->addDay();
            $dayCount--;
            echo 'There are '.$dayCount.' days left for the full pull'.PHP_EOL.PHP_EOL;
            // exit("Break from execution");
        }

        $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
        echo "Process Time: {$time}".PHP_EOL;
    }



    public function importListingByListingID($mlsNum){

        $log = new \Monolog\Logger('PHRETS');
        $config = new \PHRETS\Configuration;
        $config->setLoginUrl(env('RETS_SERVER_URL'));
        $config->setUsername(env('RETS_USER'));
        $config->setPassword(env('RETS_PASSWORD'));
        $config->setRetsVersion(env('RETS_VERSION'));
        $rets = new \PHRETS\Session($config);

        try {
            $connect = $rets->Login();
            $query =  $query = '(L_ListingID='.trim($mlsNum).')';
            $results = $rets->Search('Property', 'RE_1', $query, ['QueryType' => 'DMQL2','Format' => 'COMPACT-DECODED','Limit' => '1']);
            $hasRow = $results->count();

            if($hasRow > 0){
                foreach ($results as $record) {
                    $this->importListing($record,$rets);
                }
            } else {
                echo 'No record with that listingID found';
            }

            $time = microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"];
            echo "Process Time: {$time}".PHP_EOL;
        } catch(Exception $e){
            echo 'Exception caught'.PHP_EOL;
            dd($e);
        }



    }


    public function importListing($record,$rets){
        $resultArr = array();
        $resultArr['status'] = 'failed';
        $resultArr['lastListingIDSaved'] = '';
       // dd($property);
        // rets raw property data imported and converted to array
        $property = $record->toArray();
        // dd($property);
        // get the photo links and convert to array
        $objects = $rets->GetObject('Property', 'Photo', $property['L_ListingID'], '*', 1);
        $objectsArr = $objects->toArray();
        $emptyArrFlag = 0;

        $imageArr = array();

        for($i = 0; $i < count($objectsArr); $i++){
            if($objectsArr[$i]->getLocation() == ''){
                if($i == 0){
                    $emptyArrFlag = 1;
                    break;
                }

            } else {
                $imageArr[$i] =  $objectsArr[$i]->getLocation();
            }

        }
        if($emptyArrFlag == 0) {
            // serialize photo array and add to property's images_serialized if images present
            $property['images_serialized'] = serialize($imageArr);
            // $testDesrialize = unserialize($property['images_serialized']);
            // dd($testDesrialize);
        } else {
            // create table for listings without images
            // add listing to table
            // get the time of insert
            // pull all records in the table
            // check the count of all records insert from time of insert back 1 minute
            // if count greater than 10 exit and send text
            // significance is that the images are being pulled and to alert sandicor that the image links are missing again
            echo 'WARNING! No images retrieved for mlsNum '.$property['L_ListingID'].PHP_EOL;
            $property['images_serialized'] = "";
        }

        $ESlisting = new \App\library\classes\ESListing(); // instantiate listing object
        $ESlisting->load($property); // load the property into the listing object

        // dd($ESlisting);
        // comment out the county for future MLS's and add any appropriate filter
        if($ESlisting->county == 'San Diego') {
            if($ESlisting->status == 'ACTIVE' || $ESlisting->status == 'BACK ON MARKET' || $ESlisting->status == 'CONTINGENT' || $ESlisting->status == 'PENDING' ||  $ESlisting->status == 'SOLD'){
                $responseResult = $ESlisting->save(); // save the listing object into elastic and return the response result
                // acceptable responses are created or updated
                if($responseResult == 'created' || $responseResult == 'updated'){
                    //dd($responseResult);
                    $prevRecord = \App\Listing::where('mlsNum','=',$ESlisting->mlsNum)->first();
                    //dd($record);
                    $tempListing = new \App\Listing;
                    $tempListing->load($ESlisting);
                    // dd($ESlisting->location);
                    //dd($tempListing);
                    if($prevRecord == null){
                        echo 'No listing has been saved yet with the mlsNum of '.$ESlisting->mlsNum.PHP_EOL;
                        try{
                            $tempListing->save();
                        } catch(Exception $e){
                            echo 'THERE WAS A QUERY EXCEPTION FOR MLSNUM '.$tempListing->mlsNum.PHP_EOL;
                            echo 'ATTEMPTING TO DELETE PREVIOUS RECORD AND TRY AGAIN!!!'.PHP_EOL;
                            $listingToDelete = \App\Listing::where('mlsNum','=',$tempListing->mlsNum);
                            if($listingToDelete != null){
                                $listingToDelete->delete();
                                echo 'OLD LISTING SUCCESSFULLY DELETED!'.PHP_EOL;
                            } else {
                                echo 'CANNOT DELETE THE LISTING BECAUSE IT DOESNT EXIST!!!'.PHP_EOL;
                            }
                            try{
                                $tempListing->save();
                            } catch(Exception $e){
                                echo 'CANNOT SAVE THE LISTING (MLS# '.$tempListing->mlsNum.' ) MOVING ON!!!'.PHP_EOL;
                            }
                            //dd($e);
                        }

                    } else {
                        $prevRecord->delete();
                        $tempListing->save();
                    }
                    $resultArr['status'] = 'success';
                    $resultArr['lastListingIDSaved'] = $tempListing->mlsNum;
                } else {
                    // the record was not saved into elasticsearch due to ES error!
                    // exit from script and send a text
                }

            } else {
                // listing not an acceptable status - Do Not Save Listing!
            }
        } else {
            // county is not San Diego - do not save the listing
        }

        return $resultArr;
    }



} 