<?php
include("config.php");

// Open php://input as a file resource
$handle = fopen('php://input', 'r');
$json = '';

if ($handle) {
    while (!feof($handle)) {
        $json .= fread($handle, 8192);
    }
    fclose($handle);
}

// Decode the JSON data
$data = json_decode($json, true);

// Extract values safely
$sessionID = $data['sessionID'] ?? null;
$userID = $data['userID'] ?? null;
$newSession = $data['newSession'] ?? null;
$msisdn = $data['msisdn'] ?? null;
$userData = $data['userData'] ?? null;
$network = $data['network'] ?? null;

// Check if user exists in the database
$sql = "SELECT fname, lname FROM users WHERE phone = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $msisdn);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();

if ($user) {
    $fName = $user['fname'];
    $lName = $user['lname'];
    $userName = strtoupper("$fName $lName");
} else {
    // Prompt guest users to register
    $userName = "Guest";
}

// Session tracking
$sessionFile = "sessions/$sessionID.json";
if (!file_exists("sessions")) {
    mkdir("sessions", 0777, true);
}

if ($newSession || !file_exists($sessionFile)) {
    $sessionData = ["step" => 1];
} else {
    $sessionData = json_decode(file_get_contents($sessionFile), true);
}

$step = $sessionData['step'];

if ($step == 1 && $userData == "*928*335#") {
    // Main Menu
    if ($userName == "Guest") {
        $message = "Welcome! Please register first:\n";
        $message .= "1. Register\n";
        $message .= "2. Exit";
        $sessionData['step'] = 99;
    } else {
        $message = "Welcome $userName, to Pay Now Gh\n";
        $message .= "1. Property Rates\n";
        $message .= "2. Pay";
        $sessionData['step'] = 2;
    }
    $continueSession = true;
}

// Guest Registration Step 99
elseif ($step == 99 && $userData == "1") {
    $message = "Enter your first name:";
    $sessionData['step'] = 100;
    $continueSession = true;
} elseif ($step == 100) {
    $sessionData['fname'] = $userData;
    $message = "Enter your last name:";
    $sessionData['step'] = 101;
    $continueSession = true;
} elseif ($step == 101) {
    $sessionData['lname'] = $userData;
    $message = "Confirm Registration:\n";
    $message .= "1. Confirm\n";
    $message .= "2. Cancel";
    $sessionData['step'] = 102;
    $continueSession = true;
} elseif ($step == 102) {
    if ($userData == "1") {
        $sql = "INSERT INTO users (fname, lname, phone) VALUES (?, ?, ?)";
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("sss", $sessionData['fname'], $sessionData['lname'], $msisdn);
        if ($stmt->execute()) {
            $message = "Registration successful! Please restart USSD.";
        } else {
            $message = "Registration failed. Try again.";
        }
        $continueSession = false;
    } else {
        $message = "Registration cancelled.";
        $continueSession = false;
    }
}

// Property Rates Menu
elseif ($step == 2 && $userData == "1") {
    $message = "Select an option:\n";
    $message .= "1. Add Property\n";
    $message .= "2. View Property\n";
    $message .= "3. Last Payment";
    $sessionData['step'] = 3;
    $continueSession = true;
}

// Add Property Flow
elseif ($step == 3 && $userData == "1") {
    $message = "Enter the name of your property:";
    $sessionData['step'] = 4;
    $continueSession = true;
} elseif ($step == 4) {
    $sessionData['property_name'] = $userData;
    $message = "Enter the property GPS location:";
    $sessionData['step'] = 5;
    $continueSession = true;
} elseif ($step == 5) {
    $sessionData['property_id'] = $userData;
    // Check if property exists
    $queryCheck = "SELECT propRefID FROM property WHERE property_name = ? AND gps = ? AND phone = ?";
    $stmtCheck = $conn->prepare($queryCheck);
    $stmtCheck->bind_param("sss", $sessionData['property_name'], $sessionData['property_id'], $msisdn);
    $stmtCheck->execute();
    $resultCheck = $stmtCheck->get_result();

    if ($resultCheck->num_rows > 0) {
        $message = "This property is already registered.";
        $continueSession = false;
    } else {
        $message = "Select the type of building:\n";
        $message .= "1. Apartment\n";
        $message .= "2. Bungalow\n";
        $message .= "3. Office\n";
        $message .= "4. Shop";
        $sessionData['step'] = 6;
        $continueSession = true;
    }
}

// View Property
elseif ($step == 3 && $userData == "2") {
    $sql = "SELECT propRefID, property_name FROM property WHERE phone = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s", $msisdn);
    $stmt->execute();
    $result = $stmt->get_result();

    if ($result->num_rows > 0) {
        $message = "Your registered properties:\n";
        $counter = 1;
        while ($row = $result->fetch_assoc()) {
            $message .= "$counter. {$row['property_name']} (Ref: {$row['propRefID']})\n";
            $counter++;
        }
    } else {
        $message = "No properties found.";
    }
    $continueSession = false;
}

elseif ($step == 6) {
    // Store building type and ask for number of rooms
    $buildingTypes = ["1" => "Apartment", "2" => "Bungalow", "3" => "Office", "4" => "Shop"];

    if (!isset($buildingTypes[$userData])) {
        $message = "Invalid selection. Please enter:\n";
        $message .= "1. Apartment\n2. Bungalow\n3. Office\n4. Shop";
        $continueSession = true;
    } else {
        $sessionData['building_type'] = $buildingTypes[$userData];
        $message = "Enter the number of rooms:";
        $sessionData['step'] = 7;
        $continueSession = true;
    }

} elseif ($step == 7) {
    // Store number of rooms and calculate estimated property rate
    if (!is_numeric($userData) || $userData <= 0) {
        $message = "Invalid input. Enter a valid number of rooms:";
        $continueSession = true;
    } else {
        $sessionData['num_rooms'] = (int)$userData;
        $numRooms = (int)$userData;
        
        // Example Rate Calculation (Modify as needed)
        $buildingType = $sessionData['building_type'];
        $amount = 0;
        $prateID = null;

        // Fetch property rate based on building type and number of rooms
        $query4 = "SELECT * FROM prate WHERE typeBuilding = ? AND noRooms = ?";
        $stmt = $conn->prepare($query4);
        $stmt->bind_param("si", $buildingType, $numRooms);
        $stmt->execute();
        $result = $stmt->get_result();

        if ($row = $result->fetch_assoc()) {
            $amount = $row["amount"];
            $prateID = $row["prateID"];
        }

        // Generate unique property ID
        $transdate = date("Y-m-d");
        $str_result = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
        $trandate1 = date("Ymd");
        $token = substr(str_shuffle($str_result), 0, 6);
        $prid = "GA-$token$trandate1";
        $date_create = date("Y-m-d H:i:s");
        $usertype="ind";

        // Insert property into database
        $sql = "INSERT INTO property (fullname, phone, property_name, gps, propRefID, prateID, userID, type_house, no_rooms, date_created) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("ssssssssss", $userName, $msisdn, $sessionData['property_name'], $sessionData['property_id'], $prid, $prateID, $usertype, $buildingType, $numRooms, $date_create);

        if ($stmt->execute()) {
            $message = "Property RefID:  $prid has been added successfully!\n";
            // $message .= "Estimated Property Rate: GH₵" . number_format($amount, 2);
        } else {
            $message = "Failed to add property. Please try again.";
        }

        // Reset session step
        $sessionData['step'] = 1;
        $continueSession = false;
    }
}

// Last Payment
elseif ($step == 3 && $userData == "3") {
    $sql = "SELECT t.propRefID, p.fullName, t.amount, t.date_created 
            FROM transactions t
            JOIN property p ON t.propRefID = p.propRefID
            WHERE t.phone = ? AND t.status_api = 'Success' 
            ORDER BY t.transID DESC 
            LIMIT 1";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s", $msisdn);
    $stmt->execute();
    $result = $stmt->get_result();
    
    if ($result->num_rows > 0) {
        $row = $result->fetch_assoc();
        $message = "Last Payment:\n";
        $message .= "Property: {$row['fullName']} (Ref: {$row['propRefID']})\n";
        $message .= "Amount: GH₵{$row['amount']}\n";
        $message .= "Date: {$row['date_created']}";
    } else {
        $message = "No payment history found.";
    }
    $continueSession = false;
}

elseif ($step == 2 && $userData == "2") {
    // Fetch user's registered properties
    $sql = "SELECT propRefID, property_name FROM property WHERE phone = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s", $msisdn);
    $stmt->execute();
    $result = $stmt->get_result();

    if ($result->num_rows > 0) {
        $message = "Select a property to pay for:\n";
        $counter = 1;
        $propertyList = [];

        while ($row = $result->fetch_assoc()) {
            $message .= "$counter. {$row['property_name']} (Ref: {$row['propRefID']})\n";
            $propertyList[$counter] = $row['propRefID']; // Store property reference
            $counter++;
        }

        // Store property list in session
        $sessionData['propertyList'] = $propertyList;
        $sessionData['step'] = 8;
        $continueSession = true;
    } else {
        $message = "No registered properties found. Please add a property first.";
        $continueSession = false;
    }
}

// Step 8: User selects property to pay for
elseif ($step == 8) {
    $propertyList = $sessionData['propertyList'] ?? [];

    if (!isset($propertyList[$userData])) {
        $message = "Invalid selection. Please try again.";
        $continueSession = true;
    } else {
        $sessionData['selectedProperty'] = $propertyList[$userData];

        // Fetch amount due for selected property
        $sql = "SELECT p.property_name, r.amount FROM property p
                JOIN prate r ON p.prateID = r.prateID
                WHERE p.propRefID = ?";
        $stmt = $conn->prepare($sql);
        $stmt->bind_param("s", $sessionData['selectedProperty']);
        $stmt->execute();
        $result = $stmt->get_result();

        if ($row = $result->fetch_assoc()) {
            $sessionData['paymentAmount'] = $row['amount'];
            $message = "Property: {$row['property_name']}\n";
            $message .= "Amount Due: GH₵" . number_format($row['amount'], 2) . "\n";
            $message .= "Confirm Payment:\n";
            $message .= "1. Confirm\n";
            $message .= "2. Cancel";
            $sessionData['step'] = 9;
            $continueSession = true;
        } else {
            $message = "Error retrieving payment details. Please try again.";
            $continueSession = false;
        }
    }
}

// Step 9: Confirm Payment
elseif ($step == 9) {
    if ($userData == "1") {
        $propRefID = $sessionData['selectedProperty'];
        $amount = $sessionData['paymentAmount'];
        $transactionID = "TXN" . time(); // Unique transaction ID
        $date_created = date("Y-m-d H:i:s");
        
        // Payment Calculations
        $paynow = 5;
        $user = 30;
        $GRArevenue = $amount - (($amount * $paynow) / 100);
        $paynowAmnt = $amount - $GRArevenue;
        $userCom = ($paynowAmnt * $user) / 100;
        $paynowCom = $paynowAmnt - $userCom;
        $userID = "ind";

        // Prepare SQL Statement
        $sql = "INSERT INTO transactions (telco, fullName, paynowCom, userCom, userID, phone, propRefID, amount, token, status_api, date_created) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'Pending', ?)";
        
        $stmt = $conn->prepare($sql);
        if (!$stmt) {
            die("Error preparing statement: " . $conn->error);
        }

        $stmt->bind_param("sssssssdss", $network, $userName, $paynowCom, $userCom, $userID, $msisdn, $propRefID, $amount, $transactionID, $date_created);
        $stmt->execute();
        $stmt->close();

        // Hubtel API Payment Request
        $email = "info@paynowgh.com";
        $channelMap = [
            "MTN" => "mtn-gh",
            "Telecel" => "vodafone-gh",
            "Airteltigo" => "tigo-gh"
        ];
        $channel = $channelMap[$network] ?? "";
        
        $payload = json_encode([
            "CustomerName" => $userName,
            "CustomerMsisdn" => $msisdn,
            "CustomerEmail" => $email,
            "Channel" => $channel,
            "Amount" => 0.1,
            "PrimaryCallbackUrl" => "https://mobilemoneycad.net/paynow/callback_paynow.php",
            "Description" => "Deposit",
            "ClientReference" => $transactionID
        ]);
        
        $auth = base64_encode("qQ8My7G:4daa91de2db94928824c19392030ca63");
        $ch = curl_init("https://rmp.hubtel.com/merchantaccount/merchants/2017419/receive/mobilemoney/");
        curl_setopt_array($ch, [
            CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
            CURLOPT_HTTPHEADER => ["Accept:application/json", "Content-Type:application/json", "Authorization:Basic $auth", "Cache-Control:no-cache"],
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false
        ]);
        $content = curl_exec($ch);
        curl_close($ch);
        
        // Log API Response
        $query = "INSERT INTO api_logs (response, token, date_created) VALUES (?, ?, ?)";
        $stmt = $conn->prepare($query);
        $stmt->bind_param("sss", $content, $transactionID, $date_created);
        $stmt->execute();
        $stmt->close();

        // **✅ Implement Waiting Loop for Hubtel Response**
        // $max_wait_time = 60; // Max wait time in seconds
        // $poll_interval = 5; // Time between checks
        // $time_elapsed = 0;
        // $paymentConfirmed = false;

        // while ($time_elapsed < $max_wait_time) {
            // **Check Payment Status from DB**
            $query9 = "SELECT response FROM api_logs WHERE token = ?";
            $stmt = $conn->prepare($query9);
            $stmt->bind_param("s", $transactionID);
            $stmt->execute();
            $stmt->bind_result($response_api);
            $stmt->fetch();
            $stmt->close();

            // **Handle API Response Safely**
            // if (!empty($response_api)) {
            //     $jsonDecode = json_decode($response_api, true);
            //     if ($jsonDecode) {
            //         $responseCode = $jsonDecode['ResponseCode'] ?? null;
            //         $status = $jsonDecode['Data']['status'] ?? null;

            //         if ($responseCode == "0000" && $status == "Paid") {
            //             // **Payment Successful**
            //             $updateQuery = "UPDATE transactions SET momo_api='Success', status_api='Success', date_time_paid=NOW() WHERE token=?";
            //             $statusMessage = "Payment successful!";
            //             $paymentConfirmed = true;
            //             // break;
            //         }
            //     }
            // }

            // **Wait before checking again**
        //     sleep($poll_interval);
        //     $time_elapsed += $poll_interval;
        // }

        // **If Payment Not Confirmed After Loop, Mark as Unpaid**
        // if (!$paymentConfirmed) {
        //     $updateQuery = "UPDATE transactions SET momo_api='Unpaid', status_api='Failed', date_time_paid=NOW() WHERE token=?";
        //     $statusMessage = "Payment failed. Please try again.";
        // }

        // $stmt = $conn->prepare($updateQuery);
        // $stmt->bind_param("s", $transactionID);
        // $stmt->execute();
        // $stmt->close();

        // **✅ Send SMS Notification**
        $text = "Hello $userName,\nYour property RefID: $propRefID has been paid for.\nPayment Ref: $transactionID\nThank you for choosing PayNow GH!";
        
        $smsPayload = json_encode([
            "From" => "CAD",
            "To" => $msisdn,
            "Content" => $text
        ]);
        
        $smsAuth = base64_encode("ityrcnbz:kzgcubkj");
        $smsCh = curl_init("https://sms.hubtel.com/v1/messages/send");
        curl_setopt_array($smsCh, [
            CURLOPT_HTTPHEADER => ["Authorization: Basic $smsAuth", "Content-Type: application/json"],
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $smsPayload,
            CURLOPT_RETURNTRANSFER => true
        ]);
        // curl_exec($smsCh);
        curl_close($smsCh);

        $message = $statusMessage;
        $sessionData['step'] = 1;
        $continueSession = false;
    } elseif ($userData == "2") {
        $message = "Payment cancelled.";
        $sessionData['step'] = 1;
        $continueSession = false;
    } else {
        $message = "Invalid input. Press 1 to confirm or 2 to cancel.";
        $continueSession = true;
    }
}


// Save session
file_put_contents($sessionFile, json_encode($sessionData));

// Close connection
$conn->close();

// USSD Response
$response = [
    "sessionID" => $sessionID,
    "userID" => $userID,
    "msisdn" => $msisdn,
    "message" => $message,
    "continueSession" => $continueSession
];

http_response_code(200);
header('Content-Type: application/json');
echo json_encode($response);
