<?php
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Methods: POST, OPTIONS');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    exit;
}

$DB_HOST = 'localhost';
$DB_NAME = 'pnartli1_doorkar';
$DB_USER = 'pnartli1_doorkar';
$DB_PASS = 'V[B5S(1gO,OIqPvz';

function respond($success, $data = [], $message = '') {
    echo json_encode(
        array_merge([
            'success' => $success,
            'message' => $message,
        ], $data),
        JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
    );
    exit;
}

function input_json() {
    $raw = file_get_contents('php://input');
    $json = json_decode($raw, true);
    return is_array($json) ? $json : $_POST;
}

function pm_log($title, $data = []) {
    @file_put_contents(
        __DIR__ . '/project_management_debug.log',
        '[' . date('Y-m-d H:i:s') . '] ' . $title . ' ' . json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL,
        FILE_APPEND
    );
}

function table_exists(PDO $pdo, $table) {
    try {
        $stmt = $pdo->prepare('SHOW TABLES LIKE ?');
        $stmt->execute([$table]);
        return $stmt->fetchColumn() !== false;
    } catch (Throwable $e) {
        return false;
    }
}

function column_exists(PDO $pdo, $table, $column) {
    try {
        if (!table_exists($pdo, $table)) return false;
        $stmt = $pdo->prepare("SHOW COLUMNS FROM `$table` LIKE ?");
        $stmt->execute([$column]);
        return $stmt->fetchColumn() !== false;
    } catch (Throwable $e) {
        return false;
    }
}

function fetch_one(PDO $pdo, $sql, $params = []) {
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return is_array($row) ? $row : null;
    } catch (Throwable $e) {
        pm_log('fetch_one_failed', ['sql' => $sql, 'error' => $e->getMessage()]);
        return null;
    }
}

function fetch_all(PDO $pdo, $sql, $params = []) {
    try {
        $stmt = $pdo->prepare($sql);
        $stmt->execute($params);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        return is_array($rows) ? $rows : [];
    } catch (Throwable $e) {
        pm_log('fetch_all_failed', ['sql' => $sql, 'error' => $e->getMessage()]);
        return [];
    }
}

function verify_session(PDO $pdo, $userId, $apiToken) {
    if ($userId <= 0 || trim((string)$apiToken) === '') return false;

    $user = fetch_one($pdo, 'SELECT id, api_token_hash FROM users WHERE id = ? LIMIT 1', [$userId]);
    if (!$user) return false;

    $stored = trim((string)($user['api_token_hash'] ?? ''));
    if ($stored === '') return false;

    if (preg_match('/^[a-f0-9]{64}$/i', $stored)) {
        return hash_equals(strtolower($stored), hash('sha256', $apiToken));
    }

    if (strpos($stored, '$2y$') === 0 || strpos($stored, '$argon2') === 0) {
        return password_verify($apiToken, $stored);
    }

    return false;
}

function fa_digits($value) {
    return strtr((string)$value, [
        '0' => '۰', '1' => '۱', '2' => '۲', '3' => '۳', '4' => '۴',
        '5' => '۵', '6' => '۶', '7' => '۷', '8' => '۸', '9' => '۹'
    ]);
}

function toman_text($amount) {
    $amount = (int)$amount;
    if ($amount <= 0) return 'رایگان';
    return fa_digits(number_format($amount)) . ' تومان';
}

function clean_text($value, $fallback = '') {
    $value = trim((string)$value);
    return $value !== '' ? $value : $fallback;
}

function gregorian_to_jalali($gy, $gm, $gd) {
    $g_d_m = [0,31,59,90,120,151,181,212,243,273,304,334];
    $gy2 = ($gm > 2) ? ($gy + 1) : $gy;
    $days = 355666 + (365 * $gy) + (int)(($gy2 + 3) / 4) - (int)(($gy2 + 99) / 100) + (int)(($gy2 + 399) / 400) + $gd + $g_d_m[$gm - 1];
    $jy = -1595 + (33 * (int)($days / 12053));
    $days %= 12053;
    $jy += 4 * (int)($days / 1461);
    $days %= 1461;
    if ($days > 365) {
        $jy += (int)(($days - 1) / 365);
        $days = ($days - 1) % 365;
    }
    if ($days < 186) {
        $jm = 1 + (int)($days / 31);
        $jd = 1 + ($days % 31);
    } else {
        $jm = 7 + (int)(($days - 186) / 30);
        $jd = 1 + (($days - 186) % 30);
    }
    return [$jy, $jm, $jd];
}

function jalali_date_text($raw) {
    $raw = trim((string)$raw);
    if ($raw === '' || $raw === '0000-00-00 00:00:00' || $raw === '0000-00-00') return '';
    $ts = strtotime($raw);
    if ($ts === false) return '';
    [$jy, $jm, $jd] = gregorian_to_jalali((int)date('Y', $ts), (int)date('n', $ts), (int)date('j', $ts));
    return fa_digits(sprintf('%04d/%02d/%02d', $jy, $jm, $jd));
}

function created_text($row) {
    $candidates = ['created_at', 'created_date', 'paid_at', 'updated_at'];
    foreach ($candidates as $key) {
        if (!array_key_exists($key, $row)) continue;
        $formatted = jalali_date_text($row[$key]);
        if ($formatted !== '') return $formatted;
    }
    return 'ثبت‌شده';
}

function lookup_title(PDO $pdo, $table, $id, $titleColumns = ['title', 'name', 'name_fa']) {
    $id = (int)$id;
    if ($id <= 0 || !table_exists($pdo, $table)) return '';

    foreach ($titleColumns as $column) {
        if (!column_exists($pdo, $table, $column)) continue;
        $row = fetch_one($pdo, "SELECT `$column` AS title FROM `$table` WHERE id = ? LIMIT 1", [$id]);
        if ($row && trim((string)($row['title'] ?? '')) !== '') return trim((string)$row['title']);
    }
    return '';
}

function budget_info(PDO $pdo, $row) {
    $custom = (int)($row['is_custom_budget'] ?? 0) === 1 || (int)($row['custom_budget_enabled'] ?? 0) === 1;
    if ($custom) {
        $min = (int)($row['custom_budget_min'] ?? 0);
        $max = (int)($row['custom_budget_max'] ?? 0);
        $range = 'بودجه مشخص نشده';
        if ($min > 0 && $max > 0) $range = toman_text($min) . ' تا ' . toman_text($max);
        elseif ($min > 0) $range = 'از ' . toman_text($min);
        elseif ($max > 0) $range = 'تا ' . toman_text($max);
        return ['بودجه دلخواه', $range];
    }

    $budgetId = (int)($row['budget_range_id'] ?? 0);
    $title = 'بودجه مشخص نشده';
    $range = 'بودجه مشخص نشده';

    if ($budgetId > 0 && table_exists($pdo, 'project_budget_ranges')) {
        $columns = ['id'];
        foreach (['title', 'name', 'min_budget', 'max_budget'] as $col) {
            if (column_exists($pdo, 'project_budget_ranges', $col)) $columns[] = "`$col`";
        }
        $sql = 'SELECT ' . implode(',', $columns) . ' FROM project_budget_ranges WHERE id = ? LIMIT 1';
        $budget = fetch_one($pdo, $sql, [$budgetId]);
        if ($budget) {
            $titleCandidate = trim((string)($budget['title'] ?? $budget['name'] ?? ''));
            if ($titleCandidate !== '') $title = $titleCandidate;
            $min = (int)($budget['min_budget'] ?? 0);
            $max = (int)($budget['max_budget'] ?? 0);
            if ($min > 0 && $max > 0) $range = toman_text($min) . ' تا ' . toman_text($max);
            elseif ($min > 0 && $max <= 0) $range = 'بیش از ' . toman_text($min);
            elseif ($max > 0) $range = 'تا ' . toman_text($max);
            else $range = $title;
        }
    }

    return [$title, $range];
}

function budget_text(PDO $pdo, $row) {
    [$title, $range] = budget_info($pdo, $row);
    return $range !== 'بودجه مشخص نشده' ? $range : $title;
}

function deadline_text(PDO $pdo, $row) {
    $custom = trim((string)($row['custom_deadline_text'] ?? ''));
    if ($custom !== '') return $custom;

    $deadlineId = (int)($row['deadline_option_id'] ?? 0);
    $title = lookup_title($pdo, 'project_deadline_options', $deadlineId, ['title', 'name']);
    return $title !== '' ? $title : 'زمان مشخص نشده';
}

function classify_project($status, $paymentStatus, $paymentAmount) {
    $s = strtolower(trim((string)$status));
    $p = strtolower(trim((string)$paymentStatus));
    $amount = (int)$paymentAmount;

    if (in_array($s, ['cancelled', 'canceled', 'deleted'], true)) {
        return ['cancelled', 'لغو شده', '#EF4056', 'این پروژه لغو شده یا از چرخه اجرا خارج شده است.', 0];
    }

    if (in_array($s, ['completed', 'done', 'finished'], true)) {
        return ['completed', 'تکمیل شده', '#18A957', 'پروژه تکمیل شده و برای آرشیو و گزارش آماده است.', 100];
    }

    if ($amount > 0 && !in_array($p, ['paid', 'free', 'completed'], true)) {
        $label = in_array($p, ['failed', 'verify_failed'], true) ? 'پرداخت ناموفق' : 'در انتظار پرداخت';
        return ['draft', $label, '#F59E0B', 'برای انتشار پروژه باید پرداخت ثبت پروژه کامل شود.', 18];
    }

    if (in_array($s, ['draft', 'unpaid', 'pending_payment'], true)) {
        return ['draft', 'پیش‌نویس', '#F59E0B', 'این پروژه هنوز برای فریلنسرها منتشر نشده است.', 12];
    }

    if (in_array($s, ['awarded', 'escrow_pending'], true)) {
        return ['active', 'انتخاب فریلنسر', '#2F5BEA', 'پیشنهاد انتخاب شده و مرحله گروگذاری باید تکمیل شود.', 55];
    }

    if (in_array($s, ['in_progress', 'running'], true)) {
        return ['active', 'در حال اجرا', '#2F5BEA', 'پروژه در حال انجام است و گفتگو و پرداخت مرحله‌ای فعال می‌شود.', 72];
    }

    if (in_array($s, ['submitted', 'delivered'], true)) {
        return ['active', 'تحویل‌شده', '#2F5BEA', 'فریلنسر کار را تحویل داده و منتظر بررسی کارفرماست.', 84];
    }

    if (in_array($s, ['dispute'], true)) {
        return ['active', 'اختلاف', '#EF4056', 'پرونده اختلاف باز است و مدیریت باید بررسی کند.', 65];
    }

    return ['active', 'منتشر شده', '#2F5BEA', 'پروژه منتشر شده و آماده دریافت پیشنهاد از فریلنسرهاست.', 35];
}

function payment_label($paymentStatus, $amount) {
    $p = strtolower(trim((string)$paymentStatus));
    $amount = (int)$amount;
    if ($amount <= 0) return 'رایگان';
    if (in_array($p, ['paid', 'free', 'completed'], true)) return 'پرداخت شده';
    if (in_array($p, ['failed', 'verify_failed'], true)) return 'پرداخت ناموفق';
    if (in_array($p, ['payment_started', 'token_created', 'redirected'], true)) return 'در حال پرداخت';
    return 'در انتظار پرداخت';
}

function count_project_offers(PDO $pdo, $projectId, $onlyPending = false) {
    if (!table_exists($pdo, 'project_offers') || !column_exists($pdo, 'project_offers', 'project_id')) return 0;
    try {
        if ($onlyPending && column_exists($pdo, 'project_offers', 'status')) {
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM project_offers WHERE project_id = ? AND status IN ('pending','new','sent')");
            $stmt->execute([$projectId]);
            return (int)$stmt->fetchColumn();
        }
        $stmt = $pdo->prepare('SELECT COUNT(*) FROM project_offers WHERE project_id = ?');
        $stmt->execute([$projectId]);
        return (int)$stmt->fetchColumn();
    } catch (Throwable $e) {
        return 0;
    }
}

function count_unread_project_messages(PDO $pdo, $projectId, $userId) {
    if (!table_exists($pdo, 'project_messages') || !column_exists($pdo, 'project_messages', 'project_id')) return 0;

    try {
        $userColumn = null;
        if (column_exists($pdo, 'project_messages', 'receiver_user_id')) $userColumn = 'receiver_user_id';
        elseif (column_exists($pdo, 'project_messages', 'to_user_id')) $userColumn = 'to_user_id';
        elseif (column_exists($pdo, 'project_messages', 'user_id')) $userColumn = 'user_id';
        if (!$userColumn) return 0;

        if (column_exists($pdo, 'project_messages', 'is_read')) {
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM project_messages WHERE project_id = ? AND `$userColumn` = ? AND is_read = 0");
            $stmt->execute([$projectId, $userId]);
            return (int)$stmt->fetchColumn();
        }

        if (column_exists($pdo, 'project_messages', 'read_at')) {
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM project_messages WHERE project_id = ? AND `$userColumn` = ? AND read_at IS NULL");
            $stmt->execute([$projectId, $userId]);
            return (int)$stmt->fetchColumn();
        }

        return 0;
    } catch (Throwable $e) {
        return 0;
    }
}

function project_escrow_amount(PDO $pdo, $projectId) {
    if (!table_exists($pdo, 'project_escrows') || !column_exists($pdo, 'project_escrows', 'project_id')) return 0;

    $amountColumn = null;
    foreach (['escrow_amount', 'held_amount', 'amount'] as $col) {
        if (column_exists($pdo, 'project_escrows', $col)) {
            $amountColumn = $col;
            break;
        }
    }
    if (!$amountColumn) return 0;

    try {
        if (column_exists($pdo, 'project_escrows', 'status')) {
            $stmt = $pdo->prepare("SELECT COALESCE(SUM(`$amountColumn`),0) FROM project_escrows WHERE project_id = ? AND status IN ('held','active','pending')");
        } else {
            $stmt = $pdo->prepare("SELECT COALESCE(SUM(`$amountColumn`),0) FROM project_escrows WHERE project_id = ?");
        }
        $stmt->execute([$projectId]);
        return (int)$stmt->fetchColumn();
    } catch (Throwable $e) {
        return 0;
    }
}


function option_badge_payload($key, $fallbackTitle = 'ویژه', $fallbackColor = 'featured') {
    $key = strtolower(trim((string)$key));

    if ($key === 'urgent_project' || strpos($key, 'urgent') !== false && strpos($key, 'bundle') === false) {
        return ['title' => 'فوری', 'color_key' => 'urgent'];
    }
    if ($key === 'featured_project' || strpos($key, 'featured') !== false && strpos($key, 'bundle') === false) {
        return ['title' => 'برجسته', 'color_key' => 'featured'];
    }
    if ($key === 'infinity_project' || $key === 'unlimited_project' || strpos($key, 'infinity') !== false || strpos($key, 'unlimited') !== false) {
        return ['title' => 'بی‌نهایت', 'color_key' => 'infinity'];
    }
    if ($key === 'private_project' || strpos($key, 'private') !== false) {
        return ['title' => 'محرمانه', 'color_key' => 'private'];
    }
    if ($key === 'sealed_project' || strpos($key, 'sealed') !== false) {
        return ['title' => 'پیشنهاد مخفی', 'color_key' => 'private'];
    }

    return ['title' => clean_text($fallbackTitle, 'ویژه'), 'color_key' => clean_text($fallbackColor, 'featured')];
}

function split_option_keys_for_badges($raw) {
    $raw = trim((string)$raw);
    if ($raw === '') return [];
    $parts = preg_split('/[,،|;]+/u', $raw);
    $out = [];
    foreach ($parts as $part) {
        $part = trim((string)$part);
        if ($part !== '') $out[] = $part;
    }
    return array_values(array_unique($out));
}

function is_bundle_option_row($row) {
    $type = strtolower(trim((string)($row['option_type'] ?? '')));
    $key = strtolower(trim((string)($row['option_key'] ?? '')));
    if ($type === 'bundle') return true;
    if (in_array($key, ['urgent_featured_bundle', 'featured_urgent_bundle'], true)) return true;
    return false;
}

function project_badges(PDO $pdo, $projectId) {
    $projectId = (int)$projectId;
    if ($projectId <= 0) return [];
    if (!table_exists($pdo, 'project_selected_options') || !table_exists($pdo, 'project_options')) return [];
    if (!column_exists($pdo, 'project_selected_options', 'project_id') || !column_exists($pdo, 'project_selected_options', 'option_id')) return [];

    $titleExpr = column_exists($pdo, 'project_options', 'title') ? 'po.title' : "'ویژه'";
    $badgeExpr = column_exists($pdo, 'project_options', 'badge_text') ? 'po.badge_text' : "''";
    $colorExpr = column_exists($pdo, 'project_options', 'badge_color_key') ? 'po.badge_color_key' : "'featured'";
    $keyExpr = column_exists($pdo, 'project_options', 'option_key') ? 'po.option_key' : "''";
    $typeExpr = column_exists($pdo, 'project_options', 'option_type') ? 'po.option_type' : "''";
    $includedKeysExpr = column_exists($pdo, 'project_options', 'included_option_keys') ? 'po.included_option_keys' : "''";
    $includedIdsExpr = column_exists($pdo, 'project_options', 'included_option_ids') ? 'po.included_option_ids' : "''";

    try {
        $rows = fetch_all($pdo, "
            SELECT po.id,
                   $titleExpr AS title,
                   $badgeExpr AS badge_text,
                   $colorExpr AS color_key,
                   $keyExpr AS option_key,
                   $typeExpr AS option_type,
                   $includedKeysExpr AS included_option_keys,
                   $includedIdsExpr AS included_option_ids
            FROM project_selected_options pso
            INNER JOIN project_options po ON po.id = pso.option_id
            WHERE pso.project_id = ?
            ORDER BY po.id ASC
            LIMIT 12
        ", [$projectId]);

        $badges = [];
        $seen = [];

        foreach ($rows as $row) {
            $key = strtolower((string)($row['option_key'] ?? ''));

            // اگر بسته فوری و برجسته ذخیره شده باشد، در کارت مدیریت پروژه زیرمجموعه‌های قابل فهم آن نمایش داده می‌شود، نه عنوان بسته.
            if (is_bundle_option_row($row)) {
                $childKeys = split_option_keys_for_badges($row['included_option_keys'] ?? '');
                if (!$childKeys && in_array($key, ['urgent_featured_bundle', 'featured_urgent_bundle'], true)) {
                    $childKeys = ['urgent_project', 'featured_project'];
                }

                foreach ($childKeys as $childKey) {
                    $payload = option_badge_payload($childKey);
                    $dedup = $payload['title'] . '|' . $payload['color_key'];
                    if (!isset($seen[$dedup])) {
                        $badges[] = $payload;
                        $seen[$dedup] = true;
                    }
                }
                continue;
            }

            $fallbackTitle = clean_text($row['badge_text'] ?? '', '');
            if ($fallbackTitle === '') $fallbackTitle = clean_text($row['title'] ?? '', 'ویژه');
            $fallbackColor = clean_text($row['color_key'] ?? '', 'featured');
            $payload = option_badge_payload($key, $fallbackTitle, $fallbackColor);
            $dedup = $payload['title'] . '|' . $payload['color_key'];
            if (!isset($seen[$dedup])) {
                $badges[] = $payload;
                $seen[$dedup] = true;
            }
        }

        return array_slice($badges, 0, 4);
    } catch (Throwable $e) {
        pm_log('project_badges_failed', ['project_id' => $projectId, 'error' => $e->getMessage()]);
        return [];
    }
}

try {
    $pdo = new PDO(
        "mysql:host={$DB_HOST};dbname={$DB_NAME};charset=utf8mb4",
        $DB_USER,
        $DB_PASS,
        [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]
    );
} catch (Throwable $e) {
    pm_log('db_failed', ['error' => $e->getMessage()]);
    respond(false, [], 'اتصال به دیتابیس برقرار نشد');
}

$input = input_json();
$action = trim((string)($input['action'] ?? ''));
$userId = (int)($input['user_id'] ?? 0);
$apiToken = trim((string)($input['api_token'] ?? ''));

if (!verify_session($pdo, $userId, $apiToken)) {
    respond(false, [], 'نشست ورود معتبر نیست؛ دوباره وارد حساب شو');
}

if ($action !== 'get_employer_projects') {
    respond(false, [], 'درخواست نامعتبر است');
}

if (!table_exists($pdo, 'projects')) {
    respond(true, [
        'stats' => ['total' => 0, 'draft' => 0, 'active' => 0, 'completed' => 0, 'cancelled' => 0, 'new_offers' => 0, 'unread_messages' => 0, 'escrow_amount' => 0],
        'projects' => [],
    ], 'جدول پروژه‌ها هنوز ساخته نشده است');
}

if (!column_exists($pdo, 'projects', 'employer_user_id')) {
    respond(false, [], 'ساختار جدول projects ناقص است: ستون employer_user_id وجود ندارد');
}

$rows = fetch_all($pdo, 'SELECT * FROM projects WHERE employer_user_id = ? ORDER BY id DESC LIMIT 150', [$userId]);

$projects = [];
$stats = [
    'total' => 0,
    'draft' => 0,
    'active' => 0,
    'completed' => 0,
    'cancelled' => 0,
    'new_offers' => 0,
    'unread_messages' => 0,
    'escrow_amount' => 0,
];

foreach ($rows as $row) {
    $projectId = (int)($row['id'] ?? 0);
    if ($projectId <= 0) continue;

    $title = clean_text($row['title'] ?? '', 'پروژه بدون عنوان');
    $description = clean_text($row['description'] ?? '', '');
    $status = clean_text($row['status'] ?? '', 'draft');
    $paymentStatus = clean_text($row['payment_status'] ?? '', '');
    $paymentAmount = (int)($row['payment_amount'] ?? 0);

    [$group, $statusLabel, $statusColor, $statusHint, $progress] = classify_project($status, $paymentStatus, $paymentAmount);

    $serviceTitle = lookup_title($pdo, 'project_service_types', (int)($row['service_type_id'] ?? 0), ['title', 'name']);
    if ($serviceTitle === '') $serviceTitle = 'سرویس نامشخص';

    $offersCount = count_project_offers($pdo, $projectId, false);
    $pendingOffers = count_project_offers($pdo, $projectId, true);
    $unreadMessages = count_unread_project_messages($pdo, $projectId, $userId);
    $escrowAmount = project_escrow_amount($pdo, $projectId);

    $canPayAgain = $paymentAmount > 0 && !in_array(strtolower($paymentStatus), ['paid', 'free', 'completed'], true);
    $canEdit = $group === 'draft';
    [$budgetTitle, $budgetRangeText] = budget_info($pdo, $row);

    $projects[] = [
        'id' => $projectId,
        'title' => $title,
        'description' => $description,
        'service_title' => $serviceTitle,
        'budget_text' => budget_text($pdo, $row),
        'budget_title' => $budgetTitle,
        'budget_range_text' => $budgetRangeText,
        'deadline_text' => deadline_text($pdo, $row),
        'created_text' => created_text($row),
        'status' => $status,
        'status_group' => $group,
        'status_label' => $statusLabel,
        'status_color' => $statusColor,
        'status_hint' => $statusHint,
        'payment_status' => $paymentStatus,
        'payment_label' => payment_label($paymentStatus, $paymentAmount),
        'payment_amount' => $paymentAmount,
        'offers_count' => $offersCount,
        'unread_messages' => $unreadMessages,
        'escrow_amount' => $escrowAmount,
        'progress_percent' => $progress,
        'can_pay_again' => $canPayAgain,
        'can_edit' => $canEdit,
        'badges' => project_badges($pdo, $projectId),
    ];

    $stats['total']++;
    if (isset($stats[$group])) $stats[$group]++;
    $stats['new_offers'] += $pendingOffers;
    $stats['unread_messages'] += $unreadMessages;
    $stats['escrow_amount'] += $escrowAmount;
}

respond(true, [
    'stats' => $stats,
    'projects' => $projects,
], 'لیست پروژه‌ها دریافت شد');
