<?php
// ============================================================
// includes/functions.php — دوال مساعدة عامة
// ============================================================

function sanitize(string $val): string {
    return htmlspecialchars(trim($val), ENT_QUOTES, 'UTF-8');
}

function generateCaseNumber(): string {
    $year = date('Y');
    $pdo  = db();
    $cnt  = $pdo->query("SELECT COUNT(*) FROM cases WHERE YEAR(created_at) = $year")->fetchColumn();
    return sprintf('QD-%s-%04d', $year, (int)$cnt + 1);
}

function uploadFile(array $file, string $subfolder = 'docs'): array {
    $dir = UPLOAD_PATH . $subfolder . '/';
    if (!is_dir($dir)) mkdir($dir, 0755, true);

    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    if (!in_array($ext, ALLOWED_EXT, true)) {
        return ['success' => false, 'message' => 'امتداد الملف غير مسموح'];
    }
    if ($file['size'] > MAX_FILE_SIZE) {
        return ['success' => false, 'message' => 'حجم الملف يتجاوز 5 ميغا'];
    }

    $name = uniqid('file_', true) . '.' . $ext;
    if (move_uploaded_file($file['tmp_name'], $dir . $name)) {
        return ['success' => true, 'path' => $subfolder . '/' . $name];
    }
    return ['success' => false, 'message' => 'فشل رفع الملف'];
}

function createNotification(int $userId, string $type, string $title, string $message, ?string $link = null): void {
    try {
        db()->prepare('INSERT INTO notifications (user_id, type, title, message, link) VALUES (?,?,?,?,?)')
            ->execute([$userId, $type, $title, $message, $link]);
    } catch (\Exception $e) {
        error_log('Notification error: ' . $e->getMessage());
    }
}

function getUnreadNotifCount(int $userId): int {
    return (int) db()->prepare('SELECT COUNT(*) FROM notifications WHERE user_id = ? AND is_read = 0')
        ->execute([$userId]) && false ?: (function() use ($userId) {
            $s = db()->prepare('SELECT COUNT(*) FROM notifications WHERE user_id = ? AND is_read = 0');
            $s->execute([$userId]);
            return (int)$s->fetchColumn();
        })();
}

function getNotifications(int $userId, int $limit = 10): array {
    $s = db()->prepare('SELECT * FROM notifications WHERE user_id = ? ORDER BY created_at DESC LIMIT ?');
    $s->execute([$userId, $limit]);
    return $s->fetchAll();
}

function formatDate(?string $date, bool $time = false): string {
    if (!$date) return '—';
    $ts  = strtotime($date);
    $fmt = $time ? 'd/m/Y H:i' : 'd/m/Y';
    return date($fmt, $ts);
}

function badgeHtml(string $text, string $class): string {
    return "<span class='badge bg-{$class}'>{$text}</span>";
}

function caseStatusBadge(string $status): string {
    $map = CASE_STATUS;
    $info = $map[$status] ?? ['label' => $status, 'class' => 'secondary'];
    return badgeHtml($info['label'], $info['class']);
}

function paginate(int $total, int $perPage, int $current): array {
    $pages     = (int) ceil($total / $perPage);
    $offset    = ($current - 1) * $perPage;
    return ['total' => $total, 'pages' => $pages, 'current' => $current, 'offset' => $offset, 'per_page' => $perPage];
}

// ============================================================
// — التحقق من حق الوصول لتفاصيل قضية —
// ============================================================
// قاعدة الوصول: أطراف النزاع فقط هم من يطّلعون على تفاصيل القضية.
// عملياً في النظام:
//   • admin  : يصل لكل القضايا (دور إشراف)
//   • clerk  : يصل لكل القضايا (موظف قضائي داخلي)
//   • lawyer : يصل فقط للقضايا المسندة إليه عبر case_lawyers
function canViewCase(int $userId, string $role, int $caseId): bool {
    if ($role === ROLE_ADMIN || $role === ROLE_CLERK) return true;
    if ($role !== ROLE_LAWYER) return false;
    $stmt = db()->prepare('SELECT 1 FROM case_lawyers WHERE case_id = ? AND lawyer_id = ? LIMIT 1');
    $stmt->execute([$caseId, $userId]);
    return (bool) $stmt->fetchColumn();
}

// يفرض التحقق ويرجع 403 عند الرفض
function requireCaseAccess(int $caseId): void {
    $u = currentUser();
    if (!canViewCase((int)$u['id'], $u['role'], $caseId)) {
        http_response_code(403);
        include __DIR__ . '/../public/403.php';
        exit;
    }
}

// ============================================================
// — حساب أجل تقديم الطعن —
// ============================================================
// يُرجع تاريخ انتهاء أجل الطعن بناءً على نوع الطعن وطبيعة القضية.
// تنبيه: هذه أيام تقويمية تقريبية وفق قانون 08-09 وق.إ.ج.
// لا تُغني عن مراجعة محامٍ مختص في الحالات الحساسة.
function computeRecourseDeadline(string $recourseType, string $judgmentDate, string $caseType): ?string {
    $types = RECOURSE_TYPES;
    if (!isset($types[$recourseType])) return null;
    $isPenal = ($caseType === 'criminal');
    $days = $isPenal ? $types[$recourseType]['deadline_days_penal'] : $types[$recourseType]['deadline_days_civil'];
    if ($days <= 0) return null;
    $ts = strtotime($judgmentDate);
    if ($ts === false) return null;
    return date('Y-m-d', strtotime("+{$days} days", $ts));
}

// ============================================================
// — جلب المحاكم المناسبة لمرحلة قضية وفرع قضائي ووَلاية —
// ============================================================
function getCourtsFor(string $stage, string $branch, ?string $wilayaCode = null): array {
    $pdo    = db();
    $levels = STAGE_TO_LEVELS[$stage] ?? [];
    if (!$levels) return [];
    $in     = implode(',', array_fill(0, count($levels), '?'));
    $params = $levels;
    $sql    = "SELECT id, name, level, wilaya_code, daira FROM courts WHERE branch = ? AND level IN ($in)";
    array_unshift($params, $branch);
    if ($wilayaCode) {
        // نسمح أيضاً بالجهات الاتحادية (wilaya_code قد يكون NULL في الواقع لا، لكن للسلامة)
        $sql .= ' AND (wilaya_code = ? OR level IN (?, ?))';
        $params[] = $wilayaCode;
        $params[] = 'mahkama_3oulia';
        $params[] = 'majlis_dawla';
    }
    $sql .= ' ORDER BY level, name';
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    return $stmt->fetchAll();
}

// ============================================================
// — توليد رقم قضية ذكي بناءً على رمز المحكمة —
// ============================================================
function generateCaseNumberFor(?string $courtCode = null): string {
    $year = date('Y');
    $pdo  = db();
    $cnt  = (int) $pdo->query("SELECT COUNT(*) FROM cases WHERE YEAR(created_at) = $year")->fetchColumn();
    $prefix = $courtCode ?: 'QD';
    return sprintf('%s-%s-%04d', $prefix, $year, $cnt + 1);
}

// ============================================================
// — نظام الشكاوي —
// ============================================================
function generateComplaintNumber(): string {
    $year = date('Y');
    $pdo  = db();
    $cnt  = (int) $pdo->query("SELECT COUNT(*) FROM complaints WHERE YEAR(created_at) = $year")->fetchColumn();
    return sprintf('SHK-%s-%04d', $year, $cnt + 1);
}

function createComplaint(int $userId, string $role, array $data): int {
    $pdo = db();
    $number = generateComplaintNumber();
    $pdo->prepare("INSERT INTO complaints (complaint_number,user_id,user_role,category,subject,description,related_case_id,priority)
                    VALUES (?,?,?,?,?,?,?,?)")
        ->execute([
            $number, $userId, $role,
            $data['category'], $data['subject'], $data['description'],
            $data['related_case_id'] ?: null,
            $data['priority'] ?: 'normal',
        ]);
    $complaintId = (int) $pdo->lastInsertId();

    // إشعار جميع المدراء النشطين بشكوى جديدة
    $admins = $pdo->query("SELECT id FROM users WHERE role='admin' AND status='active'")->fetchAll();
    foreach ($admins as $adm) {
        createNotification($adm['id'], 'complaint_new', 'شكوى جديدة: ' . $number,
            $data['subject'], BASE_URL . '/modules/admin/complaints.php?id=' . $complaintId);
    }
    auditLog($userId, 'create_complaint', 'complaints', $complaintId, 'تقديم شكوى: ' . $data['subject']);
    return $complaintId;
}

function addComplaintMessage(int $complaintId, int $senderId, string $senderRole, string $message, bool $isInternal = false, ?string $attachmentPath = null): void {
    $pdo = db();
    $pdo->prepare("INSERT INTO complaint_messages (complaint_id,sender_id,sender_role,message,is_internal,attachment_path) VALUES (?,?,?,?,?,?)")
        ->execute([$complaintId, $senderId, $senderRole, $message, $isInternal ? 1 : 0, $attachmentPath]);

    if (!$isInternal) {
        // أشعر صاحب الشكوى إن كان الرد من الإدارة، وأشعر الإدارة إن كان من صاحب الشكوى
        $c = $pdo->prepare("SELECT * FROM complaints WHERE id=?");
        $c->execute([$complaintId]);
        $complaint = $c->fetch();
        if ($complaint) {
            if ($senderId !== (int)$complaint['user_id']) {
                createNotification((int)$complaint['user_id'], 'complaint_reply', 'رد جديد على شكواك',
                    'تمت إضافة رد على الشكوى رقم ' . $complaint['complaint_number'],
                    BASE_URL . '/modules/' . $complaint['user_role'] . '/complaints.php?id=' . $complaintId);
            } else {
                $admins = $pdo->query("SELECT id FROM users WHERE role='admin' AND status='active'")->fetchAll();
                foreach ($admins as $adm) {
                    createNotification($adm['id'], 'complaint_reply', 'رد جديد من صاحب شكوى',
                        'رد جديد على الشكوى رقم ' . $complaint['complaint_number'],
                        BASE_URL . '/modules/admin/complaints.php?id=' . $complaintId);
                }
            }
        }
    }
    auditLog($senderId, 'complaint_message', 'complaints', $complaintId, 'إضافة رسالة على شكوى');
}

function complaintStatusBadge(string $status): string {
    $info = COMPLAINT_STATUS[$status] ?? ['label' => $status, 'class' => 'secondary'];
    return badgeHtml($info['label'], $info['class']);
}

function complaintPriorityBadge(string $priority): string {
    $info = COMPLAINT_PRIORITY[$priority] ?? ['label' => $priority, 'class' => 'secondary'];
    return badgeHtml($info['label'], $info['class']);
}
