<?php
header('Content-Type: application/json; charset=utf-8');
require_once '../includes/db.php';
require_once '../includes/auth_middleware.php';

$action = isset($_GET['action']) ? $_GET['action'] : '';
$pageKey = 'safes';

// Enforce granular RBAC for safes API
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    if ($action === 'list') {
        checkApiPagePermission($pageKey, 'view');
    }
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $input = json_decode(file_get_contents('php://input'), true) ?? [];
    if ($action === 'save_safe') {
        $id = trim($input['id'] ?? '');
        if (!empty($id)) {
            checkApiPagePermission($pageKey, 'edit');
        } else {
            checkApiPagePermission($pageKey, 'add');
        }
    } elseif ($action === 'delete_safe') {
        checkApiPagePermission($pageKey, 'delete');
    } elseif ($action === 'save_tx') {
        $tx_id = trim($input['id'] ?? '');
        if (!empty($tx_id)) {
            checkApiPagePermission($pageKey, 'edit');
        } else {
            checkApiPagePermission($pageKey, 'add');
        }
    } elseif ($action === 'delete_transaction') {
        checkApiPagePermission($pageKey, 'delete');
    } elseif ($action === 'reset_safe') {
        checkApiPagePermission($pageKey, 'edit');
    }
}

if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    if ($action === 'list') {
        // Fetch all safes
        $safes_res = $conn->query("SELECT * FROM safes ORDER BY type ASC, id ASC");
        $safes = [];
        while ($row = $safes_res->fetch_assoc()) {
            $safes[] = [
                "id" => $row['id'],
                "name" => $row['name'],
                "type" => $row['type']
            ];
        }

        // Fetch all transactions
        $whereClause = "";
        if (!canViewOthersData()) {
            $myId = (int)$_SESSION['user']['id'];
            $whereClause = " WHERE user_id = $myId ";
        }
        $tx_res = $conn->query("SELECT * FROM safe_transactions $whereClause ORDER BY date DESC, id DESC");
        $transactions = [];
        while ($row = $tx_res->fetch_assoc()) {
            $transactions[] = [
                "id" => $row['id'],
                "safeId" => $row['safe_id'],
                "description" => $row['description'],
                "type" => $row['type'],
                "date" => $row['date'],
                "createdAt" => $row['created_at'],
                "amount" => floatval($row['amount']),
                "debtorId" => $row['debtor_id'],
                "formId" => $row['form_id']
            ];
        }

        echo json_encode([
            "status" => "success",
            "safes" => $safes,
            "transactions" => $transactions
        ]);
        exit;
    }
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $input = json_decode(file_get_contents('php://input'), true);

    if ($action === 'save_safe') {
        $id = isset($input['id']) ? trim($input['id']) : '';
        $name = isset($input['name']) ? trim($input['name']) : '';
        $type = isset($input['type']) ? trim($input['type']) : '';

        if (empty($name) || empty($type)) {
            echo json_encode(["status" => "error", "message" => "يرجى ملء جميع الحقول المطلوبة"]);
            exit;
        }

        if (!empty($id)) {
            // Update
            $old_res = $conn->query("SELECT * FROM safes WHERE id = " . intval($id));
            $old_safe = $old_res ? $old_res->fetch_assoc() : null;

            // If the user tries to rename ID 1 (main safe) to something else or modify it, we let them modify name but block deletion
            $stmt = $conn->prepare("UPDATE safes SET name = ?, type = ? WHERE id = ?");
            $stmt->bind_param("ssi", $name, $type, $id);
            if ($stmt->execute()) {
                $new_res = $conn->query("SELECT * FROM safes WHERE id = " . intval($id));
                $new_safe = $new_res ? $new_res->fetch_assoc() : null;
                logActivity($conn, 'update', 'safes', $id, $old_safe, $new_safe);
                updateSystemState($conn, 'safes');
                echo json_encode(["status" => "success", "message" => "تم تحديث بيانات الصندوق بنجاح"]);
            } else {
                echo json_encode(["status" => "error", "message" => "فشل تحديث البيانات"]);
            }
            $stmt->close();
        } else {
            // Insert
            $stmt = $conn->prepare("INSERT INTO safes (name, type) VALUES (?, ?)");
            $stmt->bind_param("ss", $name, $type);
            if ($stmt->execute()) {
                $new_id = $conn->insert_id;
                $new_res = $conn->query("SELECT * FROM safes WHERE id = " . intval($new_id));
                $new_safe = $new_res ? $new_res->fetch_assoc() : null;
                logActivity($conn, 'insert', 'safes', $new_id, null, $new_safe);
                updateSystemState($conn, 'safes');
                echo json_encode(["status" => "success", "message" => "تم إضافة الصندوق بنجاح"]);
            } else {
                echo json_encode(["status" => "error", "message" => "فشل إضافة الصندوق"]);
            }
            $stmt->close();
        }
        exit;
    }

    if ($action === 'delete_safe') {
        $id = isset($input['id']) ? trim($input['id']) : '';
        if (empty($id)) {
            echo json_encode(["status" => "error", "message" => "معرف الصندوق غير صحيح"]);
            exit;
        }

        // --- PROTECT MAIN SAFE ---
        // Block delete if ID is 1 (the seeded main safe) or the safe name contains "الرئيسية" or "المركزية"
        $check_stmt = $conn->prepare("SELECT name FROM safes WHERE id = ?");
        $check_stmt->bind_param("i", $id);
        $check_stmt->execute();
        $check_res = $check_stmt->get_result();
        if ($row = $check_res->fetch_assoc()) {
            $name = $row['name'];
            if ($id == 1 || mb_strpos($name, 'الرئيسية') !== false || mb_strpos($name, 'المركزية') !== false) {
                echo json_encode(["status" => "error", "message" => "عذراً، لا يمكن حذف الخزنة الرئيسية بتاتاً لحماية الحسابات المالية!"]);
                $check_stmt->close();
                exit;
            }
        }
        $check_stmt->close();
        // -------------------------

        $old_res = $conn->query("SELECT * FROM safes WHERE id = " . intval($id));
        $old_safe = $old_res ? $old_res->fetch_assoc() : null;

        $stmt = $conn->prepare("DELETE FROM safes WHERE id = ?");
        $stmt->bind_param("i", $id);
        if ($stmt->execute()) {
            logActivity($conn, 'delete', 'safes', $id, $old_safe, null);
            updateSystemState($conn, 'safes');
            updateSystemState($conn, 'safe_transactions'); // cascading transactions deleted
            echo json_encode(["status" => "success", "message" => "تم حذف الصندوق وكافة العمليات المرتبطة به بنجاح"]);
        } else {
            echo json_encode(["status" => "error", "message" => "فشل حذف الصندوق"]);
        }
        $stmt->close();
        exit;
    }

    if ($action === 'save_tx') {
        $safe_id = isset($input['safeId']) ? trim($input['safeId']) : '';
        $description = isset($input['description']) ? trim($input['description']) : '';
        $type = isset($input['type']) ? trim($input['type']) : '';
        $date = isset($input['date']) ? trim($input['date']) : '';
        $amount = isset($input['amount']) ? floatval($input['amount']) : 0;
        $debtor_id = isset($input['debtorId']) && !empty($input['debtorId']) ? trim($input['debtorId']) : null;
        $form_id = isset($input['formId']) && !empty($input['formId']) ? trim($input['formId']) : null;

        if (empty($safe_id) || empty($description) || empty($type) || empty($date) || $amount <= 0) {
            echo json_encode(["status" => "error", "message" => "يرجى ملء جميع الحقول بقيم صحيحة"]);
            exit;
        }

        // --- OVERDRAFT PREVENTION GUARD ---
        if ($type === 'withdrawal') {
            $stmt_bal = $conn->prepare("
                SELECT COALESCE(
                    SUM(
                        CASE 
                            WHEN type = 'deposit' THEN amount 
                            WHEN type = 'withdrawal' THEN -amount 
                            ELSE 0 
                        END
                    ), 0) AS balance
                FROM safe_transactions
                WHERE safe_id = ?
            ");
            $stmt_bal->bind_param("i", $safe_id);
            $stmt_bal->execute();
            $current_bal = (float)($stmt_bal->get_result()->fetch_assoc()['balance'] ?? 0);
            $stmt_bal->close();

            if ($amount > $current_bal + 0.001) {
                echo json_encode([
                    "status" => "error", 
                    "message" => "عذراً، الرصيد المالي المتاح في الصندوق (" . number_format($current_bal, 0) . " د.ع) غير كافٍ لإكمال عملية السحب بقيمة (" . number_format($amount, 0) . " د.ع)!"
                ]);
                exit;
            }
        }
        // ----------------------------------

        if ($debtor_id && strpos($debtor_id, 'name_') === 0) {
            $name = base64_decode(substr($debtor_id, 5));
            
            // Check if there is an existing debtor with this name
            $stmt = $conn->prepare("SELECT id FROM debtors WHERE TRIM(LOWER(name)) = TRIM(LOWER(?)) LIMIT 1");
            $stmt->bind_param('s', $name);
            $stmt->execute();
            $deb_row = $stmt->get_result()->fetch_assoc();
            $stmt->close();
            
            if ($deb_row) {
                $debtor_id = (string)$deb_row['id'];
            } else {
                // Fetch phone from customers
                $phone = '';
                $stmt = $conn->prepare("SELECT phone FROM customers WHERE TRIM(LOWER(name)) = TRIM(LOWER(?)) LIMIT 1");
                $stmt->bind_param('s', $name);
                $stmt->execute();
                $c_row = $stmt->get_result()->fetch_assoc();
                $stmt->close();
                if ($c_row && !empty($c_row['phone'])) {
                    $phone = $c_row['phone'];
                } else {
                    $phone = 'من سجل الفواتير';
                }
                
                // Create new debtor
                $stmt = $conn->prepare("INSERT INTO debtors (name, phone, user_id) VALUES (?, ?, ?)");
                $stmt->bind_param('ssi', $name, $phone, $_SESSION['user']['id']);
                $stmt->execute();
                $debtor_id = (string)$conn->insert_id;
                $stmt->close();
            }
        }

        $stmt = $conn->prepare("INSERT INTO safe_transactions (safe_id, description, type, date, amount, debtor_id, form_id, user_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
        $stmt->bind_param("isssdssi", $safe_id, $description, $type, $date, $amount, $debtor_id, $form_id, $_SESSION['user']['id']);
        if ($stmt->execute()) {
            $new_id = $conn->insert_id;
            $new_res = $conn->query("SELECT * FROM safe_transactions WHERE id = " . intval($new_id));
            $new_tx = $new_res ? $new_res->fetch_assoc() : null;
            logActivity($conn, 'insert', 'safe_transactions', $new_id, null, $new_tx);
            updateSystemState($conn, 'safe_transactions');
            if ($form_id) updateSystemState($conn, 'forms');
            echo json_encode(["status" => "success", "message" => "تم تسجيل الحركة المالية بنجاح"]);
        } else {
            echo json_encode(["status" => "error", "message" => "فشل تسجيل الحركة المالية"]);
        }
        $stmt->close();
        exit;
    }

    if ($action === 'reset_safe') {
        $safe_id = isset($input['safeId']) ? intval($input['safeId']) : 0;
        $receiver_name = isset($input['receiverName']) ? trim($input['receiverName']) : '';

        if (empty($safe_id) || empty($receiver_name)) {
            echo json_encode(["status" => "error", "message" => "يرجى ملء جميع الحقول المطلوبة"]);
            exit;
        }

        // Calculate safe balance
        $stmt_bal = $conn->prepare("
            SELECT COALESCE(
                SUM(
                    CASE 
                        WHEN type = 'deposit' THEN amount 
                        WHEN type = 'withdrawal' THEN -amount 
                        ELSE 0 
                    END
                ), 0) AS balance
            FROM safe_transactions
            WHERE safe_id = ?
        ");
        $stmt_bal->bind_param("i", $safe_id);
        $stmt_bal->execute();
        $res_bal = $stmt_bal->get_result()->fetch_assoc();
        $balance = (float)($res_bal['balance'] ?? 0);
        $stmt_bal->close();

        if ($balance <= 0.01) {
            echo json_encode(["status" => "error", "message" => "رصيد الصندوق مساوٍ للصفر بالفعل أو سالب، لا يمكن تصفيره"]);
            exit;
        }

        // Insert reset transaction as a withdrawal
        $description = "تصفير القاصة وتسليم النقدية إلى: " . $receiver_name;
        $type = 'withdrawal';
        $date = date('Y-m-d');
        $debtor_id = null;
        $form_id = null;
        $user_id = isset($_SESSION['user']['id']) ? intval($_SESSION['user']['id']) : null;

        $stmt = $conn->prepare("INSERT INTO safe_transactions (safe_id, description, type, date, amount, debtor_id, form_id, user_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
        $stmt->bind_param("isssdssi", $safe_id, $description, $type, $date, $balance, $debtor_id, $form_id, $user_id);
        if ($stmt->execute()) {
            $new_id = $conn->insert_id;
            $new_res = $conn->query("SELECT * FROM safe_transactions WHERE id = " . intval($new_id));
            $new_tx = $new_res ? $new_res->fetch_assoc() : null;
            logActivity($conn, 'insert', 'safe_transactions', $new_id, null, $new_tx);
            updateSystemState($conn, 'safe_transactions');
            echo json_encode([
                "status" => "success",
                "message" => "تم تصفير القاصة بنجاح وتسجيل حركة تسليم الأموال",
                "tx_id" => (string)$new_id,
                "amount" => $balance,
                "receiverName" => $receiver_name
            ]);
        } else {
            echo json_encode(["status" => "error", "message" => "فشل تصفير القاصة وتسجيل الحركة المالية"]);
        }
        $stmt->close();
        exit;
    }
}

echo json_encode(["status" => "error", "message" => "طلب غير صالح"]);
?>
