<?php
	defined('BASEPATH') or exit('No direct script access allowed');
	
	use PHPUnit\Util\Json;
	use Curl\Curl;
	
	class Whatsapp extends CI_Controller
	{
		var $title;
		private $token;
		private $curl;
		var $output;
		var $template;
		var $input;
		private $trackingTemplateTitle = 'Link Tracking Pesanan';
		
		protected $perPage = 10;

		public function __construct()
		{
			parent::__construct();

			cek_session_login();

			// ✅ pastikan dependency yang dipakai memang ter-load
			$this->load->model('Model_app', 'model_app');
			$this->load->model('Model_data', 'model_data');
			$this->load->library('Ajax_pagination');

			$this->title = info()['title'];
			$this->curl  = new Curl();
		}
		
		/**
			* index
			*
			* @return void
		*/
		public function index()
		{
			cek_menu_akses();
			$tab = strtolower((string) $this->input->get('tab'));
			$tab = in_array($tab, array('device', 'template', 'report'), true) ? $tab : 'device';

			if ($tab === 'template' || $tab === 'report') {
				cek_crud_akses(8);
			}

			if ($tab === 'template') {
				$this->ensureTrackingTemplate();
			}

			$views = array(
				'device' => array('title' => 'Device', 'view' => 'whatsapp/device'),
				'template' => array('title' => 'Template Pesan', 'view' => 'whatsapp/template'),
				'report' => array('title' => 'Report Pesan', 'view' => 'whatsapp/report')
			);
			$data['title'] = $views[$tab]['title'] . ' | ' . $this->title;
			$data['ip'] = $this->input->ip_address();
			if ($this->input->get('partial') === '1' && $this->input->is_ajax_request()) {
				$data['wa_workspace_partial'] = true;
				$this->load->view($views[$tab]['view'], $data);
				return;
			}
			$this->template->load('main/themes', $views[$tab]['view'], $data);
		}
		
		public function report()
		{
			cek_menu_akses();
			cek_crud_akses(8);
			redirect('whatsapp?tab=report');
		}
		
		public function ajaxReport()
		{
			$page = $this->input->post('page');
			if(!$page){ 
				$offset = 0; 
				}else{ 
				$offset = $page; 
			} 
			
			$limits = $this->input->post('limits'); 
			if(!empty($limits)){ 
				$limit = $limits; 
				}else{ 
				$limit = $this->perPage; 
			} 
			// Set conditions for search and filter 
			$keywords = $this->input->post('keywords'); 
			$sortBy = $this->input->post('sortBy'); 
			$statusFilter = $this->input->post('statusFilter');
			if(!empty($keywords)){ 
				$conditions['search']['keywords'] = $keywords; 
			} 
			if(!empty($sortBy)){ 
				$conditions['search']['sortBy'] = $sortBy; 
			} 
			if(!empty($statusFilter)){
				$conditions['search']['statusFilter'] = $statusFilter;
			}
			
			$conditions['returnType'] = 'count'; 
			$totalRec = $this->model_data->getReport($conditions); 
			
			// Pagination configuration 
			$config['target']      = '#data_report'; 
			$config['base_url']    = base_url('whatsapp/ajaxReport'); 
			$config['total_rows']  = $totalRec; 
			$config['per_page']    = $limit; 
			$config['link_func']   = 'search_LaporanGrup'; 
			
			// Initialize pagination library 
			$this->ajax_pagination->initialize($config); 
			// Get records 
			$conditions['start'] = $offset; 
			$conditions['limit'] = $limit;
			unset($conditions['returnType']); 
			
			$data['result'] = $this->model_data->getReport($conditions); 
			// dump($data['result']);
			$this->load->view('whatsapp/ajax-report', $data, false); 
		}

		/**
		 * Menjelaskan konfigurasi sinkronisasi status.
		 * API /status Fonnte telah dihentikan; pembaruan hanya melalui webhook.
		 */
		public function sync_report_status()
		{
			cek_crud_akses(8);
			$callbackUrl = base_url('fonnte/status-callback');
			$devices = $this->model_app->views('device')->result();
			$results = [];
			$success = 0;

			foreach ($devices as $device) {
				$result = $this->register_status_webhook((string) $device->token, $device);
				$results[] = [
					'device' => maskNomor((string) $device->device),
					'status' => !empty($result['status']),
					'msg' => isset($result['msg']) ? $result['msg'] : ''
				];
				if (!empty($result['status'])) {
					$success++;
				}
			}

			$allSynced = !empty($devices) && $success === count($devices);
			$this->output
				->set_content_type('application/json', 'utf-8')
				->set_output(json_encode([
					'status' => $allSynced,
					'code' => $allSynced ? 'webhook_registered' : 'webhook_registration_failed',
					'callback_url' => $callbackUrl,
					'msg' => $allSynced
						? 'Sinkronisasi status Fonnte aktif untuk '.$success.' device.'
						: 'Webhook belum aktif pada semua device. Pastikan aplikasi memakai HTTPS publik dan token device masih valid.',
					'devices' => $results
				], JSON_UNESCAPED_UNICODE));
		}

		public function hapus_report()
		{
			$id = decrypt_url($this->input->post('id'));
			$konsumen = decrypt_url($this->input->post('konsumen'));

			if (!empty($konsumen)) {
				$cek_konsumen = $this->model_app->edit('konsumen', ['id' => $konsumen])->num_rows();
				if ($cek_konsumen > 0) {
					$this->model_app->update('konsumen', ['kunci' => 0], ['id' => $konsumen]);
				}
			}

			$cek_report = $this->model_app->edit('report_pesan', ['id' => $id])->num_rows();
			if ($cek_report > 0) {
				$delete = $this->model_app->delete('report_pesan', ['id' => $id]);
				$result = $delete
					? ['status' => 200, 'msg' => 'Data berhasil dihapus']
					: ['status' => 400, 'msg' => 'Data gagal dihapus'];
			} else {
				$result = ['status' => 400, 'msg' => 'Data tidak ditemukan'];
			}

			$this->output
			->set_content_type('application/json')
			->set_output(json_encode($result));
		}
		/**
			* data_device
			*
			* @return void
		*/
		public function data_device()
		{
			$device = $this->model_app->views('device')->result();
			$html ='';
			if(!empty($device)){
				foreach($device AS $row)
				{
					if ($row->device_status == 'connect') {
						$device_status = 'Terhubung';
						$device_btn = 'success';
						$scan_qr = 'logout_qr';
						}else{
						$device_btn = 'danger';
						$scan_qr = 'scan_qr';
						$device_status = 'Klik untuk memindai';
					}
					
					$is_connected = ($row->device_status === 'connect');
					$html .= '<article class="wa-device-card" data-connected="'.($is_connected ? '1' : '0').'" data-quota="'.(int) $row->quota.'">';
					$html .= '<div class="wa-device-card-top"><div class="wa-device-identity"><span class="wa-device-avatar"><i class="fa fa-whatsapp"></i></span><div><a href="javascript:void(0)" class="add_device wa-device-number" data-id="'.$row->id.'">'.maskNomor($row->device).'</a><span class="wa-device-edit">Klik nomor untuk mengubah token</span></div></div><span class="wa-status-pill '.($is_connected ? '' : 'disconnected').'"><i class="wa-status-dot"></i>'.$device_status.'</span></div>';
					$html .= '<div class="wa-device-metrics"><div class="wa-device-metric"><small>Expired</small><strong>'.html_escape($row->expired).'</strong></div><div class="wa-device-metric"><small>Kuota</small><strong>'.number_format((int) $row->quota, 0, ',', '.').'</strong></div><div class="wa-device-metric"><small>Paket</small><strong>'.html_escape($row->package).'</strong></div></div>';
					$html .= '<div class="wa-device-actions"><button type="button" class="btn '.$scan_qr.'" token-id="'.$row->token.'" title="'.$device_status.'"><i class="fa fa-qrcode"></i>'.($is_connected ? 'Kelola Koneksi' : 'Scan QR').'</button><button type="button" class="btn cek_status" token-id="'.$row->token.'"><i class="fa fa-refresh"></i>Cek Status</button><a class="btn wa-delete" data-toggle="modal" data-target="#confirm-delete" data-id="'.$row->id.'" href="#"><i class="fa fa-trash"></i>Hapus</a></div>';
					$html .= '</article>';
				}
				}else{
				$html .= '<div class="wa-device-empty"><i class="fa fa-mobile"></i><strong>Belum ada device</strong><div>Tambahkan token WhatsApp API untuk mulai menghubungkan perangkat.</div></div>';
			}
			echo $html;
		}
		
		/**
			* cek_status
			*
			* @return void
		*/
		public function cek_status()
		{
			$token = decrypt_url($this->input->post('token'));
			$result = $this->fonnte('https://api.fonnte.com/device',$token);
			
			if ($result['status'] == true) {
				if ($result['msg']->status == true) {
					$this->update_device($result['msg'],$token);
					$data = $result['msg'];
					} else {
					$data = $result['msg'];
				}
			}
			if ($result['status'] == false) {
				$data = ['status' => false, 'msg' => $result['msg']];
			}
			$this->output
			->set_content_type('application/json')
			->set_output(json_encode($data, JSON_UNESCAPED_UNICODE));

		}
		/**
			* cek_status
			*
			* @return void
		*/
		public function cek_status_device()
		{
			$token = ($this->input->post('token'));
			$result = $this->fonnte('https://api.fonnte.com/device',$token);
			
			if ($result['status'] == true) {
				if ($result['msg']->status == true) {
					$this->update_device($result['msg'],$token);
					$data = $result['msg'];
					} else {
					$data = $result['msg'];
				}
			}
			if ($result['status'] == false) {
				$data = ['status' => false, 'msg' => $result['msg']];
			}
			$this->output
			->set_content_type('application/json')
			->set_output(json_encode($data, JSON_UNESCAPED_UNICODE));

		}
		
		
		/**
			* scan_qr
			*
			* @return void
		*/
		public function scan_qr()
		{
			$token = $this->input->post('token');
			// cek_promo('get',$token);
			$result = $this->fonnte('https://api.fonnte.com/qr',$token);
			// dump($result);
			$_token = (object)['token'=>$token];
			if ($result['status'] == true) {
				if ($result['msg']->status == true) {
					$data = $result['msg'];
					} else {
					$data = $result['msg'];
				}
			}
			if ($result['status'] == false) {
				$data = ['status' => false, 'msg' => $result['msg']];
			}
			$obj_merged = (object) array_merge((array) $data, (array) $_token);
			
			$this->output
			->set_content_type('application/json')
			->set_output(json_encode($obj_merged));
		}
		
		/**
			* logout_device
			*
			* @return string
		*/
		public function logout_device()
		{
			$token = $this->input->post('token');
			$status = cek_demo_promo('disconnect',$token);
			if ($status['status'] == true) {
				$response = $status;
				} else {
				$response = $this->fonnte('https://api.fonnte.com/disconnect',$token);
			}
			$this->output
			->set_content_type('application/json')
			->set_output(json_encode($response));
		}
		
		/**
			* validate_number
			*
			* @return string
		*/
		public function validate_number()
		{
			$token = $this->input->post('token');
			$target = $this->input->post('target');
			$cek_nomor = array(
			'target' => $target,
			'countryCode' => '62'
			);
			
			$this->curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
			$this->curl->setDefaultJsonDecoder($assoc = true);
			$this->curl->setHeader('Authorization', $token);
			$this->curl->setHeader('Content-Type', 'application/json');
			$this->curl->post('https://api.fonnte.com/validate', $cek_nomor);
			if ($this->curl->error) {
				$result = ['status' => false, 'msg' => $this->curl->errorMessage];
				} else {
				$result = ['status' => true, 'msg' => (object)$this->curl->response];
			}
			
			if ($result['status'] == true) {
				if (!empty($result->registered)) {
					$data = ['status' => true, 'msg' => 'OK'];
					} else {
					$data = ['status' => false, 'msg' => 'ERROR'];
				}
				} else {
				$data = ['status' => false, 'msg' => $result['msg']];
			}
			$this->output
			->set_content_type('application/json')
			->set_output(json_encode($data, JSON_UNESCAPED_UNICODE));

		}
		
		/**
			* fonnte
			*
			* @param  mixed $url
			* @return array
		*/
		private function fonnte($url,$token="")
		{
			$this->curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
			$this->curl->setDefaultJsonDecoder($assoc = true);
			$this->curl->setHeader('Authorization', $token);
			$this->curl->setHeader('Content-Type', 'application/json');
			$this->curl->post($url);
			if ($this->curl->error) {
				$result = ['status' => false, 'msg' => $this->curl->errorMessage];
				} else {
				$result = ['status' => true, 'msg' => (object)$this->curl->response];
			}
			return $result;
		}

		private function _is_local_baseurl(): bool
{
	$web = base_url();

	// localhost
	if (stripos($web, 'localhost') !== false) return true;

	// IP address
	if (preg_match('/\b\d{1,3}(\.\d{1,3}){3}\b/', $web)) return true;

	return false;
}

private function _is_online(): bool
{
	$targets = [
		['host' => '8.8.8.8', 'port' => 53],
		['host' => '1.1.1.1', 'port' => 53],
		['host' => 'api.fonnte.com', 'port' => 443],
	];

	foreach ($targets as $t) {
		$fp = @fsockopen($t['host'], $t['port'], $errno, $errstr, 1.5);
		if ($fp) {
			fclose($fp);
			return true;
		}
	}
	return false;
}

		
		/**
			* load_device
			*
			* @param  mixed $param
			* @return void
		*/
		public function load_device()
		{
			$load = $this->model_app->views('device')->result();
			foreach($load AS $row)
			{
				$response[] = array("id"=>encrypt_url($row->token),"name"=>$row->device);
			}
			$this->output
			->set_content_type('application/json')
			->set_output(json_encode($response));
		}
		/**
			* add_device
			*
			* @param  mixed $param
			* @return void
		*/
		public function add_device()
		{
			$id = $this->input->post('id');
			$tipe = $this->input->post('tipe');
			$token = $this->input->post('token');
			
			if($tipe=='get' AND $id==0)
			{
				simpan_demo('Tambah');
				$response = ['status'=>false,'id'=>0];
			}
			
			if($tipe=='get' AND $id > 0)
			{
				// simpan_demo('Simpan');
				cek_crud_akses(8);//read
				$cek = $this->model_app->view_where('device', ['id' => $id]);
				if ($cek->num_rows() > 0) {
					$response = ['status'=>200,'id'=>$id,'token'=>maskString($cek->row()->token)];
					} else {
					$response = ['status'=>false,'token'=>''];
				}
			}
			
			if($tipe=='add')
			{
				simpan_demo('Simpan');
				cek_crud_akses(7);//create
				$cek = $this->model_app->view_where('device', ['token' => $token]);
				if ($cek->num_rows() > 0) {
					$response = ['status'=>false,'msg'=>'Token Sudah ada'];
					} else {
					$input = $this->model_app->input('device', ['token' => $token]);
					if($input['status']=='ok')
					{
						$response = ['status'=>200,'msg'=>'Berhasil di simpan'];
						$this->get_data_fonnte($token);
						}else{
						$response = ['status'=>false,'msg'=>'Gagal di simpan'];
					}
				}
			}
			
			if($tipe=='edit' AND $id > 0)
			{
				simpan_demo('Simpan');
				cek_crud_akses(9,'json');//update
				$cek = $this->model_app->view_where('device', ['token'=>$token,'id !=' => $id]);
				if ($cek->num_rows() > 0) {
					$response = ['status'=>false,'msg'=>'Token Sudah ada'];
					}else{
					$update = $this->model_app->update('device', ['token'=>$token], ['id' => $id]);
					if($update['status']=='ok')
					{
						$response = ['status'=>200,'msg'=>'Berhasil di update'];
						$this->get_data_fonnte($token);
						}else{
						$response = ['status'=>false,'msg'=>'Gagal di update'];
					}
				}
			}
			
			if($tipe=='hapus' AND $id > 0)
			{
				cek_crud_akses(10,'json');//delete
				$cek = $this->model_app->view_where('device', ['id' => $id]);
				if ($cek->num_rows() > 0) {
					$hapus = $this->model_app->hapus('device', array('id' => $id));
					if($hapus['status']=='ok')
					{
						$response = ['status'=>200,'msg'=>'Berhasil di hapus'];
						}else{
						$response = ['status'=>false,'msg'=>'Gagal di hapus'];
					}
					}else{
					$response = ['status'=>false,'msg'=>'Data tidak ditemukan'];
				}
			}
			
			$this->output
			->set_content_type('application/json')
			->set_output(json_encode($response));
		}
		
		/**
			* cek_status
			*
			* @return void
		*/
		public function get_data_fonnte($token)
		{
			
			$result = $this->fonnte('https://api.fonnte.com/device',$token);
			
			if ($result['status'] == true) {
				if ($result['msg']->status == true) {
					$this->update_device($result['msg'],$token);
					$this->register_status_webhook($token, $result['msg']);
				}
			}
			
		}
		
		/**
			* update_device
			*
			* @param  mixed $param
			* @return void
		*/
		private function update_device($array,$token)
		{
			$param = [
			'device'       => $array->device,
			'device_status'=> $array->device_status,
			'expired'      => $array->expired,
			'messages'     => $array->messages,
			'name'         => $array->name,
			'package'      => $array->package,
			'quota'        => $array->quota,
			];
			
			$cek = $this->model_app->view_where('device', ['token' => $token]);
			if ($cek->num_rows() > 0) {
				$this->model_app->update('device', $param, ['token' => $token]);
			}
		}
		
		/**
			* get_pesan
			*
			* @return void
		*/
		public function get_pesan()
{
	if (!$this->input->is_ajax_request()) {
		show_404();
	}

	$idorder     = $this->input->post('idorder');
	$deid        = decrypt_url($idorder);
	$status      = xss_filter($this->input->post('status'), 'xss');
	$nomor_order = xss_filter($this->input->post('nomor_order'), 'xss');
	$tgl         = xss_filter($this->input->post('tgl'), 'xss');

	$data = ['status' => false, 'msg' => '', 'pesan' => ''];

	if (empty($deid) || empty($status)) {
		return $this->output->set_content_type('application/json')->set_output(json_encode($data, JSON_UNESCAPED_UNICODE));

	}

	$pesan = '';
	$rowTpl = ($status === 'tracking_link')
		? $this->trackingTemplateRow()
		: $this->model_app->view_where('template_pesan', ['id' => $status])->row();
	$pesan  = isset($rowTpl->deskripsi) ? $rowTpl->deskripsi : '';

	if (empty($pesan)) {
		$data['msg'] = 'Template tidak ditemukan.';
		return $this->output->set_content_type('application/json')->set_output(json_encode($data, JSON_UNESCAPED_UNICODE));
	}

	$trx = get_id_transaksi($deid);
	if (!is_array($trx) || empty($trx)) {
		$data['msg'] = 'Transaksi tidak ditemukan.';
		return $this->output->set_content_type('application/json')->set_output(json_encode($data, JSON_UNESCAPED_UNICODE));

	}

	$id_fo      = $trx['id_fo'] ?? null;
	$idkonsumen = $trx['idkonsumen'] ?? null;

	$fo        = ($id_fo) ? (cekUser($id_fo)['nama'] ?? '-') : '-';
	$nama      = ($idkonsumen) ? (cekKonsumen($idkonsumen)['nama'] ?? '-') : '-';
	$panggilan = ($idkonsumen) ? (cekKonsumen($idkonsumen)['panggilan'] ?? '') : '';

	$tot = $this->total($deid);

	// status order
	$piutangRaw = $tot['piutang'] ?? '0';
	$piutangNum = (int)preg_replace('/\D/', '', (string)$piutangRaw);
	$status_order = ($piutangNum > 0) ? 'BELUM LUNAS' : 'LUNAS';

	// ✅ text mode supaya rapih di textarea
	$detail   = $this->kirim_rincian($deid, 'text');
	$rekening = $this->_rekening_tag('text');
	$tracking_link = base_url('tracking-pesanan/') . rawurlencode($idorder);
	$tracking_data = $this->boardTrackingData($deid);
	$tracking_status = isset($tracking_data['status_label']) ? $tracking_data['status_label'] : 'Baru';

	// ✅ token/device (kalau fungsi get_device() memang ada di project kamu)
	$tokenDevice = function_exists('get_device') ? get_device() : '';

	// ✅ BLOK WAJIB ONLINE (muncul saat pilih jenis pesan)
	if ($this->_is_local_baseurl()) {
		$data = [
			'status' => false,
			'msg'    => 'Aplikasi harus online (pakai domain publik), karena link invoice tidak bisa diakses jika masih localhost / IP lokal.',
			'pesan'  => ''
		];
		return $this->output
			->set_content_type('application/json')
			->set_output(json_encode($data, JSON_UNESCAPED_UNICODE));
	}

	// ✅ optional: jika server tidak ada internet sama sekali
	if (!$this->_is_online()) {
		$data = [
			'status' => false,
			'msg'    => 'Aplikasi harus online / terhubung internet untuk menggunakan fitur WhatsApp.',
			'pesan'  => ''
		];
		return $this->output
			->set_content_type('application/json')
			->set_output(json_encode($data, JSON_UNESCAPED_UNICODE));
	}

	$searchVal = array(
		"{perusahaan}",
		"{web}",
		"{link}",         // ✅ alias untuk link_mobile
		"{link_mobile}",
		"{link_desktop}",
		"{tracking}",
		"{tracking_link}",
		"{link_tracking}",
		"{tracking_status}",
		"{selamat}",
		"{invoice}",
		"{tgl}",
		"{fo}",
		"{hp}",
		"{detail}",
		"{total}",
		"{bayar}",
		"{diskon}",
		"{cashback}",
		"{piutang}",
		"{status}",
		"{email}",
		"{alamat}",
		"{token}",        // ✅ token/device
		"{rekening}",
		"{nama}",
		"{panggilan}"
	);

	$replaceVal = array(
		info()['perusahaan'],
		base_url(),
		base_url('e-invoice-mobile/') . $idorder,  // {link}
		base_url('e-invoice-mobile/') . $idorder,
		base_url('e-invoice-desktop/') . $idorder,
		$tracking_link,
		$tracking_link,
		$tracking_link,
		$tracking_status,
		ucapan(),
		$nomor_order,
		dtimes($tgl, false, false),
		$fo,
		hp62(info()['phone']),
		$detail,
		$tot['total'] ?? 0,
		$tot['bayar'] ?? 0,
		$tot['diskon'] ?? 0,
		$tot['cashback'] ?? 0,
		$tot['piutang'] ?? 0,
		$status_order,
		info()['email'],
		strip_word_html(base64_decode(info()['deskripsi'])),
		$tokenDevice,
		$rekening,
		$nama,
		$panggilan
	);

	$hasil = str_replace($searchVal, $replaceVal, $pesan);

	// ✅ rapikan line break untuk textarea
	$hasil = str_replace(["\r\n", "\r"], "\n", $hasil);

	$data = array(
		'status' => true,
		'msg'    => $hasil,   // untuk JS lama
		'pesan'  => $hasil    // untuk JS versi baru
	);

	$this->output->set_content_type('application/json')->set_output(json_encode($data, JSON_UNESCAPED_UNICODE));

}

	private function boardTrackingData($idInvoice)
	{
		$idInvoice = (int) $idInvoice;
		if ($idInvoice <= 0) {
			return ['status_label' => 'Baru'];
		}

		$this->load->model('StatusBoard_model', 'status_board');
		$tracking = $this->status_board->getPublicTracking($idInvoice);
		if (!$tracking || empty($tracking['order'])) {
			return ['status_label' => 'Baru'];
		}

		return $tracking['order'];
	}

	/**
	 * Daftarkan endpoint pembaruan status ke device Fonnte. Fonnte tidak
	 * mengambil URL callback dari endpoint /send, sehingga konfigurasi ini
	 * memang harus disimpan pada device melalui /update-device.
	 */
	private function register_status_webhook($token, $deviceData = null)
	{
		$callbackUrl = base_url('fonnte/status-callback');
		$host = strtolower((string) parse_url($callbackUrl, PHP_URL_HOST));
		$scheme = strtolower((string) parse_url($callbackUrl, PHP_URL_SCHEME));

		// Server Fonnte tidak dapat memanggil domain lokal.
		if ($scheme !== 'https' || $host === 'localhost' || substr($host, -5) === '.test' || filter_var($host, FILTER_VALIDATE_IP)) {
			return ['status' => false, 'msg' => 'Callback memerlukan domain HTTPS publik.'];
		}

		if (empty($deviceData) || empty($deviceData->device) || empty($deviceData->name)) {
			$deviceResult = $this->fonnte('https://api.fonnte.com/device', $token);
			if (empty($deviceResult['status']) || empty($deviceResult['msg']->status)) {
				return ['status' => false, 'msg' => 'Data device Fonnte tidak dapat dibaca.'];
			}
			$deviceData = $deviceResult['msg'];
		}

		$post = [
			'name' => (string) $deviceData->name,
			'device' => (string) $deviceData->device,
			'webhookstatus' => $callbackUrl
		];

		$ch = curl_init('https://api.fonnte.com/update-device');
		curl_setopt_array($ch, [
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_POST => true,
			CURLOPT_POSTFIELDS => $post,
			CURLOPT_HTTPHEADER => ['Authorization: '.$token],
			CURLOPT_CONNECTTIMEOUT => 8,
			CURLOPT_TIMEOUT => 20,
			CURLOPT_SSL_VERIFYPEER => true
		]);
		$body = curl_exec($ch);
		$error = curl_error($ch);
		$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);

		$response = json_decode((string) $body, true);
		$ok = $error === '' && $httpCode >= 200 && $httpCode < 300 && is_array($response) && !empty($response['status']);
		return [
			'status' => $ok,
			'msg' => $ok ? 'Webhook status aktif.' : ($error !== '' ? $error : (isset($response['reason']) ? $response['reason'] : 'Fonnte menolak konfigurasi webhook.'))
		];
	}

	private function trackingTemplateDefault()
	{
		return "{selamat} {nama},\n\nBerikut link untuk melihat progres pesanan Anda.\nNo. Order: {invoice}\nStatus saat ini: {tracking_status}\n\n{tracking}\n\nSilakan buka link tersebut untuk melihat detail dan update progres pesanan.";
	}

	private function trackingTemplateRow()
	{
		return $this->model_app->view_where('template_pesan', ['title' => $this->trackingTemplateTitle])->row();
	}

	private function ensureTrackingTemplate()
	{
		$row = $this->trackingTemplateRow();
		if ($row) {
			return $row;
		}

		$this->model_app->input('template_pesan', [
			'title' => $this->trackingTemplateTitle,
			'deskripsi' => $this->trackingTemplateDefault(),
			'status' => 5,
			'active' => 'Y',
			'create_date' => today()
		]);

		return $this->trackingTemplateRow();
	}

	/**
 * SHORT TAG {rekening}
 * Ambil data dari tabel rekening_bank (sama seperti halaman Pembayaran > Rekening)
 */
private function _rekening_tag($mode = 'text')
{
	$nl = ($mode === 'wa') ? "%0A" : "\n";

	$rows = $this->model_app
		->view_where_ordering('rekening_bank', ['publish' => 'Y'], 'id', 'DESC')
		->result();

	if (!$rows || count($rows) == 0) {
		return '-';
	}

	$out = "Rekening Pembayaran:" . $nl;
	$no = 1;

	foreach ($rows as $r) {
		$nama_bank      = isset($r->nama_bank) ? trim($r->nama_bank) : '';
		$inisial        = isset($r->inisial) ? trim($r->inisial) : '';
		$nomor_rekening = isset($r->nomor_rekening) ? trim($r->nomor_rekening) : '';
		$pemilik        = isset($r->pemilik) ? trim($r->pemilik) : '';

		$labelBank = $nama_bank;
		if ($inisial !== '') $labelBank .= " ($inisial)";
		if ($labelBank === '') $labelBank = 'BANK';

		$line = $no . ". " . $labelBank;
		if ($nomor_rekening !== '') $line .= " - " . $nomor_rekening;
		if ($pemilik !== '') $line .= " a.n " . $pemilik;

		$out .= $line . $nl;
		$no++;
	}

	return rtrim($out, $nl);
}


		
		/**
			* kirim_rincian
			*
			* @param  mixed $id
			* @return string
		*/
		private function kirim_rincian($id, $mode = 'text')
{
	$detail = $this->model_app->produk_cart(array('invoice_detail.id_invoice' => $id));

	$nl = ($mode === 'wa') ? "%0A" : "\n";

	if (empty($detail)) {
		return '-';
	}

	$result = "Detail Order:" . $nl;
	$result .= "----------------------------------" . $nl;

	foreach ($detail as $row) {
		$produk = $row['nama_produk'] ?? $row['title'] ?? $row['produk'] ?? '-';
		$bahan  = $row['nama_bahan'] ?? $row['nbahan'] ?? $row['bahan'] ?? '-';
		$jumlah = $row['jumlah'] ?? '-';
		$harga  = $row['harga'] ?? 0;
		$ukuran = $row['ukuran'] ?? '-';
		$ket    = $row['keterangan'] ?? '-';

		$result .= "Produk : " . $produk . $nl;
		$result .= "Bahan  : " . $bahan . $nl;
		$result .= "Jml.   : " . $jumlah . $nl;
		$result .= "Harga  : " . rp($harga) . $nl;
		$result .= "Ukuran : " . $ukuran . $nl;
		$result .= "Ket.   : " . $ket . $nl;
		$result .= "----------------------------------" . $nl;
	}

	return rtrim($result, $nl);
}

		
		/**
			* kirim_pesan
			*
			* @return void
		*/
		public function kirim_pesan()
		{
			cek_crud_akses(9);
			if ($this->input->is_ajax_request()) {
				
				$token  	   = decrypt_url($this->input->post('device'));
				$nomor_tujuan  = xss_filter($this->input->post('nomor_tujuan'), 'xss');
				$isi_pesan     = xss_filter($this->input->post('isi_pesan'), 'xss');
				
				$remove = array("\r\n", "\r", "<p>", "</p>", "<h1>", "</h1>", "<br>", "<br />", "<br/>");
				$content = str_replace($remove, '', $isi_pesan);
				
				$data_send = array(
				'target' => $nomor_tujuan,
				'message' => $isi_pesan,
				'countryCode' => '62'
				);
				
				$id_konsumen = $this->get_id_konsumen($nomor_tujuan);
				$device_status = cek_device_status($token);
				if ($device_status == true) {
					// Menjamin deployment hosting lama ikut mengaktifkan callback saat
					// pengiriman pertama setelah pembaruan aplikasi.
					$webhookRegistration = $this->register_status_webhook($token);
					if (empty($webhookRegistration['status'])) {
						error_log('Fonnte webhook registration failed: '.($webhookRegistration['msg'] ?? 'unknown error'));
					}
					$this->curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
					$this->curl->setDefaultJsonDecoder($assoc = true);
					$this->curl->setHeader('Authorization', $token);
					$this->curl->setHeader('Content-Type', 'application/json');
					$this->curl->post('https://api.fonnte.com/send', $data_send);
					if ($this->curl->error) {
						$result = ['status' => false, 'msg' => $this->curl->errorMessage];
						} else {
						$response = $this->curl->response;
						$result = ['status' => true, 'msg' => (object)$response];
						$this->report_pesan($response,$isi_pesan,$id_konsumen,$token);
					}
					} else {
					$result = ['status' => false, 'target' => hp62($nomor_tujuan), 'msg' => $isi_pesan];
				}
				} else {
				$result = ['status' => false];
			}
			
			$this->output
			->set_content_type('application/json')
			->set_output(json_encode($result));
		}
		
		private function report_pesan($response,$message,$id_konsumen,$token = '')
		{
			$this->ensure_report_datetime();
			$deviceNumber = '';
			if ($token !== '') {
				$deviceRow = $this->model_app->view_where('device', ['token' => $token])->row();
				$deviceNumber = !empty($deviceRow) ? (string) $deviceRow->device : '';
			}
			if ($deviceNumber === '') {
				$deviceNumber = (string) get_device();
			}
			foreach($response["id"] as $k=>$v){
				$target = $response["target"][$k];
				$process = $response["process"];
				$status = $response["status"];
				$data = ['id_kirim'=>$v,'id_konsumen'=>$id_konsumen,'device'=>$deviceNumber,'target'=>$target,'message'=>$message,'status'=>strtolower(trim((string) $process)),'create_date'=>date('Y-m-d H:i:s')];
				if($status==true){
					$this->model_app->input('report_pesan',$data);
				}
				// dump($data);
			}
			
		}

		private function ensure_report_datetime()
		{
			$column = $this->db->query("SHOW COLUMNS FROM `report_pesan` LIKE 'create_date'")->row_array();
			if (!empty($column) && strtolower((string) $column['Type']) === 'date') {
				$this->db->query('ALTER TABLE `report_pesan` MODIFY `create_date` DATETIME NULL');
			}
		}
		
		/**
			* get_form_wa
			*
			* @return int
		*/
		
		private function get_id_konsumen($nomor)
		{
			
			return $this->model_app->pilih_where('id','konsumen', ['no_hp' => $nomor])->row()->id;
			
		}
		/**
			* get_form_wa
			*
			* @return void
		*/
		public function get_form_wa()
		{
			cek_crud_akses(8);
			if ($this->input->is_ajax_request()) {
				$this->ensureTrackingTemplate();
				
				$id    = $this->input->post('id');
				$deid  = decrypt_url($id);
				$nomor = xss_filter($this->input->post('nomor'), 'xss');
				$tgl   = ($this->input->post('tgl'));
				
				$data['id'] = $id;
				$data['nomor'] = $nomor;
				$data['tgl'] = $tgl;
				$data['user'] = cekUser($deid)['nama'];
				// $data['device'] = $this->load_device();
				$data['id_invoice'] = get_id_transaksi($deid)['nomor_order'];
				$data['jenis'] = $this->model_app->view_where_ordering('template_pesan', ['active' => 'Y'], 'id', 'DESC')->result();
				$data['kirim'] = $this->model_app->view_where('invoice', ['id_invoice' => $deid])->row();
				$data['tracking_link'] = base_url('tracking-pesanan/' . rawurlencode($id));
				$this->load->view('whatsapp/kirim_wa', $data);
			}
		}
		
		/**
			* template
			*
			* @return void
		*/
		public function template()
		{
			cek_menu_akses();
			cek_crud_akses(8);
			redirect('whatsapp?tab=template');
		}
		
		/**
			* data_template
			*
			* @return void
		*/
		public function data_template()
		{
			cek_crud_akses(8);
			$this->ensureTrackingTemplate();
			$data['record'] = $this->model_app->view_where_ordering('template_pesan', array(), 'id', 'DESC')->result();
			$this->load->view('whatsapp/data_template', $data);
		}
		
		/**
			* total
			*
			* @param  mixed $id
			* @return array
		*/
		private function total($id)
		{
			
			$total_order = $this->model_app->sum_data('total_bayar', 'invoice', ['id_invoice' => $id]);
			$totalorder = $total_order > 0 ? rp($total_order) : 0;
			$total_bayar = $this->model_app->sum_data('jml_bayar', 'bayar_invoice_detail', ['id_invoice' => $id]);
			$totalbayar = $total_bayar > 0 ? rp($total_bayar) : 0;
			
			$_diskon = $this->model_app->sum_data('potongan_harga', 'invoice', ['id_invoice' => $id]);
			$diskon = $_diskon > 0 ? rp($_diskon) : 0;
			$cashback = $this->model_app->sum_data('cashback', 'invoice', ['id_invoice' => $id]);
			$cashback = $cashback > 0 ? rp($cashback) : 0;
			if ($total_bayar <= 0) {
				$piutang = $total_order;
				} elseif ($total_bayar > 0 and $total_bayar < $total_order) {
				$piutang = $total_order - $total_bayar - $_diskon;
				} else {
				$piutang = 0;
			}
			
			$result = [
			'total' => $totalorder,
			'bayar' => $totalbayar,
			'diskon' => $diskon,
			'cashback' => $cashback,
			'piutang' => rp($piutang)
			];
			return $result;
		}
		
		/**
			* get_template
			*
			* @return void
		*/
		public function get_template()
		{
			cek_crud_akses(8);
			
			if ($this->input->is_ajax_request()) {
				$id = xss_filter($this->input->post('id'), 'xss');
				if(!empty($id)){
					$row = $this->model_app->view_where('template_pesan', ['id' => $id])->row();
					$result = [
					'status' => true,
					'id' => $id,
					'title' => $row->title,
					'deskripsi' => $row->deskripsi,
					'publish' => $row->active
					];
					} else {
					$result = [
					'status' => true,
					'id' => 0,
					'title' =>'',
					'deskripsi' =>'',
					'publish' =>'Y'
					];
				}
				}else{
				$result = ['status' => false];
			}
			$this->output
			->set_content_type('application/json')
			->set_output(json_encode($result));
		}
		
		/**
			* save_template
			*
			* @return void
		*/
		public function save_template()
		{
			if ($this->input->is_ajax_request()) {
				$type      = xss_filter($this->input->post('type'), 'xss');
				$title     = xss_filter($this->input->post('title'), 'xss');
				$deskripsi = xss_filter($this->input->post('deskripsi'));
				$deskripsi = ($deskripsi);
				$active    = $this->input->post('publish');
				
				$this->form_validation->set_rules(array(array(
				'field' => 'title',
				'label' => 'Title',
				'rules' => 'required|trim',
				'errors' => array(
				'required' => '%s. Harus di isi'
				)
				)));
				
				$this->form_validation->set_rules(array(array(
				'field' => 'deskripsi',
				'label' => 'Deskripsi',
				'rules' => 'required|trim',
				'errors' => array(
				'required' => '%s. Harus di isi'
				)
				)));
				
				if ($this->form_validation->run()) {
					if ($type == 'add') {
						simpan_demo('Simpan');
						$param = ['title' => $title, 'deskripsi' => $deskripsi, 'status' => 5, 'active' => $active, 'create_date' => today()];
						$input =  $this->model_app->input('template_pesan', $param);
						if ($input['status'] == 'ok') {
							$result = array('status' => true, 'msg' => 'Data berhasil diinput');
							} else {
							$result = array('status' => false);
						}
					}
					if ($type == 'edit') {
						simpan_demo('Edit');
						$id = xss_filter($this->input->post('id'), 'xss');
						$param = ['title' => $title, 'deskripsi' => $deskripsi, 'active' => $active];
						$update = $this->model_app->update('template_pesan', $param, ['id' => $id]);
						if ($update['status'] == 'ok') {
							$result = ['status' => true, 'msg' => 'Berhasil'];
							} else {
							$result = ['status' => false, 'msg' => 'Gagal'];
						}
					}
					} else {
					
					$result['status'] = 'error';
					$result['alert']['type'] = 'error';
					$result['alert']['content'] = validation_errors();
				}
				if ($type == 'hapus') {
					simpan_demo('Hapus');
					cek_crud_akses(10);
					$id = xss_filter($this->input->post('id'), 'xss');
					$cek = $this->model_app->view_where('template_pesan', array('id' => $id));
					if ($cek->num_rows() > 0) {
						$res = $this->model_app->hapus('template_pesan', array('id' => $id));
						if ($res['status'] == 'ok') {
							$result = array('status' => 200, 'msg' => 'Data berhasil dihapus');
							} else {
							$result = array('status' => 400, 'msg' => 'Data gagal dihapus');
						}
						} else {
						$result = array('status' => 400, 'msg' => 'Data tidak ditemukan');
					}
				}
				} else {
				$result = ['status' => false];
			}
			$this->output
			->set_content_type('application/json')
			->set_output(json_encode($result));
		}
		
		public function get_media()
		{
			$media = $this->db->query('SELECT * FROM storage ORDER BY id DESC')->result();
			echo '<div class="row">';
			foreach ($media as $m) {
				if (preg_match('/.pdf/', $m->namafile)) {
					$namafile = 'pdf.png';
					} else {
					$namafile = $m->namafile;
				}
				$bb = _storage() .$m->namafile;
				echo '  <div class="col-6 col-xl-2 col-lg-3 col-md-4 col-sm-4">
				<a href="javascript:void(0)" style="text-decoration: none; color: black" data-dismiss="modal" onclick="getmedia(' . "'$bb'" . ')">
				<div class="card">
				<img src="' . base_url('uploads/whatsapp/') . $namafile . '" class="card-img-top" style="max-height: 8rem; min-height: 8rem; object-fit: cover;">
				<div class="card-body p-1 text-center">
				<small style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">' . $m->nama_original . '</small>
				</div>
				</div>
				</a>
				</div>';
			}
			echo '</div>';
		}
		public function upload()
		{
			
			$img = uploadimg([
			'path' => FCPATH."/uploads/whatsapp/",
			'name' => 'fileupload',
			'compress' => false
			]);
			if ($img['result'] == 'success') {
				$this->db->insert('storage', [
				'namafile' => $img['nama_file'],
				'nama_original' => $_FILES['fileupload']['name']
				]);
				echo 'berhasil';
				} else {
				echo 'Hanya File pdf | jpeg | jpg | png yang diizinkan';
			}
		}
	}																										
