<?php

namespace frontend\jobs;

use Yii;
use yii\base\BaseObject;
use yii\httpclient\Client;
use backend\models\Galleriesbe;
use backend\models\Sysmodels;
use backend\models\Categoriesbe;
use backend\models\Productsbe;
use backend\models\Lookuptablebe;
use yii\helpers\Json;

class Importdata extends BaseObject implements \common\components\Queue\JobInterface
{
    public $id;
    public $schedule;
    public $limit;
    /**
     * Runs Imports from Various Sources.
     *
     * @param [type] $queue
     * @return void
     */
    public function execute($queue)
    {
        echo "Starting Data Import" . PHP_EOL;
        //print_r(Yii::$app->Datafile);
        $sysmodel = Sysmodels::findOne(['id' => $this->id]);

        if ($this->schedule == 'auto') {
            $schedule = $sysmodel->options->schedule;
           // print_r($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 Importdata(['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 Importdata(['id' => $this->id, 'schedule' => 'auto']));
            }
        } else {
            $runnow = true;
        }

        if ($runnow == true) {
            if ($sysmodel->type == 'File') {
                $base = Yii::getAlias('@common', $throwException = true);
                echo $sysmodel->sourceurl . PHP_EOL;
                $fullfilepath = $sysmodel->sourceurl;
                $inputFileType = \PhpOffice\PhpSpreadsheet\IOFactory::identify($fullfilepath);
                $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
                $reader->setReadDataOnly(true);
                $spreadsheet = $reader->load($fullfilepath);
                $sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
                $headings = [];
                $array = [];
                foreach ($sheetData as $key => $xlsx) {
                    if ($key == 1) {
                        foreach ($xlsx as $k => $value) {
                            //$headings[] = $value;
                            $title = strtolower(preg_replace('/[^A-Za-z0-9\w]/', '_', $value, -1));
                            $headings[$title] = $title;
                        }
                    } else {
                        $t2 = [];
                        foreach ($xlsx as $k => $value) {
                            $t2[] = $value;
                        }
                        $array[] = array_combine($headings, $t2);
                    }
                }
                $count = count($array);
                foreach ($array 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'];
                    //$r1 = $sysmodel->datamap['relation1'] == 'product_stockcode' ? 'stock_code' : $sysmodel->datamap['relation1'];
                    //$r2 = $sysmodel->datamap['relation2'];
                    $M = $sysmodel->destination;



                    $nmodel = new $M();
                    if ($sysmodel->options->createcatsfromfield == true) {
                        $field = $sysmodel->options->createcatsfromfieldfield;
                        $category = Categoriesbe::find()->where(['name' => $model[$field]])->one();
                        if (!$category) {
                            $catid = Categoriesbe::Tempid();
                            $category = new Categoriesbe(
                                [
                                    'id' => $catid,
                                    'language' => 'en',
                                    'status' => 'Active',

                                ]
                            );
                            $category->name = $model[$field];
                            if ($category->save()) {
                                if (empty($sysmodel->options->categoryparent) == false) {
                                    $lt = new Lookuptablebe();
                                    $lt->source = 'Category';
                                    $lt->sourceid = $category->id;
                                    $lt->related = 'Categories';
                                    $lt->relatedid = $sysmodel->options->categoryparent;
                                    $lt->primaryrecord = true;
                                    $lt->save();
                                }
                            }

                            //$nmodel->categories[] = $catid;
                        } else {
                            //$nmodel->categories[] = $category->id;
                        }
                    }
                    $cms = [];
                    foreach ($sysmodel->datamap as $destination => $source) {
                        if (empty($source) == false && in_array($destination, ['relation1', 'relation2']) == false) {
                            $nmodel->$destination = empty($model[$source]) == false
                                ? $model[$source]
                                : $nmodel->$destination;
                        }
                    }
                    if (str_contains($sysmodel->destination, 'Importproduct') == true) {
                        //$nmodel->source = $sysmodel->source;//
                        $nmodel->product_status = $sysmodel->options->importstatus;
                        //$nmodel->importdata = Json::encode($model);

                        $product = \backend\models\Productsbe::find()->Where([$r2 => $model[$r1]])->one();

                        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;
                                print_r($nmodel);
                            }
                        } else {
                            echo 'Updating Product' . PHP_EOL;
                            $id = $nmodel->update($product->id);
                        }
                    } else {
                        $nmodel->process();
                        echo 'DONE';
                    }
                }
            } else {
                echo 'Model Copy' . PHP_EOL;
                echo  $sysmodel->destination . PHP_EOL;
                $models = $sysmodel->source::find();

                str_contains($sysmodel->source, 'mmssta') == true ? $models->andWhere(['WP' => 'Y']) : false;
                str_contains($sysmodel->source, 'Pursta') == true ? $models->andWhere(['WEB_PRODUCT' => 'Y']) : false;
                str_contains($sysmodel->source, 'Pursla') == true ? $models->andWhere(['not', ['like', 'ACCOUNT', 'R%', false]]) : false;

                if ($sysmodel->date_created_field !== null && $sysmodel->date_created_field !== '') {
                    $date = date('Y-m-d', strtotime("-$sysmodel->daysdown days"));
                    $models->andFilterWhere(['or', ['>=', $sysmodel->date_created_field, $date], ['>=', $sysmodel->date_updated_field, $date]]);
                }
                str_contains($sysmodel->source, 'mmssoh') == true ? $models->andfilterWhere([$sysmodel->source::tablename() . '.STATUS' => ['C', 'A']]) : false;
                //$models->limit($this->limit);
                if (empty($sysmodel->date_created_field) == false) {
                    $models->orderby([$sysmodel->date_created_field => SORT_ASC]);
                }

                $data = $models->all();
                echo 'Found: ' . count($data) . ' ' . $sysmodel->destination . PHP_EOL;
                foreach ($data 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 ;
                    //print_r($class::instance());
                //  print_r($model[$r1]);
                    echo '---' . $model[$r1] . '---' . PHP_EOL;
                    if (str_contains($sysmodel->destination, 'Importproduct') == true) {
                        $product = \backend\models\Productsbe::find()
                            ->Where([$r2 => $model[$r1]])
                            ->one();
                        $nmodel = new $class();
                        echo 'Here';
                        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 ' . $model[$r1] . PHP_EOL;
                            echo $nmodel->update($product->id) . PHP_EOL;
                            echo 'Update Complete ' . $model[$r1] . PHP_EOL;
                        }
                    } elseif ($sysmodel->destination == '\frontend\models\ErpOrders') {
                        $nmodel =  $class::find()->select([$r2])->where([$r2 => $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') {
                                    $nmodel->$destination = empty($model[$source]) == false ? trim($model[$source]) : trim($nmodel->$destination);
                                }
                            }
                            $rsysmodel = Sysmodels::find()->where(['destination' => '\frontend\models\ErpOrderlines'])->one();
                            $class2 = $rsysmodel->destination;
                            $sclass2 = $rsysmodel->source;
                            $models2 = $sclass2::find()->where(['ORDER_REF'  =>  $nmodel->orderref])->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->$destination = empty($rec2[$source]) == false ? trim($rec2[$source]) : trim($nmodel2->$destination);
                                        }
                                    }
                                    $lines[$nmodel2->id] = $nmodel2;
                                }
                            }

                            $nmodel->orderlines = json_encode($lines);
                            $out = $nmodel->status;
                            switch ($nmodel->status) {
                                case 'C':
                                    $out = 'Complete';
                                    break;
                                case 'A':
                                    $out = 'Outstanding';
                                    break;
                                case 'D':
                                    $out = 'Deleted';
                                    break;
                                default:
                                    $out = $nmodel->status;
                                    break;
                            };
                            $nmodel->status = $out;
                            echo $nmodel->save() ? '.' : PHP_EOL . $model[$r1] . print_r($nmodel->errors) . PHP_EOL;
                        }
                    } elseif ($sysmodel->destination == '\frontend\models\Import\Newusers') {
                        $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') {
                                    $nmodel->$destination !== trim($model[$source])
                                        ? $nmodel->$destination =  trim($model[$source])
                                        : false;
                                }
                            }
                            $nmodel->status = $sysmodel->options->importstatus;
                            property_exists($nmodel, 'ex_proformacustomer') && property_exists($model, 'Proforma') == true ? $nmodel->ex_proformacustomer = $model['Proforma'] : false;
                            echo $nmodel->process() ? 'U' : PHP_EOL . $model[$r1] . PHP_EOL . print_r($nmodel->errors) . PHP_EOL;
                        }
                    } 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') {
                                $nmodel->$destination !== trim($model[$source])
                                    ? $nmodel->$destination =  trim($model[$source])
                                    : false;
                            }
                        }

                            $nmodel->status = $sysmodel->options->importstatus;
                        //echo 'Creating Model'.PHP_EOL;
                        property_exists($nmodel, 'ex_proformacustomer') && property_exists($model, 'Proforma') == true ? $nmodel->ex_proformacustomer = $model['Proforma'] : false;


                    // property_exists($nmodel, 'stop') == true && $nmodel->stop == 'Y' ? $nmodel->stop = 1 : $nmodel->stop = 0;
                        if (\method_exists($nmodel, 'save')) {
                            echo $nmodel->save() ? 'U' : PHP_EOL . $model[$r1] . PHP_EOL . print_r($nmodel->errors) . PHP_EOL;
                        } else {
                            echo $nmodel->process() ? 'U' : PHP_EOL . $model[$r1] . PHP_EOL . print_r($nmodel->errors) . PHP_EOL;
                        }
                    }
                }
            }
        }
    }

    /**
     * @inheritdoc
     */
    public function getTtr()
    {
        return 6000;
    }

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