<?php
declare(strict_types=1);

if (session_status() === PHP_SESSION_NONE) session_start();
require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/auth.php';
require_once __DIR__ . '/db_bootstrap.php';
require_once __DIR__ . '/security.php';
require_once __DIR__ . '/subscriber_contracts_lib.php';
require_once __DIR__ . '/subscriber_contracts_bulk_export_lib.php';
require_once __DIR__ . '/output_devices_lib.php';

require_login('index.php?login=1');
if (function_exists('require_perm')) require_perm('can_view_subscribers');
if (function_exists('ensure_db')) ensure_db(true);
$conn = $GLOBALS['conn'] ?? null;
if (!($conn instanceof mysqli)) { http_response_code(500); die('Database connection error'); }

$isAndroid = ((string)($_GET['ua_android'] ?? '') === '1')
    || stripos((string)($_SERVER['HTTP_USER_AGENT'] ?? ''), 'NetworkCustomersAndroid/') !== false;
$GLOBALS['SC_PAGE_ANDROID'] = $isAndroid;
$platformQuery = $isAndroid ? 'ua_android=1&' : '';

function sc_page_panel(string $value, string $fallback = 'subscribers'): string {
    $value = strtolower(trim($value));
    $aliases = ['bulk' => 'bulk-export', 'print' => 'bulk-export'];
    $value = $aliases[$value] ?? $value;
    return in_array($value, ['subscribers', 'contracts', 'templates', 'history', 'bulk-export'], true)
        ? $value
        : $fallback;
}

sc_ensure_schema($conn);
$defaultTemplatePath = 'templates/default-subscriber-contract.docx';
if (is_file(sc_safe_storage_path($defaultTemplatePath))) {
    $exists = $conn->query("SELECT id FROM subscriber_contract_templates WHERE file_path='templates/default-subscriber-contract.docx' LIMIT 1");
    if (!$exists || $exists->num_rows === 0) {
        $hasAny = $conn->query('SELECT id FROM subscriber_contract_templates WHERE is_active=1 LIMIT 1');
        $isDefault = (!$hasAny || $hasAny->num_rows === 0) ? 1 : 0;
        $stmt = $conn->prepare('INSERT INTO subscriber_contract_templates(name,file_path,original_filename,is_default,created_by) VALUES(?,?,?,?,?)');
        if ($stmt) {
            $name = 'قالب عقد المشترك الافتراضي';
            $original = 'default-subscriber-contract.docx';
            $actor = 'system';
            $stmt->bind_param('sssis', $name, $defaultTemplatePath, $original, $isDefault, $actor);
            @$stmt->execute();
            $stmt->close();
        }
    }
}

function sc_page_redirect(array $params = [], string $fragment = ''): never {
    if (!empty($GLOBALS['SC_PAGE_ANDROID'])) $params['ua_android'] = 1;
    $panelHint = (string)($params['panel'] ?? $params['tab'] ?? '');
    if ($panelHint === '') {
        if (isset($params['contract_id'])) $panelHint = 'contracts';
        elseif (isset($params['mapping_template_id'])) $panelHint = 'templates';
        elseif ($fragment !== '') $panelHint = $fragment;
    }
    $panel = sc_page_panel($panelHint);
    unset($params['tab']);
    $params['panel'] = $panel;
    $location = 'subscriber_contracts.php?' . http_build_query($params);
    $location .= '#' . rawurlencode($fragment !== '' ? $fragment : $panel);
    header('Location: ' . $location);
    exit;
}

function sc_page_contract_row(mysqli $conn, int $id): ?array {
    $stmt = $conn->prepare('SELECT c.*, t.name template_name FROM subscriber_contracts c LEFT JOIN subscriber_contract_templates t ON t.id=c.template_id WHERE c.id=? LIMIT 1');
    if (!$stmt) return null;
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $row = $stmt->get_result()->fetch_assoc() ?: null;
    $stmt->close();
    return $row;
}

if (isset($_GET['download_contract'])) {
    $row = sc_page_contract_row($conn, max(0, (int)$_GET['download_contract']));
    if (!$row || trim((string)$row['generated_path']) === '') { http_response_code(404); die('Contract not found'); }
    $path = sc_safe_storage_path((string)$row['generated_path']);
    if (!is_file($path)) { http_response_code(404); die('Contract file not found'); }
    sc_event($conn, (int)$row['id'], (int)$row['subscriber_id'], 'DOWNLOAD', 'تم تنزيل ملف العقد.');
    $name = trim((string)$row['generated_filename']) ?: ('contract-' . (int)$row['id'] . '.docx');
    header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
    header('Content-Length: ' . filesize($path));
    header("Content-Disposition: attachment; filename=contract-" . (int)$row['id'] . ".docx; filename*=UTF-8''" . rawurlencode($name));
    header('X-UA-Contract-Id: ' . (int)$row['id']);
    header('X-Content-Type-Options: nosniff');
    readfile($path);
    exit;
}

if (isset($_GET['download_template'])) {
    $id = max(0, (int)$_GET['download_template']);
    $stmt = $conn->prepare('SELECT * FROM subscriber_contract_templates WHERE id=? AND is_active=1 LIMIT 1');
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $row = $stmt->get_result()->fetch_assoc();
    $stmt->close();
    if (!$row) { http_response_code(404); die('Template not found'); }
    $path = sc_safe_storage_path((string)$row['file_path']);
    if (!is_file($path)) { http_response_code(404); die('Template file not found'); }
    $name = trim((string)$row['original_filename']) ?: ('contract-template-' . $id . '.docx');
    header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
    header('Content-Length: ' . filesize($path));
    header("Content-Disposition: attachment; filename=contract-template-" . $id . ".docx; filename*=UTF-8''" . rawurlencode($name));
    header('X-Content-Type-Options: nosniff');
    readfile($path);
    exit;
}
if (isset($_GET['download_batch'])) {
    $token=preg_replace('/[^a-f0-9]/','',(string)$_GET['download_batch']);
    $batch=(array)($_SESSION['sc_batch_downloads'][$token]??[]);
    $relative=(string)($batch['path']??'');
    if($relative===''||!str_starts_with($relative,'generated/batches/')){http_response_code(404);die('Batch not found');}
    $path=sc_safe_storage_path($relative);if(!is_file($path)){http_response_code(404);die('Batch file not found');}
    unset($_SESSION['sc_batch_downloads'][$token]);
    $mime=(string)($batch['mime']??'application/zip');
    if(!in_array($mime,['application/zip','application/pdf'],true))$mime='application/octet-stream';
    $filename=preg_replace('/[^A-Za-z0-9._-]/','',(string)($batch['filename']??''));
    if($filename==='')$filename=$mime==='application/pdf'?'subscriber-contracts.pdf':'subscriber-contracts.zip';
    header('Content-Type: '.$mime);header('Content-Length: '.filesize($path));header('Content-Disposition: attachment; filename="'.$filename.'"');header('X-Content-Type-Options: nosniff');readfile($path);exit;
}

$msg = trim((string)($_SESSION['sc_flash_success'] ?? ''));
$err = trim((string)($_SESSION['sc_flash_error'] ?? ''));
unset($_SESSION['sc_flash_success'], $_SESSION['sc_flash_error']);
$csrf = ua_csrf_token();
$postPanelByAction = [
    'upload_template' => 'templates',
    'save_branding' => 'templates',
    'set_default_template' => 'templates',
    'scan_template_fields' => 'templates',
    'save_template_fields' => 'templates',
    'delete_template' => 'templates',
    'regenerate_contract' => 'contracts',
    'generate_contract' => 'subscribers',
    'bulk_export_contracts' => 'bulk-export',
    'mark_printed' => 'contracts',
    'delete_contract' => 'contracts',
];
$requestPanelHint = (string)($_POST['return_panel']
    ?? $postPanelByAction[(string)($_POST['action'] ?? '')]
    ?? $_GET['panel']
    ?? $_GET['tab']
    ?? '');

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    try {
        if (!ua_csrf_verify()) throw new RuntimeException('انتهت صلاحية الطلب. أعد فتح الصفحة وحاول مجدداً.');
        $action = (string)($_POST['action'] ?? '');
        if ($action === 'upload_template') {
            [$relative, $original] = sc_upload_docx($_FILES['template_docx'] ?? []);
            $name = trim((string)($_POST['template_name'] ?? '')) ?: pathinfo($original, PATHINFO_FILENAME);
            $isDefault = !empty($_POST['is_default']) ? 1 : 0;
            if ($isDefault) $conn->query('UPDATE subscriber_contract_templates SET is_default=0');
            $actor = (string)($_SESSION['admin_username'] ?? $_SESSION['admin_user'] ?? 'admin');
            $stmt = $conn->prepare('INSERT INTO subscriber_contract_templates(name,file_path,original_filename,is_default,created_by) VALUES(?,?,?,?,?)');
            if (!$stmt) throw new RuntimeException('تعذر حفظ بيانات القالب.');
            $stmt->bind_param('sssis', $name, $relative, $original, $isDefault, $actor);
            if (!$stmt->execute()) throw new RuntimeException('تعذر حفظ بيانات القالب.');
            $templateId = (int)$stmt->insert_id;
            $stmt->close();
            $suggestions = sc_scan_template_keywords($relative);
            sc_seed_template_fields($conn, $templateId, $suggestions);
            sc_event($conn, null, 0, 'TEMPLATE_UPLOAD', 'تم رفع قالب: ' . $name);
            $_SESSION['sc_flash_success'] = 'تم رفع القالب وفحصه. راجع الكلمات المفتاحية المقترحة واحفظ المطابقة.';
            sc_page_redirect(['tab' => 'templates', 'mapping_template_id' => $templateId]);
        }
        if ($action === 'save_branding') {
            $companyName = trim((string)($_POST['company_name'] ?? '')) ?: 'الشركة';
            sc_setting_set($conn, 'company_name', $companyName);
            foreach (['company_stamp' => 'stamp', 'company_signature' => 'signature'] as $field => $kind) {
                $relative = sc_upload_image($_FILES[$field] ?? [], $kind);
                if ($relative !== '') sc_setting_set($conn, $field, $relative);
            }
            $_SESSION['sc_flash_success'] = 'تم حفظ اسم الشركة والختم والتوقيع.';
            sc_page_redirect(['tab' => 'templates']);
        }
        if ($action === 'set_default_template') {
            $templateId = max(0, (int)($_POST['template_id'] ?? 0));
            $conn->begin_transaction();
            $conn->query('UPDATE subscriber_contract_templates SET is_default=0');
            $stmt = $conn->prepare('UPDATE subscriber_contract_templates SET is_default=1 WHERE id=? AND is_active=1 LIMIT 1');
            $stmt->bind_param('i', $templateId);
            $stmt->execute();
            if ($stmt->affected_rows < 1) throw new RuntimeException('القالب المحدد غير موجود.');
            $stmt->close();
            $conn->commit();
            $_SESSION['sc_flash_success'] = 'تم تعيين القالب الافتراضي.';
            sc_page_redirect(['tab' => 'templates']);
        }
        if ($action === 'scan_template_fields') {
            $templateId=max(0,(int)($_POST['template_id']??0));
            $stmt=$conn->prepare('SELECT file_path FROM subscriber_contract_templates WHERE id=? AND is_active=1 LIMIT 1');
            $stmt->bind_param('i',$templateId);$stmt->execute();$templateRow=$stmt->get_result()->fetch_assoc();$stmt->close();
            if(!$templateRow) throw new RuntimeException('القالب المحدد غير موجود.');
            $suggestions=sc_scan_template_keywords((string)$templateRow['file_path']);
            $added=sc_seed_template_fields($conn,$templateId,$suggestions);
            $_SESSION['sc_flash_success']='اكتمل فحص القالب: '.count($suggestions).' اقتراح، أضيف منها '.$added.' اقتراح جديد.';
            sc_page_redirect(['tab'=>'templates','mapping_template_id'=>$templateId]);
        }
        if ($action === 'save_template_fields') {
            $templateId=max(0,(int)($_POST['template_id']??0));
            $keywords=(array)($_POST['keyword_text']??[]);$fields=(array)($_POST['subscriber_field']??[]);$catalog=sc_contract_field_catalog();$clean=[];
            foreach($keywords as $i=>$raw){$keyword=trim((string)$raw);$field=(string)($fields[$i]??'');if($keyword===''&&$field==='')continue;if($keyword===''||!isset($catalog[$field]))throw new RuntimeException('أكمل الكلمة المفتاحية وحقل المشترك في كل سطر.');$clean[$keyword]=$field;}
            if(!$clean) throw new RuntimeException('أضف مطابقة واحدة على الأقل قبل الحفظ.');
            $conn->begin_transaction();$stmt=$conn->prepare('DELETE FROM subscriber_contract_template_fields WHERE template_id=?');$stmt->bind_param('i',$templateId);$stmt->execute();$stmt->close();
            $stmt=$conn->prepare('INSERT INTO subscriber_contract_template_fields(template_id,keyword_text,subscriber_field,sort_order) VALUES(?,?,?,?)');$order=0;
            foreach($clean as $keyword=>$field){$order++;$stmt->bind_param('issi',$templateId,$keyword,$field,$order);if(!$stmt->execute())throw new RuntimeException('تعذر حفظ المطابقة.');}$stmt->close();$conn->commit();
            $_SESSION['sc_flash_success']='تم حفظ مطابقة كلمات القالب. ستُطبّق على العقود الجديدة، أما العقود المنشأة سابقاً فاستخدم لها زر «إعادة توليد بالمطابقات الحالية».';
            sc_page_redirect(['tab'=>'templates','mapping_template_id'=>$templateId]);
        }
        if ($action === 'delete_template') {
            $templateId = max(0, (int)($_POST['template_id'] ?? 0));
            $stmt = $conn->prepare('SELECT * FROM subscriber_contract_templates WHERE id=? AND is_active=1 LIMIT 1');
            if (!$stmt) throw new RuntimeException('تعذر تجهيز قراءة القالب.');
            $stmt->bind_param('i', $templateId);
            $stmt->execute();
            $templateRow = $stmt->get_result()->fetch_assoc();
            $stmt->close();
            if (!$templateRow) throw new RuntimeException('القالب المحدد غير موجود أو حُذف مسبقاً.');

            $activeResult = $conn->query('SELECT COUNT(*) total FROM subscriber_contract_templates WHERE is_active=1');
            $activeCount = $activeResult ? (int)($activeResult->fetch_assoc()['total'] ?? 0) : 0;
            if ($activeCount <= 1) throw new RuntimeException('لا يمكن حذف آخر قالب فعال. ارفع قالباً بديلاً أولاً.');

            $conn->begin_transaction();
            $stmt = $conn->prepare('UPDATE subscriber_contract_templates SET is_active=0,is_default=0 WHERE id=? AND is_active=1 LIMIT 1');
            if (!$stmt) throw new RuntimeException('تعذر تجهيز حذف القالب.');
            $stmt->bind_param('i', $templateId);
            if (!$stmt->execute() || $stmt->affected_rows !== 1) throw new RuntimeException('تعذر حذف القالب.');
            $stmt->close();

            if (!empty($templateRow['is_default'])) {
                $replacement = $conn->query('SELECT id FROM subscriber_contract_templates WHERE is_active=1 ORDER BY id DESC LIMIT 1');
                $replacementId = $replacement && ($replacementRow = $replacement->fetch_assoc()) ? (int)$replacementRow['id'] : 0;
                if ($replacementId <= 0) throw new RuntimeException('تعذر تعيين قالب افتراضي بديل.');
                $stmt = $conn->prepare('UPDATE subscriber_contract_templates SET is_default=1 WHERE id=? LIMIT 1');
                $stmt->bind_param('i', $replacementId);
                if (!$stmt->execute()) throw new RuntimeException('تعذر تعيين القالب الافتراضي البديل.');
                $stmt->close();
            }
            $conn->commit();

            $templatePath = trim((string)($templateRow['file_path'] ?? ''));
            if ($templatePath !== 'templates/default-subscriber-contract.docx' && str_starts_with(str_replace('\\', '/', $templatePath), 'templates/')) {
                $templateFile = sc_safe_storage_path($templatePath);
                if (is_file($templateFile)) @unlink($templateFile);
            }
            sc_event($conn, null, 0, 'TEMPLATE_DELETE', 'تم حذف قالب: ' . (string)$templateRow['name']);
            $_SESSION['sc_flash_success'] = 'تم حذف القالب وتعيين بديل افتراضي عند الحاجة.';
            sc_page_redirect(['tab' => 'templates']);
        }
        if ($action === 'regenerate_contract') {
            $sourceContractId = max(0, (int)($_POST['contract_id'] ?? 0));
            $sourceContract = sc_page_contract_row($conn, $sourceContractId);
            if (!$sourceContract) throw new RuntimeException('العقد المحدد غير موجود.');

            $actor = (string)($_SESSION['admin_username'] ?? $_SESSION['admin_user'] ?? 'admin');
            $result = sc_generate_subscriber_contract_record(
                $conn,
                (int)$sourceContract['subscriber_id'],
                'full',
                $actor,
                null
            );
            if (empty($result['ok'])) {
                throw new RuntimeException((string)($result['error'] ?? 'تعذرت إعادة توليد العقد.'));
            }

            $newContractId = (int)($result['contract_id'] ?? 0);
            sc_event(
                $conn,
                $newContractId,
                (int)$sourceContract['subscriber_id'],
                'REGENERATE',
                'أعيد توليد العقد من العقد #' . $sourceContractId . ' باستخدام القالب الافتراضي والمطابقات الحالية.'
            );
            $_SESSION['sc_flash_success'] = 'تم إنشاء نسخة جديدة من العقد باستخدام القالب الافتراضي والمفاتيح اليدوية المحفوظة حالياً. بقيت النسخة القديمة محفوظة في السجل.';
            sc_page_redirect([
                'subscriber_id' => (int)$sourceContract['subscriber_id'],
                'contract_id' => $newContractId,
            ], 'contracts');
        }
        if ($action === 'generate_contract') {
            $subscriberId = max(0, (int)($_POST['subscriber_id'] ?? 0));
            $templateId = max(0, (int)($_POST['template_id'] ?? 0));
            $stmt = $conn->prepare('SELECT s.*, COALESCE(sec.name, CAST(s.sector_id AS CHAR), \'\') sector_name FROM subscribers s LEFT JOIN sectors sec ON sec.id=s.sector_id WHERE s.id=? AND COALESCE(s.is_deleted,0)=0 LIMIT 1');
            if (!$stmt) throw new RuntimeException('تعذر قراءة بيانات المشترك.');
            $stmt->bind_param('i', $subscriberId);
            $stmt->execute();
            $subscriber = $stmt->get_result()->fetch_assoc();
            $stmt->close();
            if (!$subscriber) throw new RuntimeException('المشترك المحدد غير موجود.');
            $template = sc_resolve_contract_template($conn, $templateId);
            if (!$template) throw new RuntimeException('لا يوجد قالب عقد معتمد للتصدير.');
            $templateId = (int)$template['id'];

            $contractNumber = sc_contract_number($conn, $subscriberId);
            $title = trim((string)($_POST['contract_title'] ?? '')) ?: 'عقد تقديم خدمة إنترنت';
            $notes = trim((string)($_POST['contract_notes'] ?? ''));
            $companyName = sc_setting_get($conn, 'company_name', 'الشركة');
            $useStamp = !empty($_POST['include_stamp']) && sc_setting_get($conn, 'company_stamp') !== '';
            $useSignature = !empty($_POST['include_signature']) && sc_setting_get($conn, 'company_signature') !== '';
            $map = sc_subscriber_placeholders($subscriber, [
                'company_name' => $companyName,
                'contract_number' => $contractNumber,
                'contract_date' => date('Y-m-d'),
                'contract_title' => $title,
                'contract_notes' => $notes,
            ]);
            $templateFields = sc_template_field_rows($conn, $templateId);
            $exportCatalog = sc_template_export_catalog((string)$template['file_path'], $templateFields);
            $pageNumbers = trim((string)($_POST['page_numbers'] ?? ''));
            $pageScope = $pageNumbers !== '' ? 'pages:' . $pageNumbers : (string)($_POST['page_scope'] ?? 'all');
            $selectedPages = sc_contract_selected_pages($exportCatalog, $pageScope);
            $requiredFields = $selectedPages === null
                ? (array)$exportCatalog['all_required_fields']
                : (array)($exportCatalog['page_required_fields'][$selectedPages[0]] ?? []);
            $map = sc_apply_template_fields($map, $templateFields);
            $map['{{company_stamp}}'] = '';
            $map['{{company_signature}}'] = '';
            $images = [];
            if ($useStamp) $images['{{company_stamp}}'] = sc_setting_get($conn, 'company_stamp');
            if ($useSignature) $images['{{company_signature}}'] = sc_setting_get($conn, 'company_signature');
            $relative = 'generated/' . date('Y/m');
            $directory = sc_safe_storage_path($relative);
            if (!is_dir($directory) && !@mkdir($directory, 0770, true) && !is_dir($directory)) throw new RuntimeException('تعذر تجهيز مجلد العقود.');
            $outputRelative = $relative . '/contract-' . preg_replace('/[^A-Za-z0-9_-]+/', '-', $contractNumber) . '-' . bin2hex(random_bytes(4)) . '.docx';
            $verificationValues=[];
            foreach($requiredFields as $field){$value=trim((string)($map['{{'.(string)$field.'}}']??''));if($value!=='')$verificationValues[]=$value;}
            sc_generate_docx(
                (string)$template['file_path'],
                $outputRelative,
                $map,
                $images,
                array_values(array_unique($verificationValues)),
                false,
                $selectedPages
            );
            $filename = 'عقد-' . preg_replace('/[^\p{L}\p{N}._-]+/u', '-', trim((string)($subscriber['full_name'] ?? $subscriberId))) . '-' . $contractNumber . '.docx';
            $actor = (string)($_SESSION['admin_username'] ?? $_SESSION['admin_user'] ?? 'admin');
            $stampInt = $useStamp ? 1 : 0;
            $signatureInt = $useSignature ? 1 : 0;
            $stmt = $conn->prepare('INSERT INTO subscriber_contracts(subscriber_id,template_id,contract_number,title,custom_notes,generated_path,generated_filename,has_stamp,has_signature,created_by) VALUES(?,?,?,?,?,?,?,?,?,?)');
            if (!$stmt) throw new RuntimeException('تعذر إنشاء سجل العقد.');
            $stmt->bind_param('iisssssiis', $subscriberId, $templateId, $contractNumber, $title, $notes, $outputRelative, $filename, $stampInt, $signatureInt, $actor);
            if (!$stmt->execute()) throw new RuntimeException('تعذر إنشاء سجل العقد.');
            $contractId = (int)$stmt->insert_id;
            $stmt->close();
            $pageNote = $selectedPages === null ? 'العقد الكامل' : 'الصفحة ' . $selectedPages[0];
            sc_event($conn, $contractId, $subscriberId, 'GENERATE', 'تم إنشاء ' . $pageNote . ' من القالب ' . (string)$template['name']);
            $_SESSION['sc_flash_success'] = 'تم إنشاء عقد Word وتعبئته وفق خريطة القالب المحفوظة. نزّله من قسم العقود المنشأة.';
            sc_page_redirect(['subscriber_id' => $subscriberId, 'contract_id' => $contractId, 'panel' => 'contracts']);
        }
        if ($action === 'bulk_export_contracts') {
            if (sc_bulk_export_output_format((string)($_POST['output_format'] ?? 'docx')) === 'pdf') {
                @set_time_limit(0);
                $job = sc_bulk_export_start($conn, $_POST);
                while (($job['status'] ?? '') === 'processing') {
                    $job = sc_bulk_export_process_next($conn, (string)$job['token']);
                }
                if (($job['status'] ?? '') !== 'complete' || empty($job['download_token'])) {
                    throw new RuntimeException((string)($job['error'] ?? 'تعذر إكمال تصدير PDF الجماعي.'));
                }
                header('Location: subscriber_contracts.php?download_batch=' . rawurlencode((string)$job['download_token']));
                exit;
            }
            $templateId = max(0, (int)($_POST['template_id'] ?? 0));
            $scope = (string)($_POST['bulk_scope'] ?? 'selected');
            $legacyMode = (string)($_POST['export_mode'] ?? 'full');
            $dataFilter = sc_contract_export_filter((string)($_POST['data_filter'] ?? (!empty($_POST['exclude_incomplete']) ? 'complete' : 'all')));
            if (!in_array($legacyMode, ['full', 'changed'], true)) throw new RuntimeException('نمط التصدير غير صالح.');

            $ids = [];
            if ($scope === 'all') {
                $rs = $conn->query('SELECT id FROM subscribers WHERE COALESCE(is_deleted,0)=0 ORDER BY id');
                while ($rs && ($row = $rs->fetch_assoc())) $ids[] = (int)$row['id'];
            } else {
                foreach ((array)($_POST['subscriber_ids'] ?? []) as $subscriberId) {
                    $subscriberId = (int)$subscriberId;
                    if ($subscriberId > 0) $ids[$subscriberId] = $subscriberId;
                }
                $ids = array_values($ids);
            }
            if (!$ids) throw new RuntimeException('حدد مشتركاً واحداً على الأقل للتصدير.');

            $template = sc_resolve_contract_template($conn, $templateId);
            if (!$template) throw new RuntimeException('لا يوجد قالب عقد معتمد للتصدير.');
            $templateId = (int)$template['id'];

            $templateFields = sc_template_field_rows($conn, $templateId);
            $exportCatalog = sc_template_export_catalog((string)$template['file_path'], $templateFields);
            $pageNumbers = trim((string)($_POST['page_numbers'] ?? ''));
            $pageScope = $pageNumbers !== '' ? 'pages:' . $pageNumbers : (string)($_POST['page_scope'] ?? 'all');
            $selectedPages = sc_contract_selected_pages($exportCatalog, $pageScope);
            $filterRequiredFields = sc_contract_filter_required_fields($exportCatalog);
            $renderRequiredFields = sc_contract_render_required_fields($exportCatalog, $selectedPages);
            $companyName = sc_setting_get($conn, 'company_name', 'الشركة');
            $fieldLabels = sc_contract_field_catalog();

            $subscriberRowsById = [];
            foreach (array_chunk($ids, 500) as $idChunk) {
                $idSql = implode(',', array_map('intval', $idChunk));
                $rs = $conn->query(
                    "SELECT s.*,COALESCE(sec.name,CAST(s.sector_id AS CHAR),'') sector_name
                     FROM subscribers s
                     LEFT JOIN sectors sec ON sec.id=s.sector_id
                     WHERE s.id IN ($idSql) AND COALESCE(s.is_deleted,0)=0"
                );
                while ($rs && ($subscriber = $rs->fetch_assoc())) {
                    $subscriberRowsById[(int)$subscriber['id']] = $subscriber;
                }
            }
            $orderedSubscriberRows = [];
            foreach ($ids as $subscriberId) {
                if (isset($subscriberRowsById[$subscriberId])) {
                    $orderedSubscriberRows[] = $subscriberRowsById[$subscriberId];
                }
            }
            $partition = sc_filter_contract_export_rows(
                $orderedSubscriberRows,
                $filterRequiredFields,
                $dataFilter,
                $fieldLabels
            );
            $eligibleSubscribers = (array)$partition['eligible'];
            $excludedRows = $dataFilter === 'complete' ? (array)$partition['omitted'] : [];
            $eligibleCount = (int)$partition['eligible_count'];

            $maxExportCount = sc_contract_export_max_count();
            if ($eligibleCount > $maxExportCount) {
                throw new RuntimeException(
                    'العدد النهائي الصالح للتصدير ' . $eligibleCount
                    . ' مشتركاً، والحد الأعلى ' . $maxExportCount . ' بعد تطبيق فلتر البيانات.'
                );
            }
            if ($eligibleCount < 1) {
                throw new RuntimeException(
                    $excludedRows
                        ? 'استُبعد جميع المشتركين لأن بياناتهم لا تغطي مفاتيح القالب المطلوبة.'
                        : 'لم يتم العثور على مشتركين صالحين للتصدير.'
                );
            }

            $batchRelative = 'generated/batches/' . date('Ymd-His') . '-' . bin2hex(random_bytes(4));
            $batchDir = sc_safe_storage_path($batchRelative);
            if (!is_dir($batchDir) && !@mkdir($batchDir, 0770, true) && !is_dir($batchDir)) {
                throw new RuntimeException('تعذر تجهيز مجلد التصدير الجماعي.');
            }
            $zipRelative = $batchRelative . '/subscriber-contracts.zip';
            $zipPath = sc_safe_storage_path($zipRelative);
            $zip = new ZipArchive();
            if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
                throw new RuntimeException('تعذر إنشاء ملف ZIP.');
            }

            $created = 0;
            foreach ($eligibleSubscribers as $subscriber) {
                $subscriberId = (int)$subscriber['id'];
                $contractNumber = sc_contract_number($conn, $subscriberId);
                $title = 'عقد تقديم خدمة إنترنت';
                $map = sc_subscriber_placeholders($subscriber, [
                    'company_name' => $companyName,
                    'contract_number' => $contractNumber,
                    'contract_date' => date('Y-m-d'),
                    'contract_title' => $title,
                    'contract_notes' => '',
                ]);
                $map = sc_apply_template_fields($map, $templateFields);
                $map['{{company_stamp}}'] = '';
                $map['{{company_signature}}'] = '';
                $docRelative = $batchRelative . '/contract-' . $subscriberId . '-' . bin2hex(random_bytes(3)) . '.docx';
                $verificationValues = [];
                foreach ($renderRequiredFields as $field) {
                    $value = trim((string)($map['{{' . $field . '}}'] ?? ''));
                    if ($value !== '') $verificationValues[] = $value;
                }
                sc_generate_docx(
                    (string)$template['file_path'],
                    $docRelative,
                    $map,
                    [],
                    array_values(array_unique($verificationValues)),
                    $selectedPages === null && $legacyMode === 'changed',
                    $selectedPages
                );

                $name = 'عقد-' . preg_replace('/[^\p{L}\p{N}._-]+/u', '-', trim((string)($subscriber['full_name'] ?? $subscriberId))) . '-' . $contractNumber . '.docx';
                $zip->addFile(sc_safe_storage_path($docRelative), $name);
                $actor = (string)($_SESSION['admin_username'] ?? $_SESSION['admin_user'] ?? 'admin');
                $notes = '';
                $stmt = $conn->prepare('INSERT INTO subscriber_contracts(subscriber_id,template_id,contract_number,title,custom_notes,generated_path,generated_filename,created_by) VALUES(?,?,?,?,?,?,?,?)');
                $stmt->bind_param('iissssss', $subscriberId, $templateId, $contractNumber, $title, $notes, $docRelative, $name, $actor);
                $stmt->execute();
                $contractId = (int)$stmt->insert_id;
                $stmt->close();
                $pageNote = $selectedPages === null ? ($legacyMode === 'changed' ? 'الصفحات المعبأة فقط' : 'العقد الكامل') : 'الصفحة ' . $selectedPages[0];
                sc_event($conn, $contractId, $subscriberId, 'BULK_GENERATE', 'تصدير ' . $pageNote);
                $created++;
            }

            if ($excludedRows) {
                $stream = fopen('php://temp', 'w+');
                fwrite($stream, "\xEF\xBB\xBF");
                fputcsv($stream, ['رقم المشترك', 'اسم المشترك', 'المعلومات الناقصة']);
                foreach ($excludedRows as $row) {
                    fputcsv($stream, [$row['id'], $row['name'], implode('، ', $row['fields'])]);
                }
                rewind($stream);
                $zip->addFromString('العقود-غير-المكتملة.csv', (string)stream_get_contents($stream));
                fclose($stream);
            }
            $zip->close();
            if ($created < 1) {
                if (is_file($zipPath)) @unlink($zipPath);
                throw new RuntimeException(
                    $excludedRows
                        ? 'استُبعد جميع المشتركين لأن بياناتهم لا تغطي مفاتيح القالب المطلوبة.'
                        : 'لم يتم إنشاء أي عقد.'
                );
            }
            $token = bin2hex(random_bytes(16));
            $_SESSION['sc_batch_downloads'][$token] = ['path' => $zipRelative, 'created' => time()];
            header('Location: subscriber_contracts.php?download_batch=' . $token);
            exit;
        }
        if ($action === 'mark_printed') {
            $contractId = max(0, (int)($_POST['contract_id'] ?? 0));
            $row = sc_page_contract_row($conn, $contractId);
            if (!$row || !sc_mark_printed($conn, $contractId)) throw new RuntimeException('تعذر تسجيل عملية الطباعة.');
            $_SESSION['sc_flash_success'] = 'تم تسجيل الطباعة مع الوقت والتاريخ.';
            sc_page_redirect(['subscriber_id' => (int)$row['subscriber_id'], 'contract_id' => $contractId, 'panel' => 'contracts']);
        }
        if ($action === 'delete_contract') {
            $contractId = max(0, (int)($_POST['contract_id'] ?? 0));
            $row = sc_page_contract_row($conn, $contractId);
            if (!$row) throw new RuntimeException('العقد المحدد غير موجود أو حُذف مسبقاً.');

            $subscriberId = (int)$row['subscriber_id'];
            $generatedPath = trim((string)($row['generated_path'] ?? ''));
            $conn->begin_transaction();
            $stmt = $conn->prepare('DELETE FROM subscriber_contract_events WHERE contract_id=?');
            if (!$stmt) throw new RuntimeException('تعذر تجهيز حذف سجل أحداث العقد.');
            $stmt->bind_param('i', $contractId);
            if (!$stmt->execute()) throw new RuntimeException('تعذر حذف سجل أحداث العقد.');
            $stmt->close();
            $stmt = $conn->prepare('DELETE FROM subscriber_contracts WHERE id=? LIMIT 1');
            if (!$stmt) throw new RuntimeException('تعذر تجهيز حذف العقد.');
            $stmt->bind_param('i', $contractId);
            if (!$stmt->execute() || $stmt->affected_rows !== 1) throw new RuntimeException('تعذر حذف العقد.');
            $stmt->close();
            $conn->commit();

            if ($generatedPath !== '' && str_starts_with(str_replace('\\', '/', $generatedPath), 'generated/')) {
                $generatedFile = sc_safe_storage_path($generatedPath);
                if (is_file($generatedFile)) @unlink($generatedFile);
            }
            $_SESSION['sc_flash_success'] = 'تم حذف مهمة العقد وملف Word المرتبط بها.';
            sc_page_redirect(['subscriber_id' => $subscriberId, 'panel' => 'contracts']);
        }
        throw new RuntimeException('العملية المطلوبة غير معروفة.');
    } catch (Throwable $e) {
        try { $conn->rollback(); } catch (Throwable $ignore) {}
        $err = $e->getMessage();
    }
}

$companyName = sc_setting_get($conn, 'company_name', 'الشركة');
$stampPath = sc_setting_get($conn, 'company_stamp');
$signaturePath = sc_setting_get($conn, 'company_signature');
$templates = [];
$qTemplates = $conn->query('SELECT * FROM subscriber_contract_templates WHERE is_active=1 ORDER BY is_default DESC, id DESC');
if ($qTemplates) while ($row = $qTemplates->fetch_assoc()) $templates[] = $row;
$defaultTemplateId = $templates ? (int)$templates[0]['id'] : 0;
$bulkIds=[];
foreach(explode(',',(string)($_GET['bulk_ids']??'')) as $bulkId){$bulkId=(int)$bulkId;if($bulkId>0)$bulkIds[$bulkId]=$bulkId;}
$bulkIds=array_values($bulkIds);$bulkSubscribers=[];
if($bulkIds){
    $idSql=implode(',',array_map('intval',$bulkIds));
    $rs=$conn->query("SELECT s.*,COALESCE(sec.name,CAST(s.sector_id AS CHAR),'') sector_name FROM subscribers s LEFT JOIN sectors sec ON sec.id=s.sector_id WHERE s.id IN ($idSql) AND COALESCE(s.is_deleted,0)=0 ORDER BY s.full_name");
    while($rs&&($r=$rs->fetch_assoc()))$bulkSubscribers[]=$r;
}
$bulkAnalysisSubscribers = $bulkSubscribers;
if ($bulkIds) {
    $bulkAnalysisSubscribers = [];
    $rs = $conn->query("SELECT s.*,COALESCE(sec.name,CAST(s.sector_id AS CHAR),'') sector_name FROM subscribers s LEFT JOIN sectors sec ON sec.id=s.sector_id WHERE COALESCE(s.is_deleted,0)=0 ORDER BY s.id");
    while ($rs && ($r = $rs->fetch_assoc())) $bulkAnalysisSubscribers[] = $r;
}
$bulkAnalysisIds = [];
$bulkAnalysisNames = [];
foreach ($bulkAnalysisSubscribers as $bulkAnalysisSubscriber) {
    $analysisId = (int)$bulkAnalysisSubscriber['id'];
    $bulkAnalysisIds[] = $analysisId;
    $bulkAnalysisNames[(string)$analysisId] = trim((string)($bulkAnalysisSubscriber['full_name'] ?? '')) ?: ('مشترك #' . $analysisId);
}
$fieldCatalog = sc_contract_field_catalog();
$templateExportMeta = [];
foreach ($templates as $templateRow) {
    $templateId = (int)$templateRow['id'];
    try {
        $templateFields = sc_template_field_rows($conn, $templateId);
        $catalog = sc_template_export_catalog((string)$templateRow['file_path'], $templateFields);
        $requiredFields = sc_contract_filter_required_fields($catalog);
        $missingBySubscriber = [];
        foreach ($bulkAnalysisSubscribers as $bulkSubscriber) {
            $missingBySubscriber[(string)(int)$bulkSubscriber['id']] = sc_contract_missing_fields($bulkSubscriber, $requiredFields);
        }
        $templateExportMeta[(string)$templateId] = [
            'pageCount' => (int)$catalog['page_count'],
            'layoutPageCount' => (int)$catalog['layout_page_count'],
            'pageSelectable' => !empty($catalog['page_selectable']),
            'warning' => (string)$catalog['warning'],
            'required' => $requiredFields,
            'missing' => $missingBySubscriber,
        ];
    } catch (Throwable $templateError) {
        $templateExportMeta[(string)$templateId] = [
            'pageCount' => 1,
            'layoutPageCount' => 1,
            'pageSelectable' => false,
            'warning' => $templateError->getMessage(),
            'required' => [],
            'missing' => [],
        ];
    }
}
$mappingTemplateId = max(0, (int)($_GET['mapping_template_id'] ?? 0));
$mappingTemplate = null;
foreach ($templates as $templateRow) if ((int)$templateRow['id'] === $mappingTemplateId) { $mappingTemplate = $templateRow; break; }
$mappingRows = $mappingTemplate ? sc_template_field_rows($conn, $mappingTemplateId) : [];

$search = trim((string)($_GET['q'] ?? ''));
$selectedSubscriberId = max(0, (int)($_GET['subscriber_id'] ?? 0));
$subscriberRows = [];
$where = 'COALESCE(s.is_deleted,0)=0';
if ($search !== '') {
    $like = '%' . $search . '%';
    $idCondition = ctype_digit($search) ? ('s.id=' . (int)$search . ' OR ') : '';
    $stmt = $conn->prepare("SELECT s.id,s.full_name,s.phone,s.ppp_username,s.username FROM subscribers s WHERE $where AND ({$idCondition}s.full_name LIKE ? OR s.phone LIKE ? OR s.ppp_username LIKE ? OR s.username LIKE ?) ORDER BY s.id DESC LIMIT 12");
    $stmt->bind_param('ssss', $like, $like, $like, $like);
    $stmt->execute();
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) $subscriberRows[] = $row;
    $stmt->close();
} elseif ($selectedSubscriberId > 0) {
    $qSubs = $conn->query("SELECT s.id,s.full_name,s.phone,s.ppp_username,s.username FROM subscribers s WHERE $where AND s.id=" . $selectedSubscriberId . " LIMIT 1");
    if ($qSubs) while ($row = $qSubs->fetch_assoc()) $subscriberRows[] = $row;
}

$selectedSubscriber = null;
if ($selectedSubscriberId > 0) {
    $stmt = $conn->prepare('SELECT * FROM subscribers WHERE id=? AND COALESCE(is_deleted,0)=0 LIMIT 1');
    $stmt->bind_param('i', $selectedSubscriberId);
    $stmt->execute();
    $selectedSubscriber = $stmt->get_result()->fetch_assoc() ?: null;
    $stmt->close();
}

$contractRows = [];
$conditions = [];
if ($selectedSubscriberId > 0) $conditions[] = 'c.subscriber_id=' . $selectedSubscriberId;
if ($search !== '') {
    $esc = $conn->real_escape_string($search);
    $conditions[] = "(c.contract_number LIKE '%$esc%' OR s.full_name LIKE '%$esc%' OR s.phone LIKE '%$esc%')";
}
$sql = 'SELECT c.*, s.full_name, s.phone, t.name template_name, t.is_default template_is_default,
        (SELECT MAX(f.updated_at) FROM subscriber_contract_template_fields f WHERE f.template_id=c.template_id) mapping_updated_at
        FROM subscriber_contracts c
        JOIN subscribers s ON s.id=c.subscriber_id
        LEFT JOIN subscriber_contract_templates t ON t.id=c.template_id';
if ($conditions) $sql .= ' WHERE ' . implode(' AND ', $conditions);
$sql .= ' ORDER BY c.id DESC LIMIT 100';
$qContracts = $conn->query($sql);
if ($qContracts) while ($row = $qContracts->fetch_assoc()) $contractRows[] = $row;

$eventRows = [];
$qEvents = $conn->query('SELECT e.*, s.full_name FROM subscriber_contract_events e LEFT JOIN subscribers s ON s.id=e.subscriber_id ORDER BY e.id DESC LIMIT 80');
if ($qEvents) while ($row = $qEvents->fetch_assoc()) $eventRows[] = $row;

$defaultPanel = $bulkSubscribers ? 'bulk-export' : 'subscribers';
if ($requestPanelHint === '' && isset($_GET['contract_id'])) $requestPanelHint = 'contracts';
if ($requestPanelHint === '' && $mappingTemplate) $requestPanelHint = 'templates';
$activePanel = sc_page_panel($requestPanelHint, $defaultPanel);
if ($activePanel === 'bulk-export' && !$bulkSubscribers) $activePanel = 'subscribers';
$panelBaseParams = [];
foreach (['q', 'subscriber_id', 'bulk_ids', 'mapping_template_id'] as $panelParam) {
    if (isset($_GET[$panelParam]) && trim((string)$_GET[$panelParam]) !== '') {
        $panelBaseParams[$panelParam] = (string)$_GET[$panelParam];
    }
}
if ($isAndroid) $panelBaseParams['ua_android'] = 1;
$panelUrl = static function (string $panel) use ($panelBaseParams): string {
    $params = $panelBaseParams;
    $params['panel'] = sc_page_panel($panel);
    return '?' . http_build_query($params) . '#' . rawurlencode($params['panel']);
};

$page_title = 'عقود المشتركين';
$UA_FORCE_DESIGN_V2 = true;
$UA_PAGE_CSS = $isAndroid
    ? ['assets/css/android_subscriber_contracts.css']
    : ['assets/css/android_subscriber_contracts.css', 'assets/css/subscriber_contracts.css'];
include __DIR__ . '/header.php';
?>
<div class="content-wrapper android-contracts subscriber-contracts <?= $isAndroid ? 'is-android' : 'is-desktop' ?>" id="page-top" data-android-contracts data-active-panel="<?= h($activePanel) ?>">
  <main class="sct-main <?= $selectedSubscriber ? 'has-editor' : 'no-editor' ?>">
    <header class="sct-heading">
      <div><span>Word Contract Center</span><h1>عقود المشتركين</h1><p>قوالب Word، تعبئة تلقائية، ختم وتوقيع، وسجل طباعة موثق.</p></div>
      <a href="subscribers.php"><i class="fa fa-arrow-right"></i><b>العودة إلى قائمة المشتركين</b></a>
    </header>

    <?php if ($msg !== ''): ?><div class="alert alert-success sct-alert is-success"><i class="fa fa-check-circle"></i><span><?= h($msg) ?></span></div><?php endif; ?>
    <?php if ($err !== ''): ?><div class="alert alert-danger sct-alert is-error"><i class="fa fa-exclamation-circle"></i><span><?= h($err) ?></span></div><?php endif; ?>

    <nav class="sct-tabs" aria-label="أقسام إدارة العقود">
      <a href="<?= h($panelUrl('subscribers')) ?>" data-sct-tab="subscribers" aria-controls="sct-panel-subscribers" aria-selected="<?= $activePanel==='subscribers'?'true':'false' ?>" class="<?= $activePanel==='subscribers'?'is-active':'' ?>"><i class="fa fa-search"></i><span>المشتركون</span></a>
      <a href="<?= h($panelUrl('contracts')) ?>" data-sct-tab="contracts" aria-controls="contracts" aria-selected="<?= $activePanel==='contracts'?'true':'false' ?>" class="<?= $activePanel==='contracts'?'is-active':'' ?>"><i class="fa fa-file-word-o"></i><span>العقود المنشأة</span><b><?= count($contractRows) ?></b></a>
      <a href="<?= h($panelUrl('templates')) ?>" data-sct-tab="templates" aria-controls="templates" aria-selected="<?= $activePanel==='templates'?'true':'false' ?>" class="<?= $activePanel==='templates'?'is-active':'' ?>"><i class="fa fa-cog"></i><span>القوالب والمطابقة</span><b><?= count($templates) ?></b></a>
      <a href="<?= h($panelUrl('history')) ?>" data-sct-tab="history" aria-controls="history" aria-selected="<?= $activePanel==='history'?'true':'false' ?>" class="<?= $activePanel==='history'?'is-active':'' ?>"><i class="fa fa-history"></i><span>سجل العمليات</span><b><?= count($eventRows) ?></b></a>
      <?php if($bulkSubscribers): ?><a href="<?= h($panelUrl('bulk-export')) ?>" data-sct-tab="bulk-export" aria-controls="bulk-export" aria-selected="<?= $activePanel==='bulk-export'?'true':'false' ?>" class="<?= $activePanel==='bulk-export'?'is-active':'' ?>"><i class="fa fa-print"></i><span>الطباعة الجماعية</span><b><?= count($bulkSubscribers) ?></b></a><?php endif; ?>
    </nav>

    <div class="sct-panels">
    <?php if($bulkSubscribers): ?>
    <section class="sct-card sct-bulk-export" id="bulk-export" data-sct-panel="bulk-export" role="tabpanel">
      <div class="sct-card-head"><div><span>Bulk Contracts</span><h2>تصدير العقود الجماعي</h2></div><i class="fa fa-file-archive-o"></i></div>
      <form method="post" class="sct-bulk-export-form" data-bulk-export-form data-ua-android-native-layout><?php ua_csrf_field(); ?><input type="hidden" name="action" value="bulk_export_contracts">
        <?php foreach($bulkSubscribers as $bulkSubscriber): ?><input type="hidden" name="subscriber_ids[]" value="<?= (int)$bulkSubscriber['id'] ?>"><?php endforeach; ?>
        <div class="sct-bulk-controlbar" aria-label="تسلسل إعداد تصدير العقود">
          <div class="sct-bulk-sequence">
            <label class="sct-bulk-step" data-step="1"><span>نطاق المشتركين</span><select class="js-contract-bulk-scope" name="bulk_scope" data-export-lock required><option value="all" selected>جميع صفحات القائمة (<?= count($bulkAnalysisSubscribers) ?>)</option><option value="selected">المحددون فقط (<?= count($bulkSubscribers) ?>)</option></select></label>
            <label class="sct-bulk-step" data-step="2"><span>قالب العقد</span><select class="js-contract-template" name="template_id" data-export-lock required><?php foreach($templates as $template): ?><option value="<?= (int)$template['id'] ?>" <?= (int)$template['id']===$defaultTemplateId?'selected':'' ?>><?= h((string)$template['name']) ?></option><?php endforeach; ?></select></label>
            <div class="sct-bulk-step sct-bulk-pages" data-step="3"><span>صفحات العقد</span><div><select class="js-contract-page-scope" name="page_scope" data-export-lock required aria-label="نطاق صفحات العقد"><option value="all">العقد كاملاً</option></select><input name="page_numbers" data-export-lock inputmode="numeric" pattern="[0-9,\- ]*" placeholder="1 - 2 - 5" aria-label="أرقام صفحات محددة" title="اتركه فارغاً لاستخدام نطاق الصفحات المختار"></div></div>
            <label class="sct-bulk-step" data-step="4"><span>فلتر المعلومات</span><select class="js-contract-data-filter" name="data_filter" data-export-lock required><option value="all">الجميع</option><option value="complete">مكتملة المعلومات فقط</option><option value="incomplete">ناقصة المعلومات فقط</option></select></label>
          </div>
          <div class="sct-bulk-actions" aria-label="خيارات تصدير العقود">
            <button type="submit" name="output_format" value="docx" class="sct-bulk-icon sct-word-icon" data-export-format="docx" data-export-lock title="توليد وتنزيل عقود Word" aria-label="توليد وتنزيل عقود Word"><i class="fa fa-file-word-o"></i><span class="sct-sr-only">توليد وتنزيل عقود Word</span></button>
            <button type="submit" name="output_format" value="pdf" class="sct-bulk-icon sct-pdf-icon" data-export-format="pdf" data-export-lock title="تصدير PDF جماعي موحد" aria-label="تصدير PDF جماعي موحد"><i class="fa fa-file-pdf-o"></i><span class="sct-sr-only">تصدير PDF جماعي موحد</span></button>
          </div>
        </div>
        <details class="sct-bulk-selection"><summary><span><i class="fa fa-users"></i> المشتركـون المحددون</span><b><?= count($bulkSubscribers) ?></b></summary><div class="sct-bulk-people"><?php foreach($bulkSubscribers as $bulkSubscriber): ?><span data-subscriber-id="<?= (int)$bulkSubscriber['id'] ?>"><i class="fa fa-user"></i><?= h((string)($bulkSubscriber['full_name']?:$bulkSubscriber['ppp_username']?:$bulkSubscriber['username'])) ?><small>#<?= (int)$bulkSubscriber['id'] ?></small></span><?php endforeach; ?></div></details>
        <section class="sct-export-insight" data-contract-export-insight>
          <div><span>المفاتيح المطلوبة</span><strong data-required-count>0</strong></div>
          <div><span>بيانات مكتملة</span><strong data-complete-count><?= count($bulkSubscribers) ?></strong></div>
          <div><span>بيانات ناقصة</span><strong data-incomplete-count>0</strong></div>
          <div><span>العدد النهائي للتصدير</span><strong data-export-count><?= count($bulkSubscribers) ?></strong></div>
          <p data-export-result>سيتم تصدير جميع المشتركين المحددين.</p>
          <p class="is-warning" data-page-warning hidden></p>
          <details data-incomplete-details hidden><summary>عرض المشتركين ذوي البيانات الناقصة</summary><ul data-incomplete-list></ul></details>
        </section>
        <p class="sct-hint">يُطبّق فلتر اكتمال البيانات وفق جميع مفاتيح القالب في كل صفحاته، بينما يحدد الملف المصدر الصفحات التي ستُصدّر فقط.</p>
        <section class="sct-export-progress" data-export-progress hidden aria-live="polite">
          <header><span><i class="fa fa-cog fa-spin" data-progress-icon></i><b data-progress-state>تجهيز مهمة التصدير</b></span><strong data-progress-percent>0%</strong></header>
          <div class="sct-progress-track"><i data-progress-bar></i></div>
          <footer><span data-progress-count>0 من 0</span><small>يمكنك متابعة العمل بعد اكتمال التنزيل.</small></footer>
        </section>
      </form>
    </section>
    <?php endif; ?>

    <div class="sct-workspace" id="sct-panel-subscribers" data-sct-panel="subscribers" role="tabpanel">
    <section class="sct-card" id="subscribers">
      <div class="sct-card-head"><div><span>اختيار المشترك</span><h2>البحث في قائمة المشتركين</h2></div><i class="fa fa-user"></i></div>
      <form class="sct-search" method="get"><?php if($isAndroid): ?><input type="hidden" name="ua_android" value="1"><?php endif; ?><?php if($bulkIds): ?><input type="hidden" name="bulk_ids" value="<?= h(implode(',', $bulkIds)) ?>"><?php endif; ?><input type="hidden" name="panel" value="subscribers"><input type="search" name="q" data-ua-subscriber-search value="<?= h($search) ?>" placeholder="ID، الاسم، الهاتف، أو حساب PPPoE"><button><i class="fa fa-search"></i><span>بحث</span></button></form>
      <div class="sct-subscriber-list">
        <?php foreach ($subscriberRows as $sub): $sid=(int)$sub['id']; $ppp=trim((string)($sub['ppp_username'] ?: $sub['username'])); ?>
          <a class="<?= $selectedSubscriberId===$sid?'is-selected':'' ?>" href="?<?= h($platformQuery) ?>panel=subscribers&amp;subscriber_id=<?= $sid ?>#subscribers"><span><i class="fa fa-user"></i></span><div><h3><?= h((string)($sub['full_name'] ?: ('مشترك #'.$sid))) ?></h3><p>#<?= $sid ?> · <?= h($ppp) ?> · <?= h((string)$sub['phone']) ?></p></div><i class="fa fa-chevron-left"></i></a>
        <?php endforeach; ?>
        <?php if (!$subscriberRows && $search === ''): ?><p class="sct-search-empty"><i class="fa fa-search"></i><span>أدخل اسم المشترك أو هاتفه أو حساب PPPoE لعرضه.</span></p><?php endif; ?>
        <?php if (!$subscriberRows && $search !== ''): ?><p class="sct-search-empty is-no-result"><i class="fa fa-user-times"></i><span>لا يوجد مشترك مطابق لعبارة البحث.</span></p><?php endif; ?>
      </div>
    </section>

    <?php if ($selectedSubscriber): ?>
    <section class="sct-card sct-editor" id="editor">
      <div class="sct-card-head"><div><span>تحرير العقد</span><h2><?= h((string)($selectedSubscriber['full_name'] ?: ('مشترك #'.$selectedSubscriberId))) ?></h2></div><b>#<?= $selectedSubscriberId ?></b></div>
      <form method="post" data-ua-android-native-layout>
        <?php ua_csrf_field(); ?><input type="hidden" name="action" value="generate_contract"><input type="hidden" name="subscriber_id" value="<?= $selectedSubscriberId ?>">
        <div class="sct-editor-source">
          <label><span>قالب Word</span><select class="js-contract-template" name="template_id" required><?php foreach($templates as $template): ?><option value="<?= (int)$template['id'] ?>" <?= (int)$template['id']===$defaultTemplateId?'selected':'' ?>><?= h((string)$template['name']) ?><?= !empty($template['is_default'])?' - افتراضي':'' ?></option><?php endforeach; ?></select></label>
          <label><span>الملف المصدر</span><select class="js-contract-page-scope" name="page_scope" required><option value="all">تصدير كامل — جميع الصفحات</option></select></label>
          <label><span>أرقام صفحات محددة</span><input name="page_numbers" inputmode="numeric" pattern="[0-9,\- ]*" placeholder="مثال: 1 - 2 - 5"><small>اتركه فارغاً لاستخدام الخيار أعلاه.</small></label>
        </div>
        <p class="sct-page-note" data-page-warning hidden></p>
        <label><span>عنوان العقد</span><input name="contract_title" value="عقد تقديم خدمة إنترنت"></label>
        <label><span>تعديلات وملاحظات خاصة</span><textarea name="contract_notes" rows="5" placeholder="أي شروط أو ملاحظات إضافية تخص هذا المشترك..."></textarea></label>
        <div class="sct-checks"><label><input type="checkbox" name="include_stamp" value="1" <?= $stampPath!==''?'checked disabled':'' ?>><span>إدراج الختم <?= $stampPath===''?'(ارفعه من القوالب)':'المحفوظ' ?></span><?php if($stampPath!==''): ?><input type="hidden" name="include_stamp" value="1"><?php endif; ?></label><label><input type="checkbox" name="include_signature" value="1" <?= $signaturePath!==''?'checked disabled':'' ?>><span>إدراج التوقيع <?= $signaturePath===''?'(ارفعه من القوالب)':'المحفوظ' ?></span><?php if($signaturePath!==''): ?><input type="hidden" name="include_signature" value="1"><?php endif; ?></label></div>
        <div class="sct-data-preview"><div><span>PPPoE</span><strong dir="ltr"><?= h((string)($selectedSubscriber['ppp_username'] ?? $selectedSubscriber['username'] ?? '')) ?></strong></div><div><span>الهاتف</span><strong dir="ltr"><?= h((string)($selectedSubscriber['phone'] ?? '')) ?></strong></div><div><span>نوع الوثيقة</span><strong><?= h((string)($selectedSubscriber['document_type'] ?? '')) ?></strong></div><div><span>رقم الوثيقة</span><strong dir="ltr"><?= h((string)($selectedSubscriber['document_number'] ?? '')) ?></strong></div><div><span>الباقة</span><strong><?= h((string)($selectedSubscriber['package_name'] ?? $selectedSubscriber['package'] ?? '')) ?></strong></div><div><span>السرعة</span><strong><?= h((string)($selectedSubscriber['speed_name'] ?? $selectedSubscriber['speed'] ?? '')) ?></strong></div></div>
        <div class="sct-fill-status" aria-label="آلية مطابقة وتعبئة القالب">
          <span><i class="fa fa-file-word-o"></i><b>فحص القالب</b></span>
          <span><i class="fa fa-exchange"></i><b>مطابقة المفاتيح</b></span>
          <span><i class="fa fa-user"></i><b>تعبئة بيانات المشترك</b></span>
        </div>
        <button class="sct-primary"><i class="fa fa-magic"></i><span>مطابقة القالب وتعبئته وإنشاء Word</span></button>
      </form>
    </section>
    <?php endif; ?>
    </div>

    <section class="sct-card" id="contracts" data-sct-panel="contracts" role="tabpanel">
      <div class="sct-card-head"><div><span>حالة الطباعة</span><h2>العقود المنشأة</h2></div><b><?= count($contractRows) ?></b></div>
      <div class="sct-contract-list">
        <?php foreach ($contractRows as $contract): $printed=(int)$contract['printed_count']>0; $mappingChanged=!empty($contract['mapping_updated_at']) && (string)$contract['mapping_updated_at'] > (string)$contract['created_at']; $usesOldTemplate=empty($contract['template_is_default']); $needsRegeneration=$mappingChanged || $usesOldTemplate; ?>
          <article>
            <header><div><span><?= h((string)$contract['contract_number']) ?></span><h3><?= h((string)($contract['full_name'] ?: ('مشترك #'.$contract['subscriber_id']))) ?></h3></div><b class="<?= $printed?'is-printed':'is-pending' ?>"><?= $printed?'تمت الطباعة':'لم يطبع' ?></b></header>
            <div class="sct-contract-meta"><span><i class="fa fa-file-word-o"></i><?= h((string)($contract['template_name'] ?: 'قالب')) ?></span><span><i class="fa fa-clock-o"></i><?= h((string)$contract['created_at']) ?></span><?php if($printed): ?><span><i class="fa fa-print"></i><?= (int)$contract['printed_count'] ?> · <?= h((string)$contract['last_printed_at']) ?></span><?php endif; ?></div>
            <?php if($needsRegeneration): ?><p class="sct-contract-stale"><i class="fa fa-info-circle"></i><span>هذه نسخة سابقة للمطابقات أو للقالب الافتراضي الحالي. أعد توليدها لتطبيق المفاتيح اليدوية الجديدة.</span></p><?php endif; ?>
            <footer>
              <button type="button" data-ua-print-contract data-url="?<?= h($platformQuery) ?>download_contract=<?= (int)$contract['id'] ?>" data-contract-id="<?= (int)$contract['id'] ?>" data-file-name="<?= h((string)($contract['generated_filename'] ?: ('contract-'.$contract['id'].'.docx'))) ?>"><i class="fa fa-print"></i><span>طباعة مباشرة</span></button>
              <a href="?<?= h($platformQuery) ?>download_contract=<?= (int)$contract['id'] ?>"><i class="fa fa-download"></i><span>تنزيل العقد المعبأ</span></a>
              <form method="post" onsubmit="return confirm('إنشاء نسخة جديدة باستخدام القالب الافتراضي والمطابقات المحفوظة حالياً؟ ستبقى النسخة القديمة محفوظة.')"><?php ua_csrf_field(); ?><input type="hidden" name="action" value="regenerate_contract"><input type="hidden" name="contract_id" value="<?= (int)$contract['id'] ?>"><button><i class="fa fa-refresh"></i><span>إعادة توليد بالمطابقات الحالية</span></button></form>
              <form method="post" onsubmit="return confirm('تأكيد أن العقد تمت طباعته فعلياً؟')"><?php ua_csrf_field(); ?><input type="hidden" name="action" value="mark_printed"><input type="hidden" name="contract_id" value="<?= (int)$contract['id'] ?>"><button><i class="fa fa-print"></i><span>تمت الطباعة</span></button></form>
              <form method="post" class="sct-delete-contract" onsubmit="return confirm('سيتم حذف مهمة العقد وملف Word المولد نهائياً. هل تريد المتابعة؟')"><?php ua_csrf_field(); ?><input type="hidden" name="action" value="delete_contract"><input type="hidden" name="contract_id" value="<?= (int)$contract['id'] ?>"><button><i class="fa fa-trash"></i><span>حذف المهمة</span></button></form>
            </footer>
          </article>
        <?php endforeach; ?>
        <?php if(!$contractRows): ?><p class="sct-empty">لا توجد عقود منشأة بعد.</p><?php endif; ?>
      </div>
    </section>

    <section class="sct-card" id="templates" data-sct-panel="templates" role="tabpanel">
      <div class="sct-card-head"><div><span>Word Templates</span><h2>القوالب والختم والتوقيع</h2></div><i class="fa fa-cog"></i></div>
      <details class="sct-details" <?= (($_GET['tab']??'')==='templates')?'open':'' ?>><summary><span><i class="fa fa-building"></i><b>هوية الشركة</b></span><i class="fa fa-angle-down"></i></summary><form method="post" enctype="multipart/form-data" data-ua-android-native-layout><?php ua_csrf_field(); ?><input type="hidden" name="action" value="save_branding"><label><span>اسم الشركة</span><input name="company_name" value="<?= h($companyName) ?>"></label><label><span>صورة الختم PNG/JPG</span><input type="file" name="company_stamp" accept="image/png,image/jpeg"></label><label><span>صورة التوقيع PNG/JPG</span><input type="file" name="company_signature" accept="image/png,image/jpeg"></label><button class="sct-primary"><i class="fa fa-save"></i><span>حفظ الهوية</span></button></form></details>
      <details class="sct-details"><summary><span><i class="fa fa-upload"></i><b>رفع قالب Word جديد</b></span><i class="fa fa-angle-down"></i></summary><form method="post" enctype="multipart/form-data" data-ua-android-native-layout><?php ua_csrf_field(); ?><input type="hidden" name="action" value="upload_template"><label><span>اسم القالب</span><input name="template_name" placeholder="مثال: عقد الاشتراك السنوي"></label><label><span>ملف DOCX</span><input type="file" name="template_docx" accept=".docx,application/vnd.openxmlformats-officedocument.wordprocessingml.document" required></label><label class="sct-toggle"><input type="checkbox" name="is_default" value="1"><span>جعله القالب الافتراضي</span></label><p class="sct-hint">بعد الرفع يُفحص ملف Word وتظهر الكلمات المقترحة لتعديلها وربط كل واحدة بحقل من بيانات المشترك قبل التوليد.</p><button class="sct-primary"><i class="fa fa-upload"></i><span>رفع القالب وفحصه</span></button></form></details>
      <div class="sct-template-list">
        <?php foreach($templates as $template): ?>
          <article>
            <div><span><?= !empty($template['is_default'])?'القالب الافتراضي':'قالب Word' ?></span><h3><?= h((string)$template['name']) ?></h3><p><?= h((string)$template['original_filename']) ?></p></div>
            <footer>
              <a href="?<?= h($platformQuery) ?>download_template=<?= (int)$template['id'] ?>"><i class="fa fa-download"></i> تنزيل القالب الأصلي</a>
              <a href="?<?= h($platformQuery) ?>panel=templates&amp;mapping_template_id=<?= (int)$template['id'] ?>#template-mapping"><i class="fa fa-exchange"></i> مطابقة البيانات</a>
              <?php if(empty($template['is_default'])): ?><form method="post"><?php ua_csrf_field(); ?><input type="hidden" name="action" value="set_default_template"><input type="hidden" name="template_id" value="<?= (int)$template['id'] ?>"><button><i class="fa fa-check"></i> اعتماد</button></form><?php endif; ?>
              <form method="post" class="sct-delete-template" onsubmit="return confirm('سيتم حذف القالب من قائمة القوالب. هل تريد المتابعة؟')"><?php ua_csrf_field(); ?><input type="hidden" name="action" value="delete_template"><input type="hidden" name="template_id" value="<?= (int)$template['id'] ?>"><button><i class="fa fa-trash"></i> حذف القالب</button></form>
            </footer>
          </article>
        <?php endforeach; ?>
      </div>
      <?php if($mappingTemplate): ?>
      <section class="sct-mapping" id="template-mapping">
        <header><div><span>Keyword Mapping</span><h3>مطابقة كلمات «<?= h((string)$mappingTemplate['name']) ?>»</h3><p>عدّل الكلمة كما تظهر حرفياً في Word، ثم اختر معلومة المشترك التي ستوضع مقابلها.</p></div>
          <form method="post"><?php ua_csrf_field(); ?><input type="hidden" name="action" value="scan_template_fields"><input type="hidden" name="template_id" value="<?= $mappingTemplateId ?>"><button><i class="fa fa-search"></i> إعادة فحص القالب</button></form>
        </header>
        <form method="post" class="sct-mapping-form" id="templateMappingForm"><?php ua_csrf_field(); ?><input type="hidden" name="action" value="save_template_fields"><input type="hidden" name="template_id" value="<?= $mappingTemplateId ?>">
          <div class="sct-mapping-labels"><span>الكلمة داخل ملف Word</span><span>المعلومة المقابلة من بيانات المشترك</span><span></span></div>
          <div id="mappingRows">
          <?php foreach($mappingRows as $row): ?><div class="sct-mapping-row"><input name="keyword_text[]" value="<?= h((string)$row['keyword_text']) ?>" required><select name="subscriber_field[]" required><?php foreach($fieldCatalog as $field=>$label): ?><option value="<?= h($field) ?>" <?= $field===$row['subscriber_field']?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select><button type="button" class="sct-remove-row" title="حذف السطر"><i class="fa fa-times"></i></button></div><?php endforeach; ?>
          </div>
          <?php if(!$mappingRows): ?><p class="sct-mapping-empty">لم تُحفظ اقتراحات بعد. اضغط «إعادة فحص القالب» أو أضف كلمة يدوياً.</p><?php endif; ?>
          <footer><button type="button" id="addMappingRow"><i class="fa fa-plus"></i> اقتراح كلمة يدوياً</button><button class="sct-primary"><i class="fa fa-save"></i> حفظ المطابقة</button></footer>
        </form>
        <template id="mappingRowTemplate"><div class="sct-mapping-row"><input name="keyword_text[]" placeholder="مثال: اسم المشترك:" required><select name="subscriber_field[]" required><?php foreach($fieldCatalog as $field=>$label): ?><option value="<?= h($field) ?>"><?= h($label) ?></option><?php endforeach; ?></select><button type="button" class="sct-remove-row" title="حذف السطر"><i class="fa fa-times"></i></button></div></template>
      </section>
      <?php endif; ?>
    </section>

    <section class="sct-card" id="history" data-sct-panel="history" role="tabpanel">
      <div class="sct-card-head"><div><span>Audit Log</span><h2>سجل العقود والطباعة</h2></div><i class="fa fa-history"></i></div>
      <div class="sct-history"><?php foreach($eventRows as $event): ?><article><span><i class="fa <?= $event['event_type']==='PRINT'?'fa-print':($event['event_type']==='DOWNLOAD'?'fa-download':'fa-file-text-o') ?>"></i></span><div><h3><?= h((string)($event['full_name'] ?: $event['event_type'])) ?></h3><p><?= h((string)$event['event_note']) ?></p><small><?= h((string)$event['actor']) ?> · <?= h((string)$event['created_at']) ?></small></div></article><?php endforeach; ?><?php if(!$eventRows): ?><p class="sct-empty">لا توجد أحداث مسجلة بعد.</p><?php endif; ?></div>
    </section>
    </div>
  </main>
</div>
<script id="contractExportMeta" type="application/json"><?= json_encode(
    [
        'templates' => $templateExportMeta,
        'labels' => $fieldCatalog,
        'allSubscriberIds' => $bulkAnalysisIds,
        'subscriberNames' => $bulkAnalysisNames,
        'maxExportCount' => sc_contract_export_max_count(),
    ],
    JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT
) ?></script>
<script>
(function(){
  const source=document.getElementById('contractExportMeta');
  if(!source) return;
  let payload={templates:{},labels:{}};
  try{payload=JSON.parse(source.textContent||'{}');}catch(_error){return;}

  function pageOption(value,label){
    const option=document.createElement('option');
    option.value=value;
    option.textContent=label;
    return option;
  }
  function subscriberName(form,id){
    const node=form.querySelector('.sct-bulk-people [data-subscriber-id="'+String(id).replace(/"/g,'\\"')+'"]');
    if(!node) return (payload.subscriberNames||{})[id]||('مشترك #'+id);
    const copy=node.cloneNode(true);
    copy.querySelectorAll('i,small').forEach(function(child){child.remove();});
    return copy.textContent.trim()||('مشترك #'+id);
  }
  function updateInsight(form,meta){
    const insight=form.querySelector('[data-contract-export-insight]');
    if(!insight) return;
    const scope=form.querySelector('.js-contract-page-scope').value||'all';
    const required=Array.isArray(meta.required)?meta.required:[];
    const bulkScopeControl=form.querySelector('.js-contract-bulk-scope');
    const bulkScope=bulkScopeControl?bulkScopeControl.value:'selected';
    const selectedIds=Array.from(form.querySelectorAll('input[name="subscriber_ids[]"]')).map(function(input){return input.value;});
    const ids=bulkScope==='all'
      ? (payload.allSubscriberIds||[]).map(function(id){return String(id);})
      : selectedIds;
    const incomplete=[];
    ids.forEach(function(id){
      const fields=((meta.missing||{})[id])||[];
      if(fields.length) incomplete.push({id:id,fields:fields});
    });
    const complete=Math.max(0,ids.length-incomplete.length);
    insight.querySelector('[data-required-count]').textContent=String(required.length);
    insight.querySelector('[data-complete-count]').textContent=String(complete);
    insight.querySelector('[data-incomplete-count]').textContent=String(incomplete.length);

    const filterControl=form.querySelector('.js-contract-data-filter');
    const dataFilter=filterControl?filterControl.value:'all';
    const finalCount=dataFilter==='complete'?complete:(dataFilter==='incomplete'?incomplete.length:ids.length);
    insight.querySelector('[data-export-count]').textContent=String(finalCount);
    const result=insight.querySelector('[data-export-result]');
    const submitButtons=Array.from(form.querySelectorAll('[data-export-format]'));
    const maxExportCount=Math.max(1,Number(payload.maxExportCount||1000));
    const overLimit=finalCount>maxExportCount;
    const emptyExport=finalCount<1;
    submitButtons.forEach(function(button){button.disabled=overLimit||emptyExport;});
    result.classList.toggle('is-warning',overLimit||emptyExport);
    result.classList.toggle('is-filtered',dataFilter!=='all'&&!overLimit&&!emptyExport);
    if(overLimit){
      result.textContent='العدد النهائي للتصدير '+finalCount+' ويتجاوز الحد الأعلى '+maxExportCount+' مشترك. قلّل الاختيار أو اختر فلتر بيانات آخر.';
    }else if(emptyExport){
      result.textContent='لا توجد عقود مطابقة لفلتر البيانات المحدد.';
    }else if(dataFilter==='complete'){
      result.textContent='سيتم تصدير '+complete+' عقداً كامل المعلومات وفق جميع مفاتيح القالب.';
    }else if(dataFilter==='incomplete'){
      result.textContent='سيتم تصدير '+incomplete.length+' من العقود غير مكتملة المعلومات مع إبقاء تفاصيل النواقص ظاهرة للمراجعة.';
    }else if(incomplete.length){
      result.textContent='سيتم تصدير جميع العقود: '+complete+' كاملة و'+incomplete.length+' غير مكتملة.';
    }else{
      result.textContent=required.length
        ? 'جميع المشتركين المحددين مكتملون وفق جميع مفاتيح القالب.'
        : 'لم يكتشف القالب مفاتيح بيانات مشترك إلزامية؛ لن يُستبعد أحد.';
    }

    const details=insight.querySelector('[data-incomplete-details]');
    const list=insight.querySelector('[data-incomplete-list]');
    list.replaceChildren();
    incomplete.forEach(function(item){
      const li=document.createElement('li');
      const labels=item.fields.map(function(field){return (payload.labels||{})[field]||field;});
      const strong=document.createElement('strong');
      strong.textContent=subscriberName(form,item.id);
      const span=document.createElement('span');
      span.textContent=labels.join('، ');
      li.append(strong,span);
      list.appendChild(li);
    });
    details.hidden=incomplete.length===0;
    if(incomplete.length===0) details.open=false;
  }
  function updateForm(form,resetScope){
    const template=form.querySelector('.js-contract-template');
    const scope=form.querySelector('.js-contract-page-scope');
    if(!template||!scope) return;
    const meta=(payload.templates||{})[template.value]||{
      pageCount:1,layoutPageCount:1,pageSelectable:false,warning:'تعذر قراءة بنية صفحات القالب.',required:[],missing:{}
    };
    const previous=resetScope?'all':scope.value;
    scope.replaceChildren(pageOption('all','تصدير كامل — جميع الصفحات'));
    if(meta.pageSelectable){
      for(let page=1;page<=Number(meta.layoutPageCount||1);page++){
        scope.appendChild(pageOption('page:'+page,'الصفحة '+page+' فقط'));
      }
    }
    scope.value=Array.from(scope.options).some(function(option){return option.value===previous;})?previous:'all';

    form.querySelectorAll('[data-page-warning]').forEach(function(warning){
      warning.textContent=meta.warning||'';
      warning.hidden=!meta.warning;
    });
    updateInsight(form,meta);
  }

  document.querySelectorAll('form').forEach(function(form){
    const template=form.querySelector('.js-contract-template');
    const scope=form.querySelector('.js-contract-page-scope');
    if(!template||!scope) return;
    template.addEventListener('change',function(){updateForm(form,true);});
    scope.addEventListener('change',function(){updateForm(form,false);});
    const dataFilter=form.querySelector('.js-contract-data-filter');
    if(dataFilter) dataFilter.addEventListener('change',function(){updateForm(form,false);});
    const bulkScope=form.querySelector('.js-contract-bulk-scope');
    if(bulkScope) bulkScope.addEventListener('change',function(){updateForm(form,false);});
    updateForm(form,false);
  });
})();
</script>
<?php if (!$isAndroid): ?>
<script src="assets/js/subscriber_contracts_desktop.js?v=<?= (int)(@filemtime(__DIR__ . '/assets/js/subscriber_contracts_desktop.js') ?: 1) ?>"></script>
<?php endif; ?>
<?php if($mappingTemplate): ?><script>(function(){const rows=document.getElementById('mappingRows'),tpl=document.getElementById('mappingRowTemplate'),add=document.getElementById('addMappingRow');function bind(root){root.querySelectorAll('.sct-remove-row').forEach(b=>b.onclick=()=>b.closest('.sct-mapping-row').remove())}add.onclick=()=>{const node=tpl.content.cloneNode(true);rows.appendChild(node);bind(rows);const empty=document.querySelector('.sct-mapping-empty');if(empty)empty.remove()};bind(rows)})();</script><?php endif; ?>
<?php
$contractOutputActor = ua_output_session_actor($conn);
$contractOutputFileRoute = [
  'commandKey'=>'contract_print',
  'scopeBase'=>(string)($contractOutputActor['scope'] ?? ua_output_scope_key()),
  'configUrl'=>'output_route_config.php',
  'fileProxyUrl'=>'output_file_proxy.php',
  'logUrl'=>'output_job_log.php',
  'contractLogUrl'=>'contract_print_log.php',
  'csrfToken'=>ua_csrf_token(),
];
?>
<script>window.UA_OUTPUT_FILE_ROUTE=<?= json_encode($contractOutputFileRoute, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES) ?>;</script>
<script src="assets/js/subscriber_contracts_bulk_export.js?v=<?= (int)(@filemtime(__DIR__ . '/assets/js/subscriber_contracts_bulk_export.js') ?: 1) ?>"></script>
<script src="assets/js/ua_output_file_router.js?v=<?= (int)(@filemtime(__DIR__ . '/assets/js/ua_output_file_router.js') ?: 1) ?>"></script>
<?php include __DIR__ . '/footer.php'; ?>
