<?php
session_start();

header('Content-Type: application/json; charset=utf-8');
error_reporting(E_ALL);
ini_set('display_errors', 1);

$path = realpath(dirname(__DIR__, 3) . '/services/Model.php');
if (!$path) {
    echo json_encode([
        'status' => 'error',
        'message' => 'Model.php not found',
        'debug' => dirname(__DIR__, 3) . '/services/Model.php'
    ]);
    exit;
}
require_once $path;

date_default_timezone_set('Asia/Dhaka');
$date_time = date('Y-m-d g:i:sA');
$date = date('Y-m-d');

$obj = new Model();

/** helper JSON responder */
function json_out($status, $message, $extra = [])
{
    echo json_encode(array_merge([
        'status'  => $status,
        'message' => $message
    ], $extra));
    exit;
}

$user_id = (int)($_SESSION['userid'] ?? 0);
if ($user_id <= 0) {
    json_out('error', 'Session expired. Please login again.');
}

$token        = (int)($_POST['customer_id'] ?? 0);
$dayDifference = (int)($_POST['customer_rdate'] ?? 0);
$agentName    = trim($_POST['name'] ?? '');
$agentIp      = trim($_POST['ip'] ?? '');

if ($token <= 0 || $dayDifference <= 0) {
    json_out('error', 'Invalid customer or days.');
}

try {

    // customer data
    $data = $obj->details_by_cond('re_tbl_agent', "ag_id='$token'");
    if (!$data) {
        json_out('error', 'Customer not found.');
    }

    // bill calc
    $billamount     = round(((float)$data['taka'] / 30) * $dayDifference);
    $rechargeamount = round(((float)$data['re_taka'] / 30) * $dayDifference);

    // reseller data
    $resellerSingle = $obj->details_by_cond('_reseller_createuser', "UserId='$user_id'");
    if (!$resellerSingle) {
        json_out('error', 'Reseller info not found.');
    }

    $avBal = (float)($resellerSingle['balance'] ?? 0);

    if ($avBal < $rechargeamount) {
        json_out('error', 'Sorry, you have insufficient balance!', [
            'available_balance' => $avBal,
            'required_balance'  => $rechargeamount
        ]);
    }

    // Calculate disconnect baseline date
    $dateDifference = (strtotime(date('Y-m-d')) - strtotime($data['mikrotik_disconnect'])) / (60 * 60 * 24);
    $disDate = ($dateDifference > (float)$resellerSingle['freeday']) ? date('Y-m-d') : $data['mikrotik_disconnect'];

    // prepare update agent
    $form_data_re_tbl_agent = [];
    $form_data_re_tbl_agent['paid_amount']     = (float)$data['paid_amount'];
    $form_data_re_tbl_agent['dueadvance']      = (float)$data['dueadvance'];
    $form_data_re_tbl_agent['generate_amount'] = (float)$data['generate_amount'];

    if ((int)$data['billgenerate'] == 0) {
        $form_data_re_tbl_agent['billgenerate'] = 1;
        $form_data_re_tbl_agent['dueadvance'] += $billamount;
        $form_data_re_tbl_agent['generate_amount'] += $billamount;
    }

    $newdisconnect = $data['mikrotik_disconnect'];

    if (($rechargeamount > 0) && ($billamount > 0) && ($dayDifference > 0)) {

        $newdisconnect = date('Y-m-d', strtotime($disDate . " +$dayDifference days"));
        $form_data_re_tbl_agent['mikrotik_disconnect'] = $newdisconnect;

        $form_data_re_tbl_agent['paid_amount'] += $billamount;
        $form_data_re_tbl_agent['dueadvance']  -= $billamount;
        $form_data_re_tbl_agent['ag_status']    = 1;

        // Balance update
        $obj->Update_data('_reseller_createuser', [
            'balance' => ($avBal - $rechargeamount)
        ], "UserId='$user_id'");

        $obj->Update_data('re_tbl_agent', [
            'balance' => ((float)$data['balance'] + $rechargeamount)
        ], "ag_id='$token'");

        // account entries
        $agent = $obj->raw_sql("SELECT * FROM re_tbl_agent WHERE ag_id='$token'");
        $agent = $agent[0] ?? $data;

        $lastresacc = $obj->Insert_data("re_tbl_reseller_account", [
            'reseller_id' => $user_id,
            'agent_id'    => $token,
            'amount'      => $rechargeamount,
            'type'        => 5,
            'description' => "Balance recharge for $dayDifference days disconnect date $newdisconnect ($agentName / $agentIp)",
            'entry_by'    => $user_id,
            'entry_date'  => $date
        ]);

        $obj->Insert_data("re_tbl_account", [
            'agent_id'            => $token,
            'cus_id'              => $data['cus_id'],
            'acc_amount'          => $billamount,
            'acc_type'            => '3',
            'acc_description'     => "Bill collection at $date_time",
            'entry_by'            => $user_id,
            'entry_date'          => $date,
            'update_by'           => $user_id,
            'reseller_id'         => $user_id,
            'reseller_account_id' => $lastresacc
        ]);
    }

    // final statuses
    $form_data_re_tbl_agent['bill_status']    = 1;
    $form_data_re_tbl_agent['pay_status']     = 0;
    $form_data_re_tbl_agent['payment_status'] = 1;

    // activity log
    $result = $obj->resellerHistoryLog([
        're_id'        => $user_id,
        'header'       => 'Partials Recharge',
        'descriptions' => 'Bill Collection Name: "'.$data['ag_name'].'" And Cus ID: "'.$data['cus_id'].'" Collected. Amount: '.$billamount.'.',
        'type'         => 'insert',
        'ag_id'        => $token,
    ]);


    $obj->Update_data("re_tbl_agent", $form_data_re_tbl_agent, "ag_id=$token");

    // enable Secret (mikrotik)
    if ($obj->tableExists('re_mikrotik_user')) {
        $mikrotikLoginData = $obj->details_by_cond('re_mikrotik_user', "user_id ='$user_id' OR id=" . (int)$data['mikrotik_id']);
        if (!empty($mikrotikLoginData['mik_ip'])) {
            $mikrotik = new Mikrotik(
                $mikrotikLoginData['mik_ip'],
                $mikrotikLoginData['mik_port'],
                $mikrotikLoginData['mik_username'],
                $mikrotikLoginData['mik_password']
            );

            if (!empty($mikrotik->connected)) {
                $obj->reEnableSingleSecret($data['mikrotik_id'], $data['ip']);
            }
        }
    }

    // SMS
    $smsPhone = "88" . strval($data['ag_mobile_no'] ?? '');
    $var_replacement = [
        '{CUSTOMER_NAME}' => $data['ag_name'] ?? '',
        '{PACKAGE_NAME}' => $data['mb'] ?? '',
        '{MONTHLY_BILL}' => $data['taka'] ?? '',
        '{CUSTOMER_ID}' => $data['cus_id'] ?? '',
        '{IP_ADDRESS}' => $data['ip'] ?? '',
        '{PAID_AMOUNT}' => $data['taka'] ?? '',
        '{DUE_AMOUNT}' => $data['dueadvance'] ?? ''
    ];
    $newCustomerSmsInfo = $obj->rawSqlSingle("SELECT * FROM re_tbl_sms  WHERE reseller_id='$data[entry_by]' AND status=5  AND smshead='active'");
    if ($newCustomerSmsInfo && isset($newCustomerSmsInfo['smsbody'])) {
        $smsBodyTpl = $newCustomerSmsInfo['smsbody'] ?? '';
        $smsBody = strtr($smsBodyTpl, $var_replacement);

        if (!empty($smsBody) && !empty($smsPhone)) {
            try {
                $result = $obj->reSendsms($smsPhone, $smsBody, $data['entry_by']);
            } catch (\Throwable $th) {
                echo $th;
            }
        }
    }


    //  JSON success response
    json_out('success', 'Partial recharge successful!', [
        'customer_id'      => $token,
        'days'             => $dayDifference,
        'bill_amount'      => $billamount,
        'reseller_charge'  => $rechargeamount,
        'new_disconnect'   => $newdisconnect,
        'new_balance'      => ($avBal - $rechargeamount)
    ]);
} catch (Throwable $e) {
    json_out('error', 'Server error: ' . $e->getMessage(), [
        'file' => $e->getFile(),
        'line' => $e->getLine()
    ]);
}
