<?php 

namespace frontend\jobs;
use Yii;
use yii\base\BaseObject;
use yii\httpclient\Client;
use PhpOffice\PhpSpreadsheet\IOFactory;
use backend\models\{Categoriesbe, Galleriesbe, Lookuptablebe, Productsbe, Sysmodels};
use yii\helpers\Json;

class Import_dbdata extends BaseObject implements \common\components\Queue\JobInterface
{

    public $id;
    public $schedule;
    public $limit;
    public $dateOverride;
    
    public function execute($queue)
    {
		echo "Starting Data Import".PHP_EOL;
        $sysmodel = Sysmodels::findOne(['id' => $this->id]);

        if($this->schedule == 'auto'){
            $schedule = $sysmodel->options->schedule;
            $day = strtolower(Date('l'));
            echo $day.PHP_EOL;
            $start = $day. '_start';
            $finish = $day. '_finish';
            $interval = $day. '_repeat';
            echo $schedule[$start] .PHP_EOL;
            if(date('H:i') <= $schedule[$finish] ){
                $delay = $schedule[$interval] * 60;
                Echo $delay;
                $runnow = true;
                Yii::$app->queue
                ->jobname('DataImport '. $sysmodel->destination)
                ->relatedid($this->id)
                ->delay($delay)
                ->ttr(7200)
                ->push(new self(['id' => $this->id, 'schedule' => 'auto']));
            } else {
                $runnow = false;
                $tomorrow = strtolower(date('l', strtotime('tomorrow')));
                $start = Date('Y-m-d ', strtotime('tomorrow')) . $schedule[$tomorrow. '_start'];
                echo $start.PHP_EOL;
                $delay = strtotime($tomorrow) - strtotime('now');
                echo $delay.PHP_EOL;
                Yii::$app->queue
                    ->jobname('DataImport '. $sysmodel->destination)
                    ->relatedid($this->id)
                    ->delay($delay)
                    ->ttr(7200)
                    ->push(new self(['id' => $this->id, 'schedule' => 'auto']));
            }
        } else {
            $runnow = true;
        }
        if($runnow == true){
            echo 'Model Copy'.PHP_EOL;
            echo  $sysmodel->destination.PHP_EOL;
            $models = $sysmodel->source::find();
            if(empty($this->dateOverride)){
                if (!empty($sysmodel->timeupdatedfield)){
                    $date = $sysmodel->lastdate;
                    $time = $sysmodel->lasttime;
                    empty(trim($date)) ? $date = date('Y-m-d') : false;
                    empty(trim($time)) ? $time = date('Hi', strtotime('-30 minutes')) : false;
                    $sysmodel->updateAttributes(['lasttime' => date('Hi', strtotime('-15 minutes')), 'lastdate' => Date('Y-m-d')]);
                    $models->andFilterWhere(['and', ['>=', $sysmodel->date_updated_field, $date], ['>=', $sysmodel->timeupdatedfield, intval($time)]]);
                    $models->orFilterWhere(['and',['>=', $sysmodel->date_created_field, $date], ['in',$sysmodel->date_updated_field, ['', null]]]);
                } else {

                    if(!empty($sysmodel->date_created_field) && !empty($sysmodel->date_updated_field)) {
                        $date = date('Y-m-d', strtotime("-$sysmodel->daysdown days"));
                        echo $date.PHP_EOL;
                        $models->andFilterWhere(['or', ['>=', $sysmodel->date_created_field, $date], ['>=', $sysmodel->date_updated_field, $date]]);
                    } elseif(!empty($sysmodel->date_created_field) && empty($sysmodel->date_updated_field)) {
                        $date = date('Y-m-d', strtotime("-$sysmodel->daysdown days"));
                        echo $date.PHP_EOL;
                        $models->andFilterWhere(['>=', $sysmodel->date_created_field, $date]);
                    }
                }
            } else {
                $date = '1990-01-01';
                echo 'Override Date: ' . $date.PHP_EOL;
                $models->andFilterWhere(['>=', $sysmodel->date_created_field, $date]);
                //$models->andFilterWhere(['in',$sysmodel->date_created_field, ['', null]]);
            }
            if (empty($sysmodel->date_created_field) == false){
                $models->orderby([$sysmodel->date_created_field => SORT_ASC]);
            }
            if ($sysmodel->source == '\api\modules\v1\models\Ltdslt' && $sysmodel->destination == '\frontend\models\ErpOrders'){
                $models->andWhere(['=', 'TYPE', 1])->andWhere(['=', 'REF', 537357]);
				//->andWhere(['Invoice_type' => 5]);
            }
           // $models->andWhere(['=', 'account', 'SUS003']);
            $class = $sysmodel->destination;
            if(method_exists($class, 'conditions')){
                Echo 'Conditions'.PHP_EOL;
                $models = $class::conditions($models);
            } 
            Echo $models->createCommand()->getRawSql().PHP_EOL;
            echo 'Found: '. $models->count().PHP_EOL;
            foreach ($models->each() as $key => $model) {
                $r2 = $sysmodel->datamap['relation1'] == 'product_stockcode' 
                ? 'stock_code' 
                : ($sysmodel->datamap['relation1'] == 'product_sourceid' 
                    ? 'product_id' 
                    : $sysmodel->datamap['relation1']);
                $r1 = $sysmodel->datamap['relation2'];
                $class = $sysmodel->destination ;
            
                if(str_contains($sysmodel->destination, 'Importproduct')){
                    $code = $model[$r1];
                    $product = \backend\models\Productsbe::find()
                    ->Where([$r2 => $code])
                    ->one();
                    $nmodel = new $class();
                    foreach ($sysmodel->datamap as $source => $destination) {
                        if ($destination !== '' && $source !== 'relation1' && $source !== 'relation2') {
                            $nmodel->$source = empty($model[$destination]) == false 
                                ? $model[$destination] 
                                : $nmodel->$source;
                        }
                    }
                    if(!$product){
                        echo 'Creating Product'.PHP_EOL;
                        $id = $nmodel->process();
                        if($id !== null){
                            //$product = \backend\models\Productsbe::find()->Where(['id' => $id])->one();
                            //is_array($cms) == true ? $nmodel->cms($product->id, 'en', $cms) : false;
                        } else {
                            echo 'Create failed'.PHP_EOL;
                        }
                    } else {
                        echo 'updating'.PHP_EOL;
                        echo  $nmodel->update($product['id']) . PHP_EOL;
                    }
                    
                } elseif($sysmodel->destination == '\frontend\models\ErpOrders'){
                    $nmodel =  $class::find()
                        ->select([$r2])
                        ->where([$r2 => trim($model[$r1])])
						->andWhere(['<', 'TYPE', 9])
                        ->one();
                    if (!$nmodel) {
                        echo 'Creating New Record'.PHP_EOL;
                        $nmodel = new $class(['id' => $sysmodel::Tempid(), 'language' => 'en']);
                        foreach ($sysmodel->datamap as $source => $destination) {
                            if ($destination !== '' && $source !== 'relation1' && $source !== 'relation2') {
                                $nmodel->$source = empty($model[$destination]) == false 
                                    ? $model[$destination] 
                                    : $nmodel->$source;
                            }
                            if(str_contains($sysmodel->source, 'slt')) {
                                $add = $model['Invoice_type'] == 5 ? 'Service': '';
								$nmodel->type = match($model['TYPE']){
                                    '1' => $add.'Invoice',
                                    '2' => 'Payment',
                                    '3' => 'Credit',
                                    '4' => 'Transfer',
                                    '5' => 'Adjustment',
                                    default => $model['TYPE'],
                                };
                            } elseif(str_contains($sysmodel->source, 'soh')){
                                $nmodel->type = 'SalesOrder';
                            }
                        }
                        if($sysmodel->source == '\api\modules\v1\models\Ltdslt'){
                            $rsysmodel = Sysmodels::find()->where(['source' => '\api\modules\v1\models\Ltdslt',  'destination' => '\frontend\models\ErpOrderlines'])->one();
                        } else {
                            $rsysmodel = Sysmodels::find()->where(['source' => '\api\modules\v1\models\Ltdsod',  'destination' => '\frontend\models\ErpOrderlines'])->one();
                        }

                        $rr2 = $rsysmodel->datamap['relation1'] == 'product_stockcode' 
                            ? 'stock_code' 
                            : ($rsysmodel->datamap['relation1'] == 'product_sourceid' 
                                ? 'product_id' 
                                : $rsysmodel->datamap['relation1']);
                        $rr1 = $rsysmodel->datamap['relation2'];



                        $class2 = $rsysmodel->destination;
                        $sclass2 = $rsysmodel->source;
                        
                            $models2 = $sclass2::find();
						if ($sysmodel->source !== '\api\modules\v1\models\Ltdslt'){
                            $models2->Where(['order_ref'=> $model['ORDER_REF']]); 
						} else {
							$models2->Where(['REF'=> $model['REF'], 'TYPE' => 9]);
						}
						$models2 = $models2->all();
                        $lines = [];
                        if(is_array($models2) == true && count($models2) > 0){
                            foreach($models2 as $key => $rec2){
                                $nmodel2 = new $class2(['id' => $sysmodel::Tempid(), 'language' => 'en']);
                                foreach ($rsysmodel->datamap as $source => $destination) {
                                    if ($destination !== '' && $source !== 'relation1' && $source !== 'relation2') {
                                        $nmodel2->$source = empty($rec2[$destination]) == false 
                                            ? $rec2[$destination] 
                                            : $nmodel2->$source;
                                    }
                                }
                                $lines[$nmodel2->id] = $nmodel2;
                            }
                        }
                        $nmodel->orderlines = json_encode($lines);
                        $nmodel->status = $sysmodel->options->importstatus;
                        echo $nmodel->save() ? '.' : PHP_EOL.$model[$r1]. print_r($nmodel->errors).PHP_EOL;
                    }
                } elseif(method_exists($class, 'import')) {
                    $concat = $model->_ID . $model->ACCOUNT;
                    if(in_array('TxREF', array_keys($model->attributes))){
                        $concat .= $model->TxREF . $model->TxDATE;
                    } elseif(in_array('ORDER_REF', array_keys($model->attributes))){
                        $concat .= $model->ORDER_REF . $model->DATE_INPUT;
                    } 

                    if ($r2 == 'erpid' && in_array($class::datatype, ['CreditInvoice', 'AdhocInvoice',  'WashroomInvoice', 'ServiceInvoice', 'Invoice', 'Payment', 'Order']) && method_exists($class, 'getErpkey') ){
                        $nmodel = $class::find()
                            ->where(['indexes_erpkey' => $concat])
                            ->one();
                        
                    } elseif ($r2 == 'erpid' && in_array($class::datatype, ['CreditInvoice', 'AdhocInvoice',  'WashroomInvoice', 'ServiceInvoice', 'Invoice', 'Payment', 'Order']) && !method_exists($class, 'getErpkey') ){
                        $nmodel = $class::find()
                            ->where(['indexes_erpid' => trim($model[$r1])])
                            ->one();
                    } else {
                        $nmodel = $class::find()->where([$r2 => trim($model[$r1])])->one();
                    }
                    if (!$nmodel) {
                        $nmodeldiff = $class::find()
                            ->where(['indexes_erpid' => trim($model[$r1])])
                            ->andWhere(['not', ['=', 'indexes_erpkey', $concat]]);
                        if($nmodeldiff->count() > 0){
                            Echo $nmodeldiff->createCommand()->getRawSql().PHP_EOL;
                            $deleted = 0;
                            foreach($nmodeldiff->each() as $diff){
                                $diff->purge() ? $deleted++ : false;
                            }
                            \yii\helpers\Console::output('Deleted '. $deleted);
                        } 
                        echo $class::import($model, $sysmodel->datamap);
                    }
                } else {
                    if($r2 == 'erpid' && in_array($class::datatype, ['CreditInvoice', 'AdhocInvoice',  'WashroomInvoice', 'ServiceInvoice', 'Invoice', 'Payment']) ){
                        $nmodel =  $class::find()->where(['type' => $class::datatype, 'indexes_erpid' => trim($model[$r1])])->one();
                    } else {
                        $nmodel =  $class::find()->where([$r2 => trim($model[$r1])])->one();
                    }
                    if (!$nmodel) {
                        echo 'Creating New Record'.PHP_EOL;
                        $nmodel = new $class(['id' => $sysmodel::Tempid(), 'language' => 'en']);
                    }
                    foreach ($sysmodel->datamap as $source => $destination) {
                        if ($destination !== '' && $source !== 'relation1' && $source !== 'relation2') {
                            if ($source === 'extended') {
                                $extended = $nmodel->extended;
                                foreach ($destination as $field => $name) {
                                    $fieldValue = isset($model[$name]) ? $model[$name] : $extended->$field;
                                    $extended->$field = $fieldValue;
                                }
                                $nmodel->extended = $extended;
                            } else {
                                $fieldValue = isset($model[$destination]) && $model[$destination] !== $nmodel->$source ? $model[$destination] : $nmodel->$source ;
                                $nmodel->$source = $fieldValue;
                            }
                        }
                    }
                    $nmodel->status = $sysmodel->options->importstatus;
                    if(count($nmodel->getDirtyAttributes()) > 0){
                        echo $nmodel->save() ? 'S' : PHP_EOL.$model[$r1].PHP_EOL. print_r($nmodel->errors).PHP_EOL;
                    }
                }
            }
            echo ''.PHP_EOL;
        }
    }
	
    /**
     * @inheritdoc
     */
    public function getTtr()
    {
        return 6000;
    }

    /**
     * @inheritdoc
     */
    public function canRetry($attempt, $error)
    {
        return $attempt < 3;
    }
}