<?php

namespace App\Controllers;
use App\Models\LineModel;
use App\Models\MachineModel;
use App\Models\HistoryMachineModel;
use App\Models\HistorySensorModel;
use App\Models\MachineOperationModel;
use App\Models\MachineStatusModel;
use App\Models\MachineLogModel;
use App\Models\MachineDailyLog;
use App\Models\AlertsModel;
use App\Models\ContactModel;

class Dashboard extends BaseController
{
    private $LineModel;
    private $MachineModel;
    private $HistoryMachineModel;
    private $HistorySensorModel;
    private $MachineOperationModel;
    private $MachineStatusModel;
    private $MachineLogModel;
    private $MachineDailyLog;
    private $AlertsModel;
    private $ContactModel;

    public function __construct()
    {
        $this->LineModel   = new LineModel();   
        $this->MachineModel   = new MachineModel();   
        $this->HistoryMachineModel   = new HistoryMachineModel();   
        $this->HistorySensorModel   = new HistorySensorModel();   
        $this->MachineOperationModel   = new MachineOperationModel();
        $this->MachineStatusModel   = new MachineStatusModel();   
        $this->MachineLogModel   = new MachineLogModel();   
        $this->MachineDailyLog   = new MachineDailyLog();   
        $this->AlertsModel   = new AlertsModel();   
        $this->ContactModel   = new ContactModel();   
    }

    public function index()
    {
            
        $data = [
            'result'    => $this->LineModel->getAllWithMachine()
        ];
        
        return view('app/dashboard/dashboard-css', $data) .
        view('app/dashboard/dashboard', $data) .
        view('app/dashboard/dashboard-js', $data);
    }



    public function getDetailMachine()
    {

        $request    = json_decode(json_encode($this->request->getGET()));
        $id         = $request->id;

        $machineRow = $this->_getInfromation($id);
        $machineRow['operation_date'] = date('d-m-Y', strtotime($request->productionDate));
        $machineRow['history'] = $this->_getHistory($id, $request->productionDate);

        return $this->response->setJSON([
            'code'      => 200,
            'success'   => true,
            'message'   => 'Successfully',
            'data'      => $machineRow,
        ]);

    }


    private function _getInfromation($id = null)
    {

        $row    = $this->MachineModel->find($id);

        $this->MachineStatusModel->where('machine_id',$id);
        $status = $this->MachineStatusModel->first();
        
        return [
            'total_operation_time'   => $status->total_operation_time,
            'operation_time_today'   => $status->operation_time_today,
            'average_temperature_today'   => $status->average_temperature_today,
            'average_rpm_today'   => $status->average_rpm_today,
            'average_current_today'   => strtoupper($row->status) == "OFF" ? 0 : $status->average_current_today,
            'average_operation_daily'   => $status->average_operation_daily,
            'target_time'   => $row->target_time,
            'status'        => $row->status,
        ];


    }

    private function _getHistory($id, $date)
    {

        $data = new \stdClass();
        $data->current = new \stdClass();
        $data->voltage = new \stdClass();
        $data->rpm = new \stdClass();
        $data->temperature = new \stdClass();

        $this->MachineLogModel->select('current, voltage, rpm, temperature');
        $this->MachineLogModel->where('machine_id', $id);
        $this->MachineLogModel->orderBy('id', "DESC");
        $lasted = $this->MachineLogModel->first();

        if(empty( (array) $lasted )){
            $data->current->lasted      = 0;
            $data->voltage->lasted      = 0;
            $data->rpm->lasted          = 0;
            $data->temperature->lasted  = 0;
        }else{
            $data->current->lasted      = $lasted->current;
            $data->voltage->lasted      = $lasted->voltage;
            $data->rpm->lasted          = $lasted->rpm;
            $data->temperature->lasted  = $lasted->temperature;
        }


        $this->MachineLogModel->select('current, voltage, rpm, temperature, created_at');
        $this->MachineLogModel->where('machine_id', $id);
        $this->MachineLogModel->where('DATE(created_at)', date('Y-m-d', strtotime($date)));
        $this->MachineLogModel->limit(10);
        $this->MachineLogModel->orderBy('id', "DESC");
        $history = $this->MachineLogModel->findAll();

        $data->current->values      = [];
        $data->current->labels      = [];
        $data->voltage->values      = [];
        $data->voltage->labels      = [];
        $data->rpm->values          = [];
        $data->rpm->labels          = [];
        $data->temperature->values  = [];
        $data->temperature->labels  = [];

        if(empty( $history )){
            return $data;
        }


        foreach($history AS $item){
            $labelsDate = date('H:i:s', strtotime($item->created_at));

            $data->current->labels[]        = $labelsDate;
            $data->voltage->labels[]        = $labelsDate;
            $data->rpm->labels[]            = $labelsDate;
            $data->temperature->labels[]    = $labelsDate;

            $data->current->values[]        = $item->current; 
            $data->voltage->values[]        = $item->voltage; 
            $data->rpm->values[]            = $item->rpm; 
            $data->temperature->values[]    = $item->temperature; 

        }


        return $data;


    }


    public function save()
    {
        $request = $this->request->getJSON();

        $this->MachineModel->set('target_time', $request->goal);
        $this->MachineModel->set('has_send',0);
        $this->MachineModel->where('id',$request->id);
        if(!$this->MachineModel->update()){

            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => 'Error',
            ]);
        }


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

    }


    public function export()
    {


        $request    = json_decode(json_encode($this->request->getGET()));
        $id         = $request->id;

        $this->MachineModel->select('tbl_machine.*,tbl_line.name AS line_name');
        $this->MachineModel->join('tbl_line','tbl_line.id=tbl_machine.line_id');
        $this->MachineModel->where('tbl_machine.id',$id);
        $machineRow = $this->MachineModel->first();

        $this->MachineStatusModel->where('machine_id',$id);
        $statusRow = $this->MachineStatusModel->first();

        $rangeRow = $this->_getTotalOperationRange($request->production_date, $id);

        $start  = $this->_getStartProduction($id);
        $end    = $this->_getCurrentProduction($id);


        $this->AlertsModel->where('DATE(created_at)>=',date('Y-m-d',strtotime($start)));
        $alerts = $this->AlertsModel->findAll();
        
        $data = [
            'line'              => $machineRow->line_name,
            'name'              => $machineRow->name,
            'start'             => $start,
            'end'               => $end,
            'rpm'               => round($this->_averageRpm($id, $start, $end),1),
            'current'           => round($this->_averageCurrent($id, $start, $end), 1),
            'temperature'       => $this->_lastedTemperature($id, $start, $end),
            'maxCurrent'           => round($this->_maximumCurrent($id, $start, $end), 1),
            'maxTemperature'       => $this->_maximumTemperature($id, $start, $end),
            'total'            => $this->_convertToHourMinute($statusRow->total_operation_time),
            'target'            => $machineRow->target_time,
            'is_connect'        => $machineRow->status,
            'alerts'           => $alerts,
            'type'           => $request->type,
            // 'total'            => $this->_convertToHourMinute($statusRow->total_operation_time),
            // 'today'            => $this->_convertToHourMinute($statusRow->operation_time_today),
            // 'range'            => json_decode(json_encode($rangeRow)),
            // 'average_current_today'            => $this->_convertToHourMinute($statusRow->average_current_today),
            // 'average_operation_daily'            => $this->_convertToHourMinute($statusRow->average_operation_daily),
            // 'average_temperature_today'            => $this->_convertToHourMinute($statusRow->average_temperature_today),
            // 'average_rpm_today'            => $this->_convertToHourMinute($statusRow->average_rpm_today),
        ];
        
        // print_r($data); die;
        return view('app/export/excel/excel', $data);
    }


    public function reset()
    {


        $request    = json_decode(json_encode($this->request->getGET()));
        $id         = $request->id;

        $machineRow = $this->MachineModel->find($id);

        if(intval($machineRow->status)=="ON"){

            return $this->response->setJSON([
                'code'      => 200,
                'success'   => false,
                'message'   => 'You need to turn off the machine if you want to reset ',
            ]);
        }


        $this->MachineModel->set('lasted_reset_at', date('Y-m-d H:i:s'));

        $this->MachineModel->set('has_send',0);
        $this->MachineModel->where('id',$id);
        $this->MachineModel->update();
        $this->MachineStatusModel->set('total_operation_time',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',$id);
        $this->MachineStatusModel->update();


        $this->_sendNotifHasBeenReset();

        return $this->response->setJSON([
            'code'      => 200,
            'success'   => true,
            'message'   => 'Reset machine is successfully',
        ]);



    }


    private function _sendNotifHasBeenReset()
    {

        $currentTime = date('Y-m-d H:i:s');
        $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("🔄 System Reset Confirmation
// 📅 Date: ". formatDate($currentTime) ."
// ⏰ Time: ". formatTime($currentTime) ."

// Dear Mr. $sub_e->name, 

// Your machine has just finished undergoing maintenance. It's been fully checked, reset, and is now ready for you to use again. Everything’s running smoothly, but let us know if anything comes up!.  

// You can continue monitoring the system in real-time through the dashboard below:  

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

// Thank you for your dedication in keeping the system in optimal condition.  

// Best regards,
// 🚀 IoT Monitoring System");

                $text = urlencode("🔄 System Reset Confirmation
📅 Date: ". formatDate($currentTime) ."
⏰ Time: ". formatTime($currentTime) ."

Dear Mr. $sub_e->name, 

The maintenance process has been successfully completed, and the system has been reset. The equipment is now operational and running under normal conditions.  

You can continue monitoring the system in real-time through the dashboard below:  

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

Thank you for your dedication in keeping the system in optimal condition.  

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);
            }
        }
            
    }


    private function _getTotalOperationRange($date, $id)
    {   

        $start  = 'x-x-x';
        $end    = 'x-x-x';
        $value  = 0;

        $lasted = $this->MachineModel->find($id);
        $lasted_reset_at = isset($lasted->lasted_reset_at) ? $lasted->lasted_reset_at : null ;

        if(empty($lasted_reset_at)){

            $this->MachineDailyLog->select('SUM(operation) AS total');
            $this->MachineDailyLog->where('machine_id', $id);
            $row = $this->MachineDailyLog->first();

            if(!empty( (array) $row)){
                
                $this->MachineDailyLog->select('created_at');
                $this->MachineDailyLog->where('machine_id',$id);
                $this->MachineDailyLog->orderBy('created_at','ASC');
                $first = $this->MachineDailyLog->first();

                $start = isset($first->created_at)&&!empty( (array) $first) ? date('d-m-Y', strtotime($first->created_at)) : 'x-x-x';
                $end = date('d-m-Y', strtotime($date));
                $value = isset($row->total)&&!empty($row->total) ? $this->_convertToHourMinute($row->total) : 0;
            }


            return [
                'start' => $start,
                'end' => $end,
                'value' => $value,
            ];


        }else{

            $this->MachineDailyLog->select('SUM(operation) AS total');
            $this->MachineDailyLog->where('machine_id', $id);
            $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($date)));
            $row = $this->MachineDailyLog->first();

            $start = date('d-m-Y', strtotime($lasted_reset_at));
            $end = date('d-m-Y', strtotime($date));
            $value = isset($row->total)&&!empty($row->total) ? $this->_convertToHourMinute($row->total) : 0;

            return [
                'start' => $start,
                'end' => $end,
                'value' => $value,
            ];

        }


    }


    function convertSecondsToTime($seconds)
    {

        $seconds = intval($seconds);
        $hours = floor($seconds / 3600);
        $minutes = floor(($seconds % 3600) / 60);

        return "{$hours}.{$minutes}";
    }


    private function _convertToHourMinute($decimalHour) {
        $decimalHour = floatval($decimalHour); // Pastikan angka float

        $jam = floor($decimalHour); // Ambil jam
        $menit = round(($decimalHour - $jam) * 60); // Konversi sisa ke menit

        if ($menit === 0) {
            return (string) $jam; // Jika menitnya 0, hanya tampilkan jam
        } else {
            return $jam . '.' . str_pad($menit, 2, "0", STR_PAD_LEFT); // Format jam.menit
        }
    }


    public function _getStartProduction($id)
    {

        $this->MachineModel->select('lasted_reset_at');
        $this->MachineModel->where('id',$id);
        $row = $this->MachineModel->first();
        if(!empty( (array) $row )){
            if(!empty($row->lasted_reset_at)){

                return $row->lasted_reset_at;

            }
        }



        $this->MachineLogModel->select('created_at');
        $this->MachineLogModel->where('machine_id',$id);
        $this->MachineLogModel->orderBy('id',"ASC");
        $this->MachineLogModel->limit(1);
        $lasted = $this->MachineLogModel->first();
        
        $lasted = !empty( (array) $lasted ) ? $lasted->created_at  : date('d-m-Y H:i:s'); 
        $lasted = !empty($lasted) ? $lasted  : date('d-m-Y H:i:s'); 

        return $lasted;
        

    }


    public function _getCurrentProduction($id)
    {

        $this->MachineLogModel->select('created_at');
        $this->MachineLogModel->where('id',$id);
        $this->MachineLogModel->orderBy('id',"DESC");
        $this->MachineLogModel->limit(1);
        $lasted = $this->MachineLogModel->first();
        $lasted = !empty( (array) $lasted ) ? $lasted->created_at  : date('Y-m-d H:i:s'); 
        $lasted = !empty($lasted ) ? $lasted : date('Y-m-d H:i:s'); 

        return $lasted;

    }


    public function _averageRpm($id, $start, $end)
    {

        $this->MachineLogModel->select('AVG(rpm) AS rpm');
        $this->MachineLogModel->where('machine_id',$id);
        $this->MachineLogModel->where('created_at>=',$start);
        $this->MachineLogModel->where('created_at<=',$end);
        $row = $this->MachineLogModel->first();
        $row = !empty( (array) $row) ? $row->rpm : 0; 

        return !empty($row) ? $row : 0; 



    }


    public function _averageCurrent($id, $start, $end)
    {


        $this->MachineLogModel->select('AVG(current) AS current');
        $this->MachineLogModel->where('machine_id',$id);
        $this->MachineLogModel->where('created_at>=',$start);
        $this->MachineLogModel->where('created_at<=',$end);
        $row = $this->MachineLogModel->first();
        
        $row = !empty( (array) $row) ? $row->current : 0; 
        return !empty($row) ? $row : 0; 


    }

    public function _lastedTemperature($id, $start = null, $end = null)
    {

        $this->MachineLogModel->select('temperature');
        $this->MachineLogModel->where('machine_id',$id);
        $this->MachineLogModel->where('created_at>=',$start);
        $this->MachineLogModel->where('created_at<=',$end);
        $this->MachineLogModel->orderBy('id',"DESC");
        $this->MachineLogModel->limit(1);
        $row = $this->MachineLogModel->first();
        $row = !empty( (array) $row) ? $row->temperature : 0; 

        return !empty($row) ? $row : 0; 
    }


    private function _maximumCurrent($id, $start, $end)
    {

        $this->MachineLogModel->select('MAX(current) AS current');
        $this->MachineLogModel->where('machine_id',$id);
        $this->MachineLogModel->where('created_at>=',$start);
        $this->MachineLogModel->where('created_at<=',$end);
        $row = $this->MachineLogModel->first();
        
        $row = !empty( (array) $row) ? $row->current : 0; 
        return !empty($row) ? $row : 0; 
    }


    public function _maximumTemperature($id, $start = null, $end = null)
    {

        $this->MachineLogModel->select('MAX(temperature) AS temperature');
        $this->MachineLogModel->where('machine_id',$id);
        $this->MachineLogModel->where('created_at>=',$start);
        $this->MachineLogModel->where('created_at<=',$end);        
        $row = $this->MachineLogModel->first();
        $row = !empty( (array) $row) ? $row->temperature : 0; 

        return !empty($row) ? $row : 0; 
    }



}
