<?php

namespace App\Controllers\api\v1;
use App\Controllers\BaseController; 
use App\Models\LineModel;
use App\Models\MachineLogModel;  
use App\Models\MachineStatusModel;  
use App\Models\MachineDailyLog;  
use App\Models\MachineModel;  
use App\Models\ContactModel;  
use App\Models\MessageHistoryModel;  
use App\Models\HistoryUsedModel;  
use App\Models\AlertsModel;  
use Config\Database;

class Machine extends BaseController
{

    
    private $seconds = 30;

    private $MachineLogModel;
    private $MachineStatusModel;
    private $MachineDailyLog;
    private $MachineModel;
    private $ContactModel;
    private $MessageHistoryModel;
    private $HistoryUsedModel;
    private $AlertsModel;

    public function __construct()
    {

        // new
        $this->MachineLogModel      = new MachineLogModel();   
        $this->MachineStatusModel   = new MachineStatusModel();   
        $this->MachineDailyLog   = new MachineDailyLog();   
        $this->MachineModel   = new MachineModel();   
        $this->ContactModel   = new ContactModel();   
        $this->MessageHistoryModel   = new MessageHistoryModel();   
        $this->HistoryUsedModel   = new HistoryUsedModel();   
        $this->AlertsModel   = new AlertsModel();   
    }


    public function set()
    {
        $request;

        if ($this->request->hasHeader('Content-Type') && strpos($this->request->getHeaderLine('Content-Type'), 'application/json') !== false) {
            $request    = $this->request->getJSON();
        }else{
            $request    = $this->request->getPOST();
        }
        $request    = json_decode(json_encode($request));
        $status     = isset($request->status) ? strtoupper($request->status) : "OFF"; 
        
        $current    = isset($request->machine1) ? $request->machine1 : 0; 
        $voltage    = isset($request->voltage1) ? $request->voltage1 : 0; 
        $temperature= isset($request->temperature1) ? $request->temperature1 : 0; 
        $rpm        = isset($request->rpm1) ? $request->rpm1 : 0; 

        $currentTime = date('Y-m-d H:i:s');


        // insert to machine log
        $dataLog = [
            'machine_id'    => 4,
            'current'       => $current,
            'voltage'       => $voltage,
            'rpm'           => $rpm,
            'temperature'   => $temperature,
            'created_at'    => $currentTime,
        ];


        $this->MachineLogModel->insert($dataLog);
        

        // update status this machine if current > 0
        if(strtoupper(trim($status))=="ON"){

            // accumulate 
            $row = json_decode(json_encode($this->_getCurrentStatus()));

            $dataStatus = [
                'total_operation_time'      => $row->total_operation_time,
                'operation_time_today'      => $row->operation_time_today,
                'average_temperature_today'      => $row->average_temperature_today,
                'average_rpm_today'      => $row->average_rpm_today,
                'average_current_today'     => $row->average_current_today,
                'average_operation_daily'   => $row->average_operation_daily,
                'last_updated'  => $currentTime,
            ];

            $this->MachineStatusModel->where('machine_id', 4)->set($dataStatus)->update();
            
        }else{

            $this->MachineStatusModel->set('last_updated', $currentTime);
            $this->MachineStatusModel->where('machine_id', 4);
            $this->MachineStatusModel->update();
        }

        $this->MachineModel->set('status', $status);
        $this->MachineModel->where('id', 4);
        $this->MachineModel->update();


        // MAKE ALERTS
        $alerts = [];
        if(strtoupper(trim($status))=="ON"){
            if( floatval($current) < 9.3 ){
            }else{
                $alerts[] = [
                    'message'       => "Current is not normal",
                    'value'         => $current,
                    'type'          => "CURRENT",
                    'created_at'    => $currentTime,
                ];
            }

            if( floatval($temperature) < 130 ){
            }else{
                $alerts[] = [
                    'message'       => "Temperature is not normal",
                    'value'         => $temperature,
                    'type'          => "TEMPERATURE",
                    'created_at'    => $currentTime,
                ];
            }            
        }   
        

        // get target
        $this->MachineStatusModel->where('machine_id',4);
        $achived = $this->MachineStatusModel->first()->total_operation_time;
        $target = $this->MachineModel->find(4)->target_time;

        $over = false;
            
        if(floatval($achived)<floatval($target)){
            // not over
            $over = false;

        }else{
            // over
            $over = true;

            $machineRow = $this->MachineModel->find(4);
            if(intval($machineRow->has_send)!=1){

                $settingContacts = $this->ContactModel->findAll();
                if(!empty($settingContacts)){
                    foreach ($settingContacts as $sub_e) {
                        
                        $url = "https://api.callmebot.com/whatsapp.php";
                        $phone = $sub_e->phone;

                        $text = urlencode("🔔Maintenance Alert
📅 Date: ". formatDate($currentTime) ."
⏰ Time: ". formatTime($currentTime) ."

Dear Mr. $sub_e->name,

The system has reached its designated operational time limit. Kindly perform the necessary inspection and maintenance to ensure optimal performance.

Please proceed with the maintenance and reset the system data once the servicing is complete.
For real-time monitoring and further details, please visit the dashboard below:

📊 Dashboard: https://re-teech.my.id/industrial/public/

Thank you for your prompt attention and action.

Best regards,
🚀IoT Monitoring System");


                        $apikey = $sub_e->key;

                        $curl = curl_init();
                        curl_setopt_array($curl, [
                            CURLOPT_URL => "$url?phone=$phone&text=$text&apikey=$apikey",
                            CURLOPT_RETURNTRANSFER => true,
                            CURLOPT_SSL_VERIFYPEER => false, 
                        ]);

                        $response = curl_exec($curl);

                        curl_close($curl);
                    }

                    $this->MachineModel->set('has_send',1);
                    $this->MachineModel->where('id',4);
                    $this->MachineModel->update();
                }
            }


            $alerts[] = [
                'message'       => "Time to maintain",
                'value'         => $this->_convertToHourMinute($achived),
                'type'          => "HOURS",
                'created_at'    => $currentTime,
            ];            

            
        }


        if(!empty($alerts)){
            $this->AlertsModel->insertBatch($alerts);
        }


        $this->_saveHistory($status, $currentTime);


        $this->MachineStatusModel->where('machine_id',4);
        $status = $this->MachineStatusModel->first();
        $total_operation_time = !empty($status->total_operation_time) ? $status->total_operation_time : 0;

        $total_operation_time = $this->_formatFix2($total_operation_time);
        $total_operation_time = $this->_convertToHourMinute($total_operation_time);

        return $this->response->setJSON([
            'code'      => 200,
            'success'   => true,
            'message'   => "Data has been save",
            'data'      => [
                'isOver'            => $over,
                'totalOperation'    => $total_operation_time,
            ]
        ]);

    }


    private function _saveHistory($sub_q, $date)
    {

        $add = (intval($this->seconds) / 3600);

        // is on
        if(strtoupper(trim($sub_q))=="ON"){

            $this->HistoryUsedModel->select('id, end_date');
            $this->HistoryUsedModel->where('DATE(start_date)',date('Y-m-d',strtotime($date)));
            $this->HistoryUsedModel->orderBy('id',"DESC");
            $hasHistory = $this->HistoryUsedModel->first();
            if(empty((array) $hasHistory)){
                $dataHistory = [
                    'machine_id'    => 4,
                    'start_date'    => $date,
                    'total'         => $add,
                    'created_at'    => $date,
                    'updated_at'    => $date,
                ];
                $this->HistoryUsedModel->insert($dataHistory);
            }else{

                
                if(empty($hasHistory->end_date)){
                    $this->HistoryUsedModel->set('total', 'total+' .  floatval($add) , FALSE);
                    $this->HistoryUsedModel->set('updated_at', $date);
                    $this->HistoryUsedModel->where('machine_id', 4);
                    $this->HistoryUsedModel->where('end_date', null);
                    $this->HistoryUsedModel->update();
                }else{
                    $dataHistory = [
                        'machine_id'    => 4,
                        'start_date'    => $date,
                        'total'         => $add,
                        'created_at'    => $date,
                        'updated_at'    => $date,
                    ];
                    $this->HistoryUsedModel->insert($dataHistory);
                }
            }
        }else{
        // is off
        
            $this->HistoryUsedModel->set('end_date', $date);
            $this->HistoryUsedModel->where('machine_id', 4);
            $this->HistoryUsedModel->where('end_date', null);
            $this->HistoryUsedModel->update();
        }

    }


    private function _formatFix2($time) {
        $time = floatval($time);
        return ($time == floor($time)) ? strval($time) : number_format($time, 2, '.', '');
    }

    private function _convertToHourMinute($decimalHour) {
        $decimalHour = floatval($decimalHour);

        $jam = floor($decimalHour);
        $menit = round(($decimalHour - $jam) * 60);

        if ($menit === 0) {
            return strval($jam);
        } else {
            return $jam . '.' . str_pad($menit, 2, '0', STR_PAD_LEFT);
        }
    }




    private function _getCurrentStatus()
    {

        $this->MachineStatusModel->where('machine_id',4);
        $row = $this->MachineStatusModel->first();

        $currentTime = date("Y-m-d H:i:s");
        if(empty( (array) $row)){

            $data = [
                'machine_id'                => 4,
                'total_operation_time'      => 0,
                'operation_time_today'      => 0,
                'average_current_today'     => 0,
                'average_operation_daily'   => 0,
                'last_updated'              => $currentTime,
            ];

            $this->MachineStatusModel->insert($data);


            return [
                'total_operation_time'      => 0,
                'operation_time_today'      => 0,
                'average_current_today'     => 0,
                'average_operation_daily'   => 0,
            ];

        }

        $add = (intval($this->seconds) / 3600);
        $total_operation_time = floatval($row->total_operation_time) + floatval($add);
        $operation_time_today = floatval($row->operation_time_today) + floatval($add);

        
        $average_current_today;
        $averageCurrent = $this->MachineLogModel->where('machine_id', 4)
                                   ->where('DATE(created_at)', date("Y-m-d"))
                                   ->selectAvg('current')
                                   ->first();
        if(!empty( (array) $averageCurrent )){
            $average_current_today = $averageCurrent->current;
        }else{
            $average_current_today = 0;
        }



        $average_temperature_today;
        $averageTemperature = $this->MachineLogModel->where('machine_id', 4)
                                   ->where('DATE(created_at)', date("Y-m-d"))
                                   ->selectAvg('temperature')
                                   ->first();
        if(!empty( (array) $averageTemperature )){
            $average_temperature_today = $averageTemperature->temperature;
        }else{
            $average_temperature_today = 0;
        }



        $average_rpm_today;
        $averageRpm = $this->MachineLogModel->where('machine_id', 4)
                                   ->where('DATE(created_at)', date("Y-m-d"))
                                   ->selectAvg('rpm')
                                   ->first();
        if(!empty( (array) $averageRpm )){
            $average_rpm_today = $averageRpm->rpm;
        }else{
            $average_rpm_today = 0;
        }


        
        $average_operation_daily = $this->MachineDailyLog->where('DATE(created_at)',date('Y-m-d'))->where('machine_id', 4)->first();
        
        if(!empty( (array) $average_operation_daily )){
            $this->MachineDailyLog->set('operation','operation+' . floatval($add), false);
            $this->MachineDailyLog->where('machine_id', 4);
            $this->MachineDailyLog->where('DATE(created_at)', date('Y-m-d',strtotime($currentTime)));
            $this->MachineDailyLog->update();

            // $average_operation_daily = $this->MachineDailyLog->where('machine_id', 4)
            //         ->selectAvg('operation')
            //         ->first();

            // $average_operation_daily = $average_operation_daily->operation;
            
            $lasted_reset_at = $this->MachineModel->find(4)->lasted_reset_at;

            $this->MachineDailyLog->select("AVG(operation) AS avg");
            $this->MachineDailyLog->where("machine_id",4);
            if(!empty($lasted_reset_at)){
                $this->MachineDailyLog->where("DATE(created_at)>=",date('Y-m-d',strtotime($lasted_reset_at)));
            }
            $this->MachineDailyLog->where("DATE(created_at)<=",date('Y-m-d',strtotime($currentTime)));
            $average_operation_daily = $this->MachineDailyLog->first();
            
            if(!empty( (array) $average_operation_daily )){
                if(!empty( (array) $average_operation_daily->avg )){
                    $average_operation_daily = $average_operation_daily->avg;
                }else{
                    $average_operation_daily = 0;    
                }
            }else{
                $average_operation_daily = 0;
            }



        }else{
            
            // $average_operation_daily = $average_operation_daily['operation'];

            $daily = [
                'machine_id'    => 4,
                'operation'     => $add,
                'created_at'    => $currentTime,
            ];

            $this->MachineDailyLog->insert($daily);


            $lasted_reset_at = $this->MachineModel->find(4)->lasted_reset_at;

            $this->MachineDailyLog->select("AVG(operation) AS avg");
            $this->MachineDailyLog->where("machine_id",4);
            if(!empty($lasted_reset_at)){
                $this->MachineDailyLog->where("DATE(created_at)>=",date('Y-m-d',strtotime($lasted_reset_at)));
            }
            $this->MachineDailyLog->where("DATE(created_at)<=",date('Y-m-d',strtotime($currentTime)));
            $average_operation_daily = $this->MachineDailyLog->first();
            
            if(!empty( (array) $average_operation_daily )){
                if(!empty( (array) $average_operation_daily->avg )){
                    $average_operation_daily = $average_operation_daily->avg;
                }else{
                    $average_operation_daily = 0;   
                }
            }else{
                $average_operation_daily = 0;
            }

        }


        return [
            'total_operation_time'      => $total_operation_time,
            'operation_time_today'      => $operation_time_today,
            'average_temperature_today' => $average_temperature_today,
            'average_rpm_today'         => $average_rpm_today,
            'average_current_today'     => $average_current_today,
            'average_operation_daily'   => $average_operation_daily,
        ];


    }


    public function check()
    {
        $this->MachineStatusModel->select('last_updated');
        $this->MachineStatusModel->where('machine_id',4);
        $row = $this->MachineStatusModel->first();

        date_default_timezone_set('Asia/Jakarta');
        if(!empty( (array) $row)){
            if(isset($row->last_updated)&&!empty( (array) $row->last_updated)){

                $timestamp_given = strtotime($row->last_updated);
                $timestamp_now = time();

                $diff_seconds = $timestamp_now - $timestamp_given;

                if ($diff_seconds > 60) {
                    
                    $this->MachineModel->set('status',"OFF");
                    $this->MachineModel->where('id',4);
                    $this->MachineModel->update();

                    $this->HistoryUsedModel->select('id, end_date');
                    $this->HistoryUsedModel->where('DATE(start_date)',date('Y-m-d'));
                    $this->HistoryUsedModel->orderBy('id',"DESC");
                    $hasHistory = $this->HistoryUsedModel->first();
                    if(!empty((array)$hasHistory)){
                        if(empty($hasHistory->end_date)){
                            $this->HistoryUsedModel->set('end_date',date('Y-m-d H:i:s'));
                            $this->HistoryUsedModel->where('id',$hasHistory->id);
                            $this->HistoryUsedModel->update();
                        }
                    }

                }

            }
        }

    }



    public function dayily()
    {
       
        $this->MachineStatusModel->select('operation_time_today');
        $this->MachineStatusModel->where('machine_id',4);
        $operationTime = $this->MachineStatusModel->first();
        $operation_time_today = isset($operationTime->operation_time_today) ? $operationTime->operation_time_today : 0;

        
        // check
        $yesterday = date('Y-m-d', strtotime('-1 day'));
        $yesterdayRow = $this->MachineDailyLog->where('DATE(created_at)',$yesterday)->where('machine_id', 4)->first();
        
        
        if(!empty( (array) $yesterdayRow )){
            $this->MachineDailyLog->set('operation', $operation_time_today);
            $this->MachineDailyLog->where('machine_id', 4);
            $this->MachineDailyLog->where('DATE(created_at)',$yesterday);
            $this->MachineDailyLog->update();

        }else{
            
            $daily = [
                'machine_id'    => 4,
                'operation'     => $operation_time_today,
                'created_at'    => $yesterday,
            ];

            $this->MachineDailyLog->insert($daily);

        }

        $this->MachineStatusModel->set('operation_time_today',0);
        $this->MachineStatusModel->set('average_temperature_today',0);
        $this->MachineStatusModel->set('average_rpm_today',0);
        $this->MachineStatusModel->set('average_current_today',0);
        $this->MachineStatusModel->where('machine_id',4);
        $this->MachineStatusModel->update();

    }


    public function reset()
    {


        if ($this->request->hasHeader('Content-Type') && strpos($this->request->getHeaderLine('Content-Type'), 'application/json') !== false) {
            $request    = $this->request->getJSON();
        }else{
            $request    = $this->request->getPOST();
        }
        $request    = json_decode(json_encode($request));

        if(empty( (array) $request)){

            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => "Access is not allowed",
            ]);
        }

        if(!isset($request->password)){

            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => "Access is not allowed",
            ]);

        }

        if($request->password!="jD3U9rVexQ0hbRa{MCf&B]1"){

            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => "Your password is not current",
            ]);
        }



        $this->MachineModel->set("status","OFF");
        $this->MachineModel->set('has_send',0);
        $this->MachineModel->where("id",4);
        $this->MachineModel->update();


        $this->MachineDailyLog->where('machine_id',4);
        $this->MachineDailyLog->delete();


        $this->MachineLogModel->where('machine_id',4);
        $this->MachineLogModel->delete();

        $this->MachineStatusModel->set('total_operation_time',0);
        $this->MachineStatusModel->set('operation_time_today',0);
        $this->MachineStatusModel->set('operation_time_today',0);
        $this->MachineStatusModel->set('average_temperature_today',0);
        $this->MachineStatusModel->set('average_rpm_today',0);
        $this->MachineStatusModel->set('average_current_today',0);
        $this->MachineStatusModel->set('average_operation_daily',0);
        $this->MachineStatusModel->where('machine_id',4);
        $this->MachineStatusModel->update();

        $this->HistoryUsedModel->where('machine_id',4);
        $this->HistoryUsedModel->delete();

        $this->AlertsModel->where('id<>',0);
        $this->AlertsModel->delete();

        return $this->response->setJSON([
            'code'      => 200,
            'success'   => true,
            'message'   => "Data has been reset",
        ]);


    }





    private function _sendMessage()
    {



    }



}
