<?php

namespace modules\activities\models;

use Yii;
use frontend\models\{Notes, Uploads, Mailqueue, User, Dtwps, Settings};
use modules\activities\models\Activitiesusers;
use modules\custom\models\{Accounts, Contacts};
use modules\forms\models\Forms;

use yii\httpclient\Client;
use yii\helpers\Json;
/**
 * This is the model class For table "activities".
 *
 * @property integer $id
 * @property string $welder
 * @property string $travelstarttime
 * @property string $starttime
 * @property string $finishtime
 * @property string $travelfinishtime
 * @property string $shiftlength
 * @property integer $company
 * @property integer $assistant
 * @property string $contact
 * @property string $contactno
 * @property string $location
 * @property string $createdby
 * @property string $createdon
 * @property string $noofwelds
 * @property string $contactemail
 * @property string $noofshifts
 * @property string $comments
 * @property string $shift
 * @property string $noofteams
 * @property string $jobstatus
 * @property string $billingstatus
 * @property string $details
 * @property string $day
 * @property string $welderemail
 * @property string $manageremail
 * @property integer $jobno
 * @property string $weldernames
 * @property string $jobtype
 * @property string $weldtype
 *
 * @property Accounts $company0
 * @property Dt122[] $dt122s
 */
class Activities extends \common\models\Base {

    public $dates = ['created_at', 'updated_at', 'deleted_at'];
    public $uniqueidentifiers = ['actid','weldprocess1', 'weldprocess2','weldprocess3'];
	public $securefields = [];
    /**
     * @inheritdoc
     */

public static function tableName()
    {
        return 'activities';
    }

    /**
     * @inheritdoc
     */
    public function rules(): array
    {
        $localrules = [
            
            [['company','prevjobno','cjobno', 'jobno', 'starttime', 'finishtime','weekno','assistant', 'totalshiftlengthi'], 'integer'],
            [['deleted'], 'boolean'],
            [['created_at', 'updated_at', 'deleted_at', 'noofwelds'], 'safe'],
            [['relatedid','type', 'deleted_by','actid', 'enquirydata', 'actualshifttime', 'predictedshifttime'], 'string'],
            
            [['welder', 'sdate', 'edate','weldprocess1','weldprocess2','weldprocess3', 'id', 'updated_by',  'created_by'], 'safe'],
            [['travelstarttime',  'travelfinishtime', 'shiftlength', 'contact', 'contactno', 'location',  'contactemail', 'noofshifts', 'shift', 'noofteams', 'jobstatus', 'billingstatus', 'day', 'jobtype', 'weldtype','accesspoint','railwear','railtrack','railclosure','process','fuelgas','fuelgas2','fuelgas3','portion','mould','wpsno','railsupport','railsupport2','railsupport3','defectno1','defectno2','defectno3',   'railwear2','railwear3','railtrack2','railtrack3','weld','weld2','weld3','railsection2','railsection3','railgrade2','railgrade3','noofwelds1','noofwelds2','noofwelds3','elr', 'welderemail','depot','tefdata','quotedata','contact6', 'contactemail6', 'contactno6', 'contact7', 'contactemail7', 'contactno7','contact8', 'contactemail8', 'contactno8','contact9', 'contactemail9', 'contactno9','contact10', 'contactemail10', 'contactno10', 'route'], 'string'],
            [['manageremail', 'postcode', 'railgrade', 'railsection', 'googletime', 'googledistance', 'contact2', 'contactemail2', 'contactno2', 'contact3', 'contactemail3', 'contactno3', 'contact4', 'contactemail4', 'contactno4', 'contact5', 'contactemail5', 'contactno5', 'journey', 'customerpono'], 'string', 'max' => 100],
            [['files'], 'string', 'max' => 10],
            [['teftitle','quotetitle','enquirytitle','tracktrolley', 'padno', 'status'], 'string', 'max' => 50],
            [['details'], 'string', 'max' => 500],
            [['ordertitle', 'orderdata', 'notes', 'notes2', 'notes3', 'jnotes', 'comments','jcnno'], 'string'],
            ['noofwelds', 'default', 'value' => 0],
            ['gcmdata', 'boolean'],
            ['gcmdata', 'default', 'value' => false],
            ['deleted', 'default', 'value' => false],
            ['status', 'default', 'value' => 'Active'],
            ['jobno', 'default', 'value' => function($model){
                    $jobno = Activities::find()->select(['jobno'])->orderby(['jobno' =>  SORT_DESC])->one();
                    return $jobno->jobno + 1;
            }],
			
            ['visitno', 'integer'],
			['visitno', 'default', 'value' => 1],
            //redundant
            [['_id', 'updated_by2',  'created_by2'], 'integer'],
            [['fileenquiry', 'fileorder', 'filetef', 'filedocs','filequotation', 'createdon'],'safe'],
            
            //removed [['updatedby', 'createdby'],'int'],
              
        ];
          return array_merge($localrules, parent::rules());  
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels(): array
    {
        return [
            'id' => 'ID',
            'welder' => 'Welder',
            'starttime' => 'Start',
            'sdate' => 'Start',
            'finishtime' => 'Finish',
            'edate' => 'Finish',
            'shiftlength' => 'Shift Length',
            'company' => 'Company',
            'contact' => 'Contact',
            'contactno' => 'Contactno',
            'location' => 'Location',
            'createdon' => 'Createdon',
            'noofwelds' => 'No of Welds',
            'noofshifts' => 'No of Shifts',
            'comments' => 'Comments',
            'shift' => 'Shift',
            'noofteams' => 'No of Teams',
            'jobstatus' => 'Job Status',
            'billingstatus' => 'Billing Status',
            'details' => 'Details',
            'day' => 'Day',
            'manageremail' => 'Manageremail',
            'jobno' => 'Job Number',
            'jobtype' => 'Job Type',
            'weldtype' => 'Weld Type',
            'accesspoint' => 'Access Point',
            'postcode' => 'Post Code',
             'contact2' => 'Contact2',
            'contactno2' => 'Contactno2',
            'contactemail2' => 'Contactemail2',
             'contact3' => 'Contact3',
            'contactno3' => 'Contactno3',
            'contactemail3' => 'Contactemail3',
             'contact4' => 'Contact4',
            'contactno4' => 'Contactno4',
            'contactemail4' => 'Contactemail4',
             'contact5' => 'Contact5',
            'contactno5' => 'Contactno5',
			'contactemail5' => 'Contactemail5',
			'googletime' => 'Google Time from Office',
			'googledistance' => 'Google Distance from Office',
			'travelstarttime' => 'Shift Length',
			'travelfinishtime' => 'Issuing Depot',
			'ordertitle' => 'Customer Job Costing Number',
			'customerpono' => 'Customer Purchase Order Number',
			'elr' => 'ELR',
			'weekno' => 'Week No',
			'railgrade' => 'Rail Grade',
			'railsection' => 'Rail Section',
			'railsupport' => 'Rail Support',
			'railwear' => 'Rail Wear',
			'railtrack' => 'Rail Track',
			'noofwelds1' => 'No of Welds',
			'weldprocess1' => 'Weld Process',
			'fuelgas' => 'Fuel Gas',
			'account' => 'Company',
			'actualshifttime' => 'Actual Shift Time',
			'predictedshifttime' => 'Predicted Shift Time',
			'defectno1' => 'Defect No',
			'gcmdata' => 'Gauge Corner Machine',
			'welders' => 'Operatives',
        ];
    }

    public function getAccount() {
        if ($this->relatedid !== null) {
            return $this->hasOne(Accounts::class, ['id' => 'relatedid']);
        } else {
            return $this->hasOne(Accounts::class, ['accountid' => 'company']);
        } 
    }

    function shift() {
        $welders = explode(",", $this->welder);
        $sevendays = $this->sdate + 604800;
        foreach ($welders as $w) {
            $ns = Activities::find()->where(['like', 'welder', $w])->andWhere(['>', 'sdate', $this->sdate])->orderby('sdate ASC')->asArray()->One();
            $diff = $ns['sdate'] - +$this->sdate;
            if ($diff > 0 and $diff < 43200 ) { //<12 hours {
                \Yii::$app->getSession()->setFlash('error', "Error $w less than 12 hours to next shift" );
            }
        }    
    }

    public function getRenotes() {
        return $this->hasMany(Notes::class, ['actid'=> 'id'])
        ->onCondition(['status' => ['Active', 'Inactive', null]]);
    }

    function getImportantnotes() {
        return $this->hasMany(Notes::class, ['actid' => 'id'])
        ->onCondition(['status' => ['Active', 'Inactive', null]])
        ->andonCondition(['>=', 'urgency', 7])
        ->orderby(['notes.created_at' => SORT_ASC]);
    }
    public function getLastjobno() {
        return Activities::findBySql('SELECT jobno FROM activities ORDER BY jobno desc')->scalar();  
    }

    public function getContactl()
        {
            return $this->hasOne(Contacts::class, ['_id' => 'contact']);
        }

    public function getContact2l()
    {
        return $this->hasOne(Contacts::class, ['_id' => 'contact2']);
    }

    public function getContact3l()
    {
        return $this->hasOne(Contacts::class, ['_id' => 'contact3']);
    }

    public function getContact4l()
    {
        return $this->hasOne(Contacts::class, ['_id' => 'contact4']);
    }

    public function getContact5l()
    {
        return $this->hasOne(Contacts::class, ['_id' => 'contact5']);
    }

    public function getContact6l()
    {
        return $this->hasOne(Contacts::class, ['_id' => 'contact6']);
    }

    public function getContact7l()
    {
        return $this->hasOne(Contacts::class, ['_id' => 'contact7']);
    }
    public function getContact8l()
        {
            return $this->hasOne(Contacts::class, ['_id' => 'contact8']);
        }
    public function getContact9l()
        {
            return $this->hasOne(Contacts::class, ['_id' => 'contact9']);
        }
    public function getContact10l()
        {
            return $this->hasOne(Contacts::class, ['_id' => 'contact10']);
        }
    
    public function getStarttime1()
    {
        return strtotime($this->starttime);
    }
    
    public function getAccountName()
    {
        $model = $this->account;
        return $model ? $model->account_name : '';
    }
    
   public function getWelderd()
    {
        return $this->hasMany(Users::class, ['welder' => 'user']);
    }

    public function getJobno()
    {
        return Activities::findBySql('SELECT jobno FROM activities ORDER BY jobno desc')->scalar();
    }

    public function getEmailsubject() {
        return "Inline Documentation - ".$this->location;
    }

    //public function getWelder()
    //{
    //    $model=$this->welder;
    //    $welder = explode(', ', $model?$model->welder);
    //    return $welder[];
    //    }


    /**
     * @return \yii\db\ActiveQuery
     */

    public function getCompany0()
    {
        return $this->hasOne(Accounts::class, ['accountid' => 'company']);
    }

    public function getUser() 
    {
        return $this->hasMany(User::class, ['id' => 'welder']);
    }
    function getActsdate() 
    {
        return strtotime($this->sdate);
    }
    
    function getActedate() {
        return strtotime($this->edate);
    }
    
    function getCreatedbyL()
    {
        return $this->hasOne(User::class, ['id' => 'created_by' ]);
    }
    
    function getUpdatedbyL()
    {
        return $this->hasOne(User::class, ['id' => 'updated_by']);
    }
    function getEmailcount()
    {
        return mailqueue::find()
        ->where(['actid' => $this->id])
        ->andwhere(['<>', 'filename', 'Inline Track Arrangement Sheet.pdf'])
        ->count();
    }
    function getRemailcount() 
    {
        return \frontend\rmmodels\Mailqueue::find()
        ->where(['actid' => $this->id])
        ->andwhere(['<>', 'filename', 'Inline Track Arrangement Sheet.pdf'])
        ->count();
    }
    function getRemailcountsent()
    {
        return \frontend\rmodels\Mailqueue::find()
        ->where(['actid' => $this->id])
        ->andwhere(['success' => 0])
        ->andwhere(['<>', 'filename', 'Inline Track Arrangement Sheet.pdf'])
        ->count();
    }
    
    //TO FIX
    function getMissingemails()
    {
        return $this->noofteams;
    }
    
    function getDtwps1()
    {
        return $this->hasOne(Dtwps::class, ['id' => 'weldprocess1']);
    }
    function getDtwps2()
    {
        return $this->hasOne(Dtwps::class, ['id' => 'weldprocess2']);
    }
    function getDtwps3() {
        return $this->hasOne(Dtwps::class, ['id' => 'weldprocess3']);
        }
        
    function getWas()
    {
        return $this->hasOne(Forms::class, ['actid' => 'id'])
            ->andOncondition(['form' => 'dtwas']);
        }     
    
    function getUploads()
    {
        return $this->hasMany(Uploads::class, ['relatedid' => 'id'], function($query){
            $query->select([
                'category', 
                'filename', 
                'title', 
                'revision', 
                'status', 
                'jobno', 
                'mime', 
                'created_at', 
                'updated_at', 
                'id', 
            ]);
        })
        ->via('lookup')
        ->oncondition(['!=','deleted', 1])
        ->orderby(['created_at' => SORT_DESC]);
    }
    function getTimes()
    {
        return $this->hasMany(Activitiesusers::class, ['actid' => 'id'])
            ->where(['status' => 'Active']);
    }
    
    function getDt179()
    {
        return $this->hasMany(Forms::class, ['actid' => 'id',])
        ->onCondition(['form' => 'dt179']);        
    }

    function getRoutedeviations()
    {
        return $this->hasMany(\frontend\models\Routedeviations::class, ['actid' => 'id']);
    }

    public function __construct($config = [])
    {
        parent::__construct($config);
        $this->data = ActivitiesData::loadData($this);
        return;
    }

    public function afterFind(){
        $this->sdate = date('d/m/Y H:i', strtotime(str_replace('/', '-', $this->sdate)));
        $this->edate = date('d/m/Y H:i', strtotime(str_replace('/', '-', $this->edate)));
		$this->welder = is_array($this->welder) ? explode(',', $this->welder) : $this->welder;
        $this->data = ActivitiesData::loadData($this);
        return parent::afterFind();
    }
    public static function Inlineaddress(){
        $settings = Settings::find()->one();
        return "$settings->address1 $settings->address2 $settings->town $settings->county $settings->postcode";
    }

    public function beforeSave($insert) {
        if($this->relatedid == null){
            $id = Accounts::find()->select(['id', 'accountid'])->where(['accountid' => $this->company])->indexBy('accountid')->one();
            $this->relatedid = $id ? $id['id'] : $this->relatedid;
        } else {
            $id = Accounts::find()->select(['id', 'accountid'])->where(['id' => $this->relatedid])->indexBy('accountid')->one();
            $this->company = $id ? $id['accountid'] : $this->company;
        }
        $this->comments = match($this->type){
            'training' => 'Training Job - ' . $this->data['Training']->company . ' - ' . $this->sdate . ' - ' . $this->edate,
            'welding' => 'Welding Job - ' . $this->account?->account_name . ' - ' . $this->sdate . ' - ' . $this->edate,
            default => 'Administration Job - ' . $this->account?->account_name . ' - ' . $this->sdate . ' - ' . $this->edate,
        };
        $this->createdby_name = empty($this->createdby_name) && $this->createdbyL ? $this->createdbyL->fullname : $this->createdby_name;
        $this->updatedby_name = empty($this->updatedby_name) && $this->updatedbyL ? $this->updatedbyL->fullname : $this->updatedby_name;
        
        if (Yii::$app->name !== 'app-console' && Yii::$app->name !== 'NGaugeApi') {
            $this->sdate = date('Y-m-d H:i:s',strtotime(str_replace('/', '-', $this->sdate)));
            $this->day = date('l',strtotime(str_replace('/', '-', $this->sdate)));
            $this->starttime = strtotime($this->sdate);
            $this->edate = date('Y-m-d H:i:s',strtotime(str_replace('/', '-', $this->edate)));
            $this->finishtime = strtotime($this->edate);
            //$this->edate = date('Y-m-d H:i:s',strtotime($this->edate));
            is_array($this->welder) ? $this->welder = implode(",", $this->welder) : false;
            empty(trim($this->shiftlength)) ? $this->shiftlength = 0 : false;
            if (empty($this->postcode) == false && $this->postcode !== 'ME172GQ' && array_key_exists('postcode', $this->oldAttributes) && $this->postcode !== $this->oldAttributes['postcode'] && Yii::$app->controller->action->id !== 'pdf') {
                $data = \modules\activities\components\GoogleDistanceMatrix::Getgoogledm($this->inlineaddress(), $this->postcode, strtotime('now'), $this->location);
                $this->googledistance = $data['distance'];
                $this->googletime = gmdate("H:i:s", $data['duration_in_traffic']);
                $journey = $this->journey == 'Return' ? 2 :1;
                $time2  = $data['duration_in_traffic'] * $journey;
                $stime = intval($this->shiftlength) * 60 * 60;
                $this->travelstarttime =  gmdate("H:i:s",$stime + $time2);
            }            
        }
        if (is_array($this->data)) {
            foreach ($this->data as $key => $object) {
                foreach($object as $attfield => $value) {
                    if($value !== null && is_object($value) && Yii::$app->request->isPost && array_key_exists($key, Yii::$app->request->post()) && array_key_exists($attfield, Yii::$app->request->post($key))) {
                        $value->load(Yii::$app->request->post($key)[$attfield], '');
                    } else {
                    }
                    is_object($value) ? $value->validate() : false;
                }
            }
        }
        $this->data = Json::encode($this->data);
        
        return parent::beforeSave($insert);
	}
	
    public function afterSave($insert, $changed)
    {
        if (str_contains($this->welder, ',')) {
            $currentWelders = explode(',', $this->welder);
        } else {
            $currentWelders = [$this->welder];
        }
        if (array_key_exists('welder', $changed) && str_contains($changed['welder'], ',')) {
            $previousWelders = explode(',', $changed['welder']);
        } else {
            $previousWelders = [];
        }
        if(Yii::$app->request->isConsoleRequest){
            echo '----------------------\n';
            print_r($currentWelders);
            echo '----------------------\n';
            print_r($previousWelders);
        }
        if (count($currentWelders) > 0) {
            // Remove trailing commas and trim whitespace
                if ( is_array($currentWelders) && count($currentWelders) > 0) {
                    // Add new welders
                    $weldersToAdd = array_diff($currentWelders, $previousWelders);
                    foreach ($weldersToAdd as $welder) {
                        if (empty($welder)) continue;
                        $actuser = Activitiesusers::find()->where([
                            'actid' => $this->id,
                            'status' => 'Active',
                            'operativename' => $welder
                        ]);
                        if (!$actuser->one()) {
                            $actuser = new Activitiesusers([
                                'actid' => $this->id,
                                'status' => 'Active',
                                'operativename' => $welder,
                                'postcodeto' => $this->postcode,
                                'shifttime' => $this->shiftlength,
                            ]);
                        }
                        ($actuser->one())->save();
                    }
                    
                    // Remove old welders (only if not insert)
                    if (!$insert && is_array($previousWelders)) {
                        $weldersToRemove = array_diff($previousWelders, $currentWelders);
                        foreach ($weldersToRemove as $welder) {
                            if (empty($welder)) continue;
                            
                            $actusers = Activitiesusers::find()
                                ->where([
                                    'actid' => $this->id,
                                    'status' => 'Active',
                                    'operativename' => $welder
                                ])
                                ->all();
                            
                            foreach ($actusers as $actuser) {
                                $actuser->delete();
                            }
                        }
                    }
                }
            }
            $times = $this->times;
            if (count($times) > 0) {
                foreach ($times as $key => $time) {
                    $time->shifttime = $this->shiftlength;
                    $time->postcodeto = $this->postcode;
                    $time->save();
                }
                $t = array_sum(array_column($this->times, 'totaltime'));
                $this->updateAttributes(['predictedshifttime' => sprintf('%02d:%02d:%02d', ($t/3600),($t/60%60), $t%60)]);
            }
        
        
        return parent::afterSave($insert, $changed);
    }

    public function getActusers(){
        return Activitiesusers::find()
            ->select(['operativename', 'actid','status'])
            ->where(['actid' => $this->id])
            ->andWhere(['status' => 'Active'])
            ->asArray()
            ->all();
    }

    public static function checkMail($emailid){
        $data = [];
		$connected = @fsockopen("my.Inlinetrack.co.uk",443);
		$output = '';
		if (!$connected) {
			$output = ['message' => 'Sorry No Internet Connection', 'code' => 100];
		} elseif($connected) {
			$settings = \backend\models\Globalsettingsbe::find()->where(['name' => 'Dataserver'])->One();
			$client = new Client(['baseUrl' => $settings->setting]);
			$response = $client->createRequest()
			->setMethod('get')
			->setUrl('mail/check')
			->setData([
				'username' => $settings->data->username1,
				'id' => $emailid,
				])
			->setOptions([
				'timeout' => 600,
				'sslVerifyPeer' => false,
			])
			->setHeaders(['Authorization' => 'Bearer ' . $settings->data->password1]);
			$result = $response->send();
            if($result->isOk){
                $result->content = is_array(json_decode($result->content, 1)) == true ? json_decode($result->content, 1) : $result->content;
            } else {
                $result->content = ['message' => 'Error Connecting to Mail Server', 'code' => $result->statusCode];
            }
			$output = $result->content;
		}
		return $output;
    }
    public function jobTypes(){
        $output = [];
        $output['administration'] = 'Administration';
        $output['training'] = 'Training';
        $output['welding'] = 'Welding';
        return $output;
    }


    public function SiteAttended(){
        $this->jobstatus = 'Attended';
		$this->save();
    }
}