<?php
if (session_status() === PHP_SESSION_NONE) session_start();

require_once realpath(dirname(__DIR__, 2) . '/services/Model.php');
$obj = new Model();

require_once realpath(dirname(__DIR__, 2) . '/services/Mikrotik.php'); 

// helper
function json_out($arr, $code = 200){
    http_response_code($code);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($arr, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

$action = $_REQUEST['action'] ?? '';
$id     = isset($_REQUEST['id']) ? (int)$_REQUEST['id'] : 0;
$token  = isset($_REQUEST['token']) ? (int)$_REQUEST['token'] : 0;

if ($token <= 0) json_out(['ok'=>false,'msg'=>'Token missing'], 422);

$agent = $obj->details_by_cond("re_tbl_agent", "ag_id='{$token}'");
if (!$agent) json_out(['ok'=>false,'msg'=>'Customer not found'], 404);


if ($action === 'mik') {
    try {
        if (!$obj->tableExists('re_mikrotik_user')) json_out(['ok'=>false,'msg'=>'Mikrotik table missing']);

        $mik = $obj->details_by_cond('re_mikrotik_user', "user_id=$id");
        
        if (empty($mik['mik_ip']) || empty($mik['mik_username']) || empty($mik['mik_password'])) {
            json_out(['ok'=>false,'msg'=>'Mikrotik not configured']);
        }
        
        $secretName = trim($agent['ip']); 
        
        

        $mikrotik = new Mikrotik($mik['mik_ip'], $mik['mik_port'], $mik['mik_username'], $mik['mik_password']);
        
        
        if (empty($mikrotik->connected)) json_out(['ok'=>false,'msg'=>'Mikrotik connection failed']);


        $mikrotik->write("/ppp/secret/print", false);
        $mikrotik->write("?name=$secretName");
        $read = $mikrotik->read(false);
        $singleSecretData = $mikrotik->parseResponse($read);

        $secret = [];
        if (!empty($singleSecretData)) $secret = $singleSecretData[0];

        //  if not found
        if (empty($secret)) {
            json_out(['ok'=>false,'msg'=>'Secret Invalide']);
        }

        json_out([
            'ok'=>true,
            'data'=>[
                'mikrotikId' => $secret['.id'] ?? '',
                'name'       => $secret['name'] ?? $agent['ip'],
                'password'   => $secret['password'] ?? '',
            ]
        ]);

    } catch (Throwable $e) {
        json_out(['ok'=>false,'msg'=>'Mikrotik error: '.$e->getMessage()], 500);
    }
}



$agent = $obj->details_by_cond("re_tbl_agent", "ag_id='{$token}'");
if (!$agent) json_out(['ok'=>false,'msg'=>'Customer not found'], 404);

// =========================
// ACTION: SAVE (FAST DB ONLY)
// =========================
if ($action === 'save') {
    try {
        $user_id = $_SESSION['userid'] ?? 0;

        if ($user_id <= 0) json_out(['ok'=>false,'msg'=>'Session expired'], 401);

        $ip   = trim($_POST['ip'] ?? '');
        $name = trim($_POST['name'] ?? '');
        $mobile = trim($_POST['mobile'] ?? '');
        $connection_date = trim($_POST['connection_date'] ?? '');
        $zone = (int)($_POST['zone'] ?? 0);
        $regularmobile = trim($_POST['regularmobile'] ?? '');
        $email = trim($_POST['email'] ?? '');
        $macaddress = trim($_POST['macaddress'] ?? '');
        $national_id = trim($_POST['national_id'] ?? '');
        $mb = trim($_POST['mb'] ?? '');
        $taka = (float)($_POST['taka'] ?? 0);
        $re_taka = (float)($_POST['re_taka'] ?? 0);
        $status = (int)($_POST['status'] ?? 0);
        $bill_date = (int)($_POST['bill_date'] ?? 10);
        $address = trim($_POST['address'] ?? '');
        $password = trim($_POST['password'] ?? '');
        
        $mikrotik_disconnect = trim($_POST['mikrotik_disconnect'] ?? '');

        $xtaka = (float)($_POST['xtaka'] ?? 0);
        $xre_taka = (float)($_POST['xre_taka'] ?? 0);
        $status_check = (int)($_POST['status_check'] ?? 0);
        $xprevious_due = (float)($_POST['xprevious_due'] ?? 0);
        $xconnection_charge_due = (float)($_POST['xconnection_charge_due'] ?? 0);

        $previous_due = (float)($_POST['previous_due'] ?? -1);
        $connection_charge_due = (float)($_POST['connection_charge_due'] ?? -1);

        // validate
        if ($name === '' || $mobile === '' || $zone <= 0 || $connection_date === '' || $address === '' || $ip === '' || $mb === '') {
            json_out(['ok'=>false,'msg'=>'Please fill all required fields.'], 422);
        }

        // speed normalize
        $int_mb = preg_replace('/[^.0-9]/', '', $mb);
        $str_fr_mb = strtolower(preg_replace('/[^a-zA-Z]/', '', $mb));
        if ($str_fr_mb == 'kbps' || $str_fr_mb == 'kb') $int_mb = ($int_mb / 1024);
        if ($int_mb > 1000) $int_mb = 0;

        $form_data = [
            'ip' => $ip,
            'ag_name' => $name,
            'ag_mobile_no' => $mobile,
            'ag_office_address' => str_replace("'", "", $address),
            'int_mb' => str_replace("'", "", $int_mb),
            'ag_email' => $email,
            'zone' => $zone,
            'regular_mobile' => str_replace("'", "", $regularmobile),
            'national_id' => $national_id,
            'mac_address' => str_replace("'", "", $macaddress),
            'connection_date' => date('Y-m-d', strtotime($connection_date)),
            'update_by' => $user_id,
            'bill_date' => $bill_date,
            'mb' => $mb,
            'mikrotik_disconnect' => $mikrotik_disconnect
            
        ];

        if ($connection_charge_due >= 0) {
            $form_data['connection_charge_due'] = $connection_charge_due;
            $form_data['dueadvance'] = ($agent['dueadvance'] + $connection_charge_due) - $xconnection_charge_due;
        }
        if ($previous_due >= 0) {
            $form_data['previous_due'] = $previous_due;
            $form_data['dueadvance'] = ($agent['dueadvance'] + $previous_due) - $xprevious_due;
        }

        if ($taka != $xtaka) {
            if ((int)$agent['billgenerate'] === 1) {
                $form_data['generate_amount'] = ($agent['generate_amount'] + $taka) - $xtaka;
            }
            $form_data['taka'] = $taka;
        }

        $mikrotik_id = isset($agent['mikrotik_id']) ? (int)$agent['mikrotik_id'] : 0;
        if ($mikrotik_id > 0) {

            $oldIp = trim($agent['ip'] ?? '');
            $newIp = trim($ip ?? '');

            if ($oldIp !== '' && $newIp !== '' && $oldIp !== $newIp) {

                $mk = $obj->rawSqlSingle(
                    "SELECT * 
                    FROM re_mikrotik_user 
                    WHERE status = 1 AND id = $mikrotik_id"
                );

                if (!$mk) return;

                $mikrotik = new Mikrotik(
                    $mk['mik_ip'],
                    $mk['mik_port'],
                    $mk['mik_username'],
                    $mk['mik_password']
                );

                if ($mikrotik->connected) {
                    $obj->updateResellerExistingSecret(
                        $mikrotik_id,
                        $newIp,
                        $password,
                        $mb,
                        $oldIp,
                        'Ip change'
                    ); 
                }
            }
        }

        $mikrotikConnect = false;
        $mikrotikId = (int)($agent['mikrotik_id'] ?? 0);
        $mk = null;
        $mkObj = null;

        if ($mikrotikId > 0 && $obj->tableExists('re_mikrotik_user')) {
            $mk = $obj->getSingleData("re_mikrotik_user", ['where' => ['id', '=', $mikrotikId]]);
            if (!empty($mk['mik_ip']) && !empty($mk['mik_port']) && !empty($mk['mik_username']) && !empty($mk['mik_password'])) {
                $mkObj = new Mikrotik($mk['mik_ip'], $mk['mik_port'], $mk['mik_username'], $mk['mik_password']);
                $mikrotikConnect = !empty($mkObj->connected);
            }
        }
        


        if ($re_taka != $xre_taka) $form_data['re_taka'] = $re_taka;
        if ($status != $status_check) $form_data['ag_status'] = $status;

        // upload
        if (isset($_FILES["image"]) && $_FILES["image"]["error"] == 0) {
            $uploadDir = "asset/uploads/";
            $base = realpath(dirname(__DIR__, 2));
            $desiredPath = $base . '/' . $uploadDir;
            if (!is_dir($desiredPath)) @mkdir($desiredPath, 0777, true);

            $fileName = $_FILES["image"]["name"];
            $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
            $allowed = ['jpg', 'jpeg', 'png', 'webp'];

            if (in_array($ext, $allowed)) {
                $uniqueName = time().uniqid().".".$ext;
                $forDatabase = $uploadDir.$uniqueName;
                $filePath = $desiredPath.$uniqueName;
                if (move_uploaded_file($_FILES["image"]["tmp_name"], $filePath)) {
                    $form_data['id_photo'] = $forDatabase;
                }
            }
        }

        // DB UPDATE (FAST)
        $customer = $obj->Update_data("re_tbl_agent", $form_data, "ag_id=$token");

        
        if ($mikrotikConnect) {

            $updateData['queue_password'] = $password;

            $obj->updateResellerExistingSecret($mikrotikId, $ip, $password, $mb, $agent['ip'], $remarks);

            $obj->updateResellerSecretPassword($mikrotikId, $agent['ip'], $password);
            
            $obj->updateExistingResellerSecretProfile($mikrotikId, $ip, $mb);
        
        }


     
        if (isset($customer) && $status !== null) {

            if ($status == 1) {
                $obj->reEnableSingleSecret($agent['mikrotik_id'], $agent['ip']);
            } elseif ($status == 0) {
                 $obj->reDisableSingleSecret($agent['mikrotik_id'], $agent['ip']);
        
            } else {
                json_out([
                    'ok' => false,
                    'msg' => 'Invalid status value'
                ]);
            }
        
        } else {
            json_out([
                'ok' => false,
                'msg' => 'Under try catch Invalid action'
            ]);
        }


        
        
        // response immediately (no Mikrotik here)
        $url = '?page=reseller-customer-list&id='.$id;
        json_out([
            'ok'=>true,
            'msg'=>'Customer successfull (mikrotik sync..)',
            'redirect'=>$url
        ]);

    } catch(Throwable $e){
        json_out(['ok'=>false,'msg'=>'Save error: '.$e->getMessage()], 500);
    }
}


json_out(['ok'=>false,'msg'=>'Invalid action'], 400);
