<?php
declare(strict_types=1);

require_once __DIR__ . '/../includes/layout.php';

require_login($conn);

if (!can_access_production_deployment($conn)) {
    redirect_with_flash(
        'dashboard.php',
        'error',
        localized_flash_message(
            'คุณไม่มีสิทธิ์เข้าถึงหน้านี้',
            'You do not have permission to access that page.'
        )
    );
}

function production_deployment_text(string $thaiText, string $englishText): string
{
    return ui_text($thaiText, $englishText);
}

function production_deployment_hidden_structure_config(string $prefix, array $config): string
{
    $fields = array('use_current', 'host', 'port', 'user', 'pass', 'database');
    $html = '';

    foreach ($fields as $field) {
        $value = $field === 'use_current'
            ? (!empty($config[$field]) ? '1' : '0')
            : (string) ($config[$field] ?? '');
        $html .= '<input type="hidden" name="' . e($prefix . '[' . $field . ']') . '" value="' . e($value) . '">' . PHP_EOL;
    }

    return $html;
}

function production_deployment_format_bytes(int $bytes): string
{
    $units = array('B', 'KB', 'MB', 'GB');
    $value = max(0, $bytes);
    $unitIndex = 0;

    while ($value >= 1024 && $unitIndex < count($units) - 1) {
        $value /= 1024;
        $unitIndex++;
    }

    return number_format($value, $unitIndex === 0 ? 0 : 1) . ' ' . $units[$unitIndex];
}

$deploymentFilters = maintenance_deployment_filters($_GET);
$deploymentFilterMeta = maintenance_deployment_filter_meta($deploymentFilters);
$canPrepareDeploymentPackage = can_access($conn, 'maintenance_prepare_deployment_package');
$canCompareDatabaseStructure = can_access($conn, 'maintenance_compare_database_structure');
$canApplyDatabaseStructure = can_access($conn, 'maintenance_apply_database_structure');
$showExportPermissionNotice = !$canPrepareDeploymentPackage && ($canCompareDatabaseStructure || $canApplyDatabaseStructure);

$deploymentSummary = null;
$deploymentArtifacts = array();
$deploymentSummaryError = '';
if ($canPrepareDeploymentPackage) {
    try {
        $deploymentSummary = maintenance_deployment_summary($deploymentFilters);
        $deploymentArtifacts = array_slice(maintenance_deployment_artifacts(), 0, 8);
    } catch (Throwable $exception) {
        $deploymentSummaryError = $exception->getMessage() !== ''
            ? $exception->getMessage()
            : production_deployment_text('ไม่สามารถเตรียม deployment summary ได้', 'Deployment summary could not be prepared.');
    }
}

$structureSyncSourceDefaults = maintenance_structure_sync_current_config($conn);
$structureSyncTargetDefaults = maintenance_structure_sync_custom_defaults($conn);
$structureSyncSourceInput = maintenance_structure_sync_input($_POST['structure_source'] ?? array(), $structureSyncSourceDefaults);
$structureSyncTargetInput = maintenance_structure_sync_input($_POST['structure_target'] ?? array(), $structureSyncTargetDefaults);
$structureSyncPreview = null;
$structureSyncPreviewError = '';

if (
    $_SERVER['REQUEST_METHOD'] === 'POST'
    && (string) ($_POST['deployment_preview_type'] ?? '') === 'database_structure_sync'
    && $canCompareDatabaseStructure
) {
    try {
        $structureSyncPreview = maintenance_structure_sync_preview($structureSyncSourceInput, $structureSyncTargetInput, $conn);
    } catch (Throwable $exception) {
        $structureSyncPreviewError = $exception->getMessage() !== ''
            ? $exception->getMessage()
            : production_deployment_text('การพรีวิว Database Structure Sync ล้มเหลว', 'Database Structure Sync preview failed.');
    }
}

$pageTitle = production_deployment_text('เตรียมโปรแกรมขึ้น Production', 'Production Deployment');
$pageDescription = production_deployment_text(
    'สร้างชุดไฟล์สำหรับอัปโหลดขึ้น Production เปรียบเทียบโครงสร้างฐานข้อมูล และจัดการการอัปเดตฐานข้อมูลปลายทางจากหน้าเดียว',
    'Prepare an upload package, compare database structure, and manage target-database updates from one page before deployment.'
);
$backToManageSystemLabel = production_deployment_text('กลับไป Manage System', 'Back to Manage System');
$openMaintenanceLabel = production_deployment_text('เปิด Data Maintenance', 'Open Data Maintenance');
$returnPage = 'production_deployment.php';
if (!empty($deploymentFilterMeta['has_filters'])) {
    $returnPage .= '?' . http_build_query(array(
        'modified_from' => (string) ($deploymentFilterMeta['modified_from'] ?? ''),
        'modified_to' => (string) ($deploymentFilterMeta['modified_to'] ?? ''),
    ));
}

render_page_start($pageTitle, 'production_deployment', array('translation_buffer' => false));
?>

<section class="page-hero">
    <div>
        <h1><?= e($pageTitle) ?></h1>
        <p><?= e($pageDescription) ?></p>
    </div>
    <div class="hero-actions">
        <a class="button button-secondary" href="manage_system.php"><?= e($backToManageSystemLabel) ?></a>
        <a class="button button-secondary" href="data_maintenance.php"><?= e($openMaintenanceLabel) ?></a>
    </div>
</section>

<section class="table-card" style="margin-top: 18px;">
    <div class="section-head" style="padding: 18px 18px 0;">
        <div>
            <h2 class="section-title"><?= e(production_deployment_text('กติกาความปลอดภัย', 'Safety rules')) ?></h2>
            <p class="helper"><?= e(production_deployment_text('หน้านี้แยกออกมาสำหรับเตรียมขึ้น production โดยตรง เพื่อให้เห็นทั้งชุดไฟล์และโครงสร้างฐานข้อมูลในที่เดียว', 'This page is dedicated to Production deployment so the file package and database structure steps are visible in one place.')) ?></p>
        </div>
    </div>
    <div class="stack" style="padding: 18px;">
        <p class="helper is-danger"><?= e(production_deployment_text('ชุด deploy สำหรับ production จะตัด `.env`, sessions, uploads, backups และ runtime files อื่นภายใต้ `storage/` ออกเสมอ', 'Production deployment package always excludes `.env`, sessions, uploads, backups and other runtime files inside `storage/`.')) ?></p>
        <p class="helper is-danger"><?= e(production_deployment_text('Database Structure Sync จะอัปเดตอัตโนมัติเฉพาะโครงสร้างที่ปลอดภัย เช่น สร้างตารางที่หาย เพิ่มคอลัมน์โดยวางตำแหน่งให้ตรงกับต้นฉบับ ดัชนี และ foreign key ส่วนคอลัมน์ที่เปลี่ยนหรือการลบที่เสี่ยงจะคงไว้ให้ตรวจเอง', 'Database Structure Sync only applies safe structure additions automatically: create missing tables, add missing columns in the same position as the source, indexes and foreign keys. Changed columns or destructive drops stay in manual review.')) ?></p>
        <p class="helper"><?= e(production_deployment_text('หลัง copy ไฟล์ขึ้นเครื่องจริง ควรรัน `scripts\\post_deploy_spot_check.ps1` ตาม checklist เดิม', 'After the upload finishes, run `scripts\\post_deploy_spot_check.ps1` as described in the deployment checklist.')) ?></p>
    </div>
</section>

<?php if ($showExportPermissionNotice): ?>
    <section class="table-card" style="margin-top: 18px;">
        <div style="padding: 18px;">
            <p class="helper is-danger"><?= e(production_deployment_text('บัญชีนี้ยังไม่มีสิทธิ์ export ไฟล์ deployment_source_only จึงเห็นเฉพาะ Database Structure Sync ถ้าต้องการปุ่ม export ให้เพิ่มสิทธิ์ `Maintenance: Prepare Deployment Package` ในหน้าตำแหน่งงาน', 'This account can only use Database Structure Sync right now. To show the export buttons, grant the `Maintenance: Prepare Deployment Package` permission from the Positions screen.')) ?></p>
        </div>
    </section>
<?php endif; ?>

<?php if ($canPrepareDeploymentPackage): ?>
    <section class="table-card" style="margin-top: 18px;">
        <div class="section-head" style="padding: 18px 18px 0;">
            <div>
                <h2 class="section-title"><?= e(production_deployment_text('ชุดไฟล์สำหรับขึ้น Production', 'Production file package')) ?></h2>
                <p class="helper"><?= e(production_deployment_text('สร้าง deployment plan, source-only folder หรือ ZIP สำหรับเอาขึ้น production โดยไม่พา runtime data ไปทับเครื่องจริง', 'Build a deployment plan, source-only folder, or ZIP for Production without copying runtime data onto the live server.')) ?></p>
            </div>
        </div>

        <div style="padding: 18px;">
            <?php if ($deploymentSummaryError !== ''): ?>
                <p class="helper is-danger"><?= e(translate_text($deploymentSummaryError)) ?></p>
            <?php elseif ($deploymentSummary !== null): ?>
                <div class="stats-grid">
                    <article class="stat-card">
                        <span class="stat-label"><?= e(production_deployment_text('ไฟล์', 'Files')) ?></span>
                        <strong class="stat-value"><?= number_format((int) ($deploymentSummary['file_count'] ?? 0)) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label"><?= e(production_deployment_text('ขนาดรวม', 'Total size')) ?></span>
                        <strong class="stat-value"><?= e(production_deployment_format_bytes((int) ($deploymentSummary['total_bytes'] ?? 0))) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label"><?= e(production_deployment_text('artifact ที่สร้างไว้', 'Artifacts')) ?></span>
                        <strong class="stat-value"><?= number_format((int) ($deploymentSummary['artifact_count'] ?? 0)) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label"><?= e(production_deployment_text('รูปแบบไฟล์อัปโหลด', 'Upload package format')) ?></span>
                        <strong class="stat-value"><?= e(!empty($deploymentSummary['archive_supported']) ? (string) ($deploymentSummary['archive_label'] ?? 'Package') : production_deployment_text('ยังไม่พร้อม', 'Unavailable')) ?></strong>
                    </article>
                </div>

                <div class="grid grid-2" style="margin-top: 18px;">
                    <section class="card">
                        <div class="stack">
                            <h3 class="section-title"><?= e(production_deployment_text('ขอบเขตไฟล์ที่จะขึ้น', 'Upload scope')) ?></h3>
                            <p class="helper"><?= e(production_deployment_text('โฟลเดอร์ artifact: ', 'Artifact directory: ')) ?><?= e((string) ($deploymentSummary['package_directory_relative'] ?? 'storage/maintenance_exports/deployment_packages')) ?></p>
                            <?php if (false): ?>
                            <form method="GET" class="card" style="margin-top: 8px;">
                                <div class="stack">
                                    <div>
                                        <h4 class="section-title" style="font-size: 16px;"><?= e(production_deployment_text('กรองไฟล์สำหรับ export', 'Export filter')) ?></h4>
                                        <p class="helper"><?= e(production_deployment_text('เว้นว่างเพื่อ export ไฟล์ทั้งชุด หากเลือกวันที่ ระบบจะรวมเฉพาะไฟล์ที่อัปเดตตั้งแต่วันนั้นเป็นต้นไป', 'Leave this blank to export the full source-only package. If you choose a date, only files updated on or after that day will be included.')) ?></p>
                                    </div>
                                    <label>
                                        <span><?= e(production_deployment_text('Updated since (รวมวันนั้นด้วย)', 'Updated since (inclusive)')) ?></span>
                                        <input type="date" name="updated_since" value="<?= e((string) ($deploymentFilters['updated_since'] ?? '')) ?>">
                                    </label>
                                    <div class="button-row">
                                        <button class="button button-secondary" type="submit"><?= e(production_deployment_text('ใช้ตัวกรองวันที่ไฟล์', 'Apply file-date filter')) ?></button>
                                        <a class="button button-secondary" href="production_deployment.php"><?= e(production_deployment_text('ล้างตัวกรอง', 'Clear filter')) ?></a>
                                    </div>
                                    <?php if (!empty($deploymentFilterMeta['has_filters'])): ?>
                                        <p class="helper is-danger"><?= e(production_deployment_text('ตอนนี้กำลัง export เฉพาะไฟล์ที่อัปเดตตั้งแต่วันที่ ', 'Current export filter: files updated on or after ')) ?><?= e((string) ($deploymentFilterMeta['updated_since'] ?? '')) ?></p>
                                    <?php else: ?>
                                        <p class="helper"><?= e(production_deployment_text('ตอนนี้ export ไฟล์ทั้งชุดตาม source-only checklist เดิม', 'Current export scope: full source-only package.')) ?></p>
                                    <?php endif; ?>
                                </div>
                            </form>
                            <?php endif; ?>
                            <form method="GET" class="card" style="margin-top: 8px;">
                                <div class="stack">
                                    <div>
                                        <h4 class="section-title" style="font-size: 16px;"><?= e(production_deployment_text('ตัวกรองสำหรับ export', 'Export filter')) ?></h4>
                                        <p class="helper"><?= e(production_deployment_text('เว้นว่างทั้ง 2 ช่องเพื่อ export ไฟล์ทั้งชุด หรือกำหนดช่วง Date modified เพื่อรวมเฉพาะไฟล์ที่แก้ไขอยู่ในช่วงวันที่นั้น', 'Leave both dates blank to export the full source-only package. Set a Date modified range to include only files updated within that period.')) ?></p>
                                    </div>
                                    <div class="grid grid-2">
                                        <label>
                                            <span><?= e(production_deployment_text('Date modified จากวันที่', 'Date modified from')) ?></span>
                                            <input type="date" name="modified_from" value="<?= e((string) ($deploymentFilters['modified_from'] ?? '')) ?>">
                                        </label>
                                        <label>
                                            <span><?= e(production_deployment_text('Date modified ถึงวันที่', 'Date modified to')) ?></span>
                                            <input type="date" name="modified_to" value="<?= e((string) ($deploymentFilters['modified_to'] ?? '')) ?>">
                                        </label>
                                    </div>
                                    <div class="button-row">
                                        <button class="button button-secondary" type="submit"><?= e(production_deployment_text('ใช้ช่วงวันที่ Date modified', 'Apply Date modified range')) ?></button>
                                        <a class="button button-secondary" href="production_deployment.php"><?= e(production_deployment_text('ล้างช่วงวันที่', 'Clear range')) ?></a>
                                    </div>
                                    <?php if (!empty($deploymentFilterMeta['has_filters'])): ?>
                                        <p class="helper is-danger"><?= e(production_deployment_text('ช่วง export ปัจจุบัน: ', 'Current export filter: ')) ?><?= e((string) ($deploymentFilterMeta['label'] ?? '')) ?></p>
                                    <?php else: ?>
                                        <p class="helper"><?= e(production_deployment_text('ตอนนี้ export ไฟล์ทั้งชุดตาม source-only checklist เดิม', 'Current export scope: full source-only package.')) ?></p>
                                    <?php endif; ?>
                                </div>
                            </form>
                            <?php if ((int) ($deploymentSummary['file_count'] ?? 0) > 0): ?>
                            <div class="button-row">
                                <form method="POST" action="../process/download_deployment_plan.php">
                                    <?= csrf_input('deployment_plan') ?>
                                    <input type="hidden" name="return_page" value="<?= e($returnPage) ?>">
                                    <input type="hidden" name="modified_from" value="<?= e((string) ($deploymentFilters['modified_from'] ?? '')) ?>">
                                    <input type="hidden" name="modified_to" value="<?= e((string) ($deploymentFilters['modified_to'] ?? '')) ?>">
                                    <button class="button button-secondary" type="submit"><?= e(production_deployment_text('Download deployment plan', 'Download deployment plan')) ?></button>
                                </form>
                                <form method="POST" action="../process/build_deployment_folder.php">
                                    <?= csrf_input('deployment_folder') ?>
                                    <input type="hidden" name="return_page" value="<?= e($returnPage) ?>">
                                    <input type="hidden" name="modified_from" value="<?= e((string) ($deploymentFilters['modified_from'] ?? '')) ?>">
                                    <input type="hidden" name="modified_to" value="<?= e((string) ($deploymentFilters['modified_to'] ?? '')) ?>">
                                    <button class="button button-secondary" type="submit"><?= e(production_deployment_text('Build deployment_source_only folder', 'Build deployment_source_only folder')) ?></button>
                                </form>
                                <?php if (!empty($deploymentSummary['archive_supported'])): ?>
                                    <form method="POST" action="../process/download_deployment_package.php">
                                        <?= csrf_input('deployment_package') ?>
                                        <input type="hidden" name="return_page" value="<?= e($returnPage) ?>">
                                        <input type="hidden" name="modified_from" value="<?= e((string) ($deploymentFilters['modified_from'] ?? '')) ?>">
                                        <input type="hidden" name="modified_to" value="<?= e((string) ($deploymentFilters['modified_to'] ?? '')) ?>">
                                        <button class="button" type="submit"><?= e(production_deployment_text('Export deployment_source_only', 'Export deployment_source_only')) ?> (<?= e((string) ($deploymentSummary['archive_label'] ?? 'Package')) ?>)</button>
                                    </form>
                                <?php endif; ?>
                            </div>
                            <?php else: ?>
                                <p class="helper is-danger" style="margin-top: 12px;"><?= e(production_deployment_text('ไม่พบไฟล์ที่ตรงกับช่วง Date modified ที่เลือก กรุณาปรับช่วงวันที่หรือล้างตัวกรองก่อน export', 'No files matched the selected Date modified range. Adjust the range or clear the filter before exporting.')) ?></p>
                            <?php endif; ?>
                            <?php if (!empty($deploymentSummary['archive_supported']) && empty($deploymentSummary['zip_supported'])): ?>
                                <p class="helper"><?= e(production_deployment_text('เครื่องนี้จะสร้างไฟล์อัปโหลดเป็น TAR.GZ แทน ZIP เพื่อให้มี package สำหรับอัปโหลดได้ทันที', 'This server will generate a TAR.GZ upload package instead of ZIP so you still get an uploadable artifact.')) ?></p>
                            <?php endif; ?>
                            <?php if (empty($deploymentSummary['archive_supported'])): ?>
                                <p class="helper is-danger"><?= e(production_deployment_text('เครื่องนี้ยังสร้างไฟล์ package จากหน้าเว็บไม่ได้ ตอนนี้ใช้ deployment plan หรือ source-only folder ต่อกับ WinSCP/Robocopy ไปก่อนได้', 'This server cannot build upload packages yet. For now, use the deployment plan or source-only folder with WinSCP or Robocopy.')) ?></p>
                            <?php endif; ?>
                        </div>
                    </section>

                    <section class="card">
                        <div class="grid grid-2">
                            <div>
                                <h3 class="section-title"><?= e(production_deployment_text('Include', 'Include')) ?></h3>
                                <ul class="stack compact-list">
                                    <?php foreach ((array) ($deploymentSummary['included_entries'] ?? array()) as $entry): ?>
                                        <li><?= e((string) ($entry['path'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </div>
                            <div>
                                <h3 class="section-title"><?= e(production_deployment_text('Exclude', 'Exclude')) ?></h3>
                                <ul class="stack compact-list">
                                    <?php foreach ((array) ($deploymentSummary['excluded_paths'] ?? array()) as $path): ?>
                                        <li><?= e((string) $path) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </div>
                        </div>
                    </section>
                </div>

                <?php if ($deploymentArtifacts !== array()): ?>
                    <div class="table-card" style="margin-top: 18px;">
                        <div class="section-head" style="padding: 18px 18px 0;">
                            <div>
                                <h3 class="section-title"><?= e(production_deployment_text('artifact ล่าสุด', 'Recent artifacts')) ?></h3>
                                <p class="helper"><?= e(production_deployment_text('แสดงไฟล์หรือโฟลเดอร์ล่าสุดที่ระบบสร้างไว้ใน `storage/maintenance_exports/deployment_packages`', 'Latest files or folders generated in `storage/maintenance_exports/deployment_packages`.')) ?></p>
                            </div>
                        </div>
                        <table>
                            <thead>
                            <tr>
                                <th><?= e(production_deployment_text('ไฟล์', 'File')) ?></th>
                                <th><?= e(production_deployment_text('ประเภท', 'Type')) ?></th>
                                <th><?= e(production_deployment_text('ขนาด', 'Size')) ?></th>
                                <th><?= e(production_deployment_text('เวลา', 'Modified')) ?></th>
                            </tr>
                            </thead>
                            <tbody>
                            <?php foreach ($deploymentArtifacts as $artifactRow): ?>
                                <tr>
                                    <td>
                                        <strong><?= e((string) ($artifactRow['file_name'] ?? '')) ?></strong><br>
                                        <small class="helper"><?= e((string) ($artifactRow['relative_path'] ?? '')) ?></small>
                                    </td>
                                    <td><?= e((string) ($artifactRow['type_label'] ?? '')) ?></td>
                                    <td><?= e(((string) ($artifactRow['type_label'] ?? '')) === 'Source-only folder' ? '-' : production_deployment_format_bytes((int) ($artifactRow['size_bytes'] ?? 0))) ?></td>
                                    <td><?= e((string) ($artifactRow['modified_at'] ?? '')) ?></td>
                                </tr>
                            <?php endforeach; ?>
                            </tbody>
                        </table>
                    </div>
                <?php endif; ?>
            <?php endif; ?>
        </div>
    </section>
<?php endif; ?>

<?php if ($canCompareDatabaseStructure || $canApplyDatabaseStructure): ?>
    <section class="table-card" style="margin-top: 18px;">
        <div class="section-head" style="padding: 18px 18px 0;">
            <div>
                <h2 class="section-title">Database Structure Sync</h2>
                <p class="helper">Compare structure between Source DB (A) and Target DB (B), generate SQL patch, then apply only safe updates to B after an automatic backup.</p>
                <p class="helper"><?= e(production_deployment_text('คอลัมน์ที่ระบบเพิ่มให้อัตโนมัติจะพยายามวางตำแหน่งให้ตรงกับฐานต้นฉบับ โดยใช้ `FIRST` หรือ `AFTER` ตามลำดับคอลัมน์เมื่อทำได้', 'Automatically added columns are positioned to match the source schema by using `FIRST` or `AFTER` whenever possible.')) ?></p>
            </div>
        </div>

        <form method="POST" style="padding: 18px;">
            <input type="hidden" name="deployment_preview_type" value="database_structure_sync">

            <div class="grid grid-2">
                <section class="card">
                    <div class="stack">
                        <h3 class="section-title">Source DB (A)</h3>
                        <label class="checkbox">
                            <input type="checkbox" name="structure_source[use_current]" value="1"<?= !empty($structureSyncSourceInput['use_current']) ? ' checked' : '' ?>>
                            <span>Use current system database connection</span>
                        </label>
                        <label>
                            <span>Host</span>
                            <input type="text" name="structure_source[host]" value="<?= e((string) ($structureSyncSourceInput['host'] ?? '')) ?>">
                        </label>
                        <label>
                            <span>Port</span>
                            <input type="number" name="structure_source[port]" min="1" value="<?= e((string) ($structureSyncSourceInput['port'] ?? '3306')) ?>">
                        </label>
                        <label>
                            <span>Username</span>
                            <input type="text" name="structure_source[user]" value="<?= e((string) ($structureSyncSourceInput['user'] ?? '')) ?>">
                        </label>
                        <label>
                            <span>Password</span>
                            <input type="password" name="structure_source[pass]" value="<?= e((string) ($structureSyncSourceInput['pass'] ?? '')) ?>">
                        </label>
                        <label>
                            <span>Database</span>
                            <input type="text" name="structure_source[database]" value="<?= e((string) ($structureSyncSourceInput['database'] ?? '')) ?>">
                        </label>
                    </div>
                </section>

                <section class="card">
                    <div class="stack">
                        <h3 class="section-title">Target DB (B)</h3>
                        <label class="checkbox">
                            <input type="checkbox" name="structure_target[use_current]" value="1"<?= !empty($structureSyncTargetInput['use_current']) ? ' checked' : '' ?>>
                            <span>Use current system database connection</span>
                        </label>
                        <label>
                            <span>Host</span>
                            <input type="text" name="structure_target[host]" value="<?= e((string) ($structureSyncTargetInput['host'] ?? '')) ?>">
                        </label>
                        <label>
                            <span>Port</span>
                            <input type="number" name="structure_target[port]" min="1" value="<?= e((string) ($structureSyncTargetInput['port'] ?? '3306')) ?>">
                        </label>
                        <label>
                            <span>Username</span>
                            <input type="text" name="structure_target[user]" value="<?= e((string) ($structureSyncTargetInput['user'] ?? '')) ?>">
                        </label>
                        <label>
                            <span>Password</span>
                            <input type="password" name="structure_target[pass]" value="<?= e((string) ($structureSyncTargetInput['pass'] ?? '')) ?>">
                        </label>
                        <label>
                            <span>Database</span>
                            <input type="text" name="structure_target[database]" value="<?= e((string) ($structureSyncTargetInput['database'] ?? '')) ?>">
                        </label>
                    </div>
                </section>
            </div>

            <div class="button-row" style="margin-top: 16px;">
                <?php if (can_access($conn, 'maintenance_compare_database_structure')): ?>
                    <button class="button" type="submit">Compare structure / Generate SQL</button>
                <?php endif; ?>
            </div>
        </form>

        <?php if ($structureSyncPreviewError !== ''): ?>
            <div style="padding: 0 18px 18px;">
                <p class="helper is-danger"><?= e(translate_text($structureSyncPreviewError)) ?></p>
            </div>
        <?php endif; ?>

        <?php if ($structureSyncPreview): ?>
            <div style="padding: 0 18px 18px;">
                <div class="stats-grid">
                    <article class="stat-card">
                        <span class="stat-label">Missing tables</span>
                        <strong class="stat-value"><?= number_format((int) ($structureSyncPreview['summary']['missing_tables'] ?? 0)) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label">Missing columns</span>
                        <strong class="stat-value"><?= number_format((int) ($structureSyncPreview['summary']['missing_columns'] ?? 0)) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label">Changed columns</span>
                        <strong class="stat-value"><?= number_format((int) ($structureSyncPreview['summary']['changed_columns'] ?? 0)) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label">Missing views</span>
                        <strong class="stat-value"><?= number_format((int) ($structureSyncPreview['summary']['missing_views'] ?? 0)) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label">Missing triggers</span>
                        <strong class="stat-value"><?= number_format((int) ($structureSyncPreview['summary']['missing_triggers'] ?? 0)) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label">Missing routines</span>
                        <strong class="stat-value"><?= number_format((int) ($structureSyncPreview['summary']['missing_routines'] ?? 0)) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label">Safe SQL</span>
                        <strong class="stat-value"><?= number_format((int) ($structureSyncPreview['summary']['safe_sql_count'] ?? 0)) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label">Manual review</span>
                        <strong class="stat-value"><?= number_format((int) ($structureSyncPreview['summary']['manual_sql_count'] ?? 0)) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label">Manual apply items</span>
                        <strong class="stat-value"><?= number_format((int) ($structureSyncPreview['summary']['manual_apply_count'] ?? 0)) ?></strong>
                    </article>
                    <article class="stat-card">
                        <span class="stat-label">Warnings</span>
                        <strong class="stat-value"><?= number_format((int) ($structureSyncPreview['summary']['warnings'] ?? 0)) ?></strong>
                    </article>
                </div>

                <div class="grid grid-2" style="margin-top: 18px;">
                    <section class="card">
                        <h3 class="section-title">Source summary</h3>
                        <p class="helper"><?= e((string) (($structureSyncPreview['source']['database'] ?? '-'))) ?> @ <?= e((string) (($structureSyncPreview['source']['host'] ?? '-'))) ?>:<?= e((string) (($structureSyncPreview['source']['port'] ?? '3306'))) ?></p>
                    </section>
                    <section class="card">
                        <h3 class="section-title">Target summary</h3>
                        <p class="helper"><?= e((string) (($structureSyncPreview['target']['database'] ?? '-'))) ?> @ <?= e((string) (($structureSyncPreview['target']['host'] ?? '-'))) ?>:<?= e((string) (($structureSyncPreview['target']['port'] ?? '3306'))) ?></p>
                    </section>
                </div>

                <?php if (!empty($structureSyncPreview['missing_tables'])): ?>
                    <div class="stack" style="margin-top: 18px;">
                        <h3 class="section-title">Missing tables in target</h3>
                        <ul class="stack compact-list">
                            <?php foreach ($structureSyncPreview['missing_tables'] as $row): ?>
                                <li><?= e((string) ($row['table_name'] ?? '')) ?></li>
                            <?php endforeach; ?>
                        </ul>
                    </div>
                <?php endif; ?>

                <?php if (!empty($structureSyncPreview['missing_views']) || !empty($structureSyncPreview['missing_triggers']) || !empty($structureSyncPreview['missing_routines'])): ?>
                    <div class="grid grid-3" style="margin-top: 18px;">
                        <?php if (!empty($structureSyncPreview['missing_views'])): ?>
                            <section class="card">
                                <h3 class="section-title">Missing views</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['missing_views'] as $row): ?>
                                        <li><?= e((string) ($row['view_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['missing_triggers'])): ?>
                            <section class="card">
                                <h3 class="section-title">Missing triggers</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['missing_triggers'] as $row): ?>
                                        <li><?= e((string) ($row['trigger_name'] ?? '')) ?><?php if (!empty($row['table_name'])): ?> on <?= e((string) $row['table_name']) ?><?php endif; ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['missing_routines'])): ?>
                            <section class="card">
                                <h3 class="section-title">Missing routines</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['missing_routines'] as $row): ?>
                                        <li><?= e((string) ($row['routine_type'] ?? '')) ?> <?= e((string) ($row['routine_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                    </div>
                <?php endif; ?>

                <?php if (!empty($structureSyncPreview['changed_columns']) || !empty($structureSyncPreview['extra_tables']) || !empty($structureSyncPreview['extra_columns']) || !empty($structureSyncPreview['changed_indexes']) || !empty($structureSyncPreview['changed_foreign_keys']) || !empty($structureSyncPreview['table_option_changes']) || !empty($structureSyncPreview['changed_views']) || !empty($structureSyncPreview['extra_views']) || !empty($structureSyncPreview['changed_triggers']) || !empty($structureSyncPreview['extra_triggers']) || !empty($structureSyncPreview['changed_routines']) || !empty($structureSyncPreview['extra_routines'])): ?>
                    <div class="stack" style="margin-top: 18px;">
                        <h3 class="section-title">Manual review required</h3>
                        <p class="helper is-danger">These differences were detected but will not be applied automatically because they may be destructive or require manual review.</p>
                    </div>
                <?php endif; ?>

                <?php if (!empty($structureSyncPreview['changed_columns']) || !empty($structureSyncPreview['changed_indexes']) || !empty($structureSyncPreview['changed_foreign_keys']) || !empty($structureSyncPreview['table_option_changes']) || !empty($structureSyncPreview['extra_tables']) || !empty($structureSyncPreview['extra_columns']) || !empty($structureSyncPreview['extra_indexes']) || !empty($structureSyncPreview['extra_foreign_keys'])): ?>
                    <div class="grid grid-3" style="margin-top: 18px;">
                        <?php if (!empty($structureSyncPreview['changed_columns'])): ?>
                            <section class="card">
                                <h3 class="section-title">Changed columns</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['changed_columns'] as $row): ?>
                                        <li><?= e((string) ($row['table_name'] ?? '')) ?>.<?= e((string) ($row['column_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['changed_indexes'])): ?>
                            <section class="card">
                                <h3 class="section-title">Changed indexes</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['changed_indexes'] as $row): ?>
                                        <li><?= e((string) ($row['table_name'] ?? '')) ?>.<?= e((string) ($row['index_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['changed_foreign_keys'])): ?>
                            <section class="card">
                                <h3 class="section-title">Changed foreign keys</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['changed_foreign_keys'] as $row): ?>
                                        <li><?= e((string) ($row['table_name'] ?? '')) ?>.<?= e((string) ($row['constraint_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['table_option_changes'])): ?>
                            <section class="card">
                                <h3 class="section-title">Changed table options</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['table_option_changes'] as $row): ?>
                                        <li><?= e((string) ($row['table_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['extra_tables'])): ?>
                            <section class="card">
                                <h3 class="section-title">Extra tables in target</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['extra_tables'] as $row): ?>
                                        <li><?= e((string) ($row['table_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['extra_columns'])): ?>
                            <section class="card">
                                <h3 class="section-title">Extra columns in target</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['extra_columns'] as $row): ?>
                                        <li><?= e((string) ($row['table_name'] ?? '')) ?>.<?= e((string) ($row['column_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['extra_indexes'])): ?>
                            <section class="card">
                                <h3 class="section-title">Extra indexes in target</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['extra_indexes'] as $row): ?>
                                        <li><?= e((string) ($row['table_name'] ?? '')) ?>.<?= e((string) ($row['index_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['extra_foreign_keys'])): ?>
                            <section class="card">
                                <h3 class="section-title">Extra foreign keys in target</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['extra_foreign_keys'] as $row): ?>
                                        <li><?= e((string) ($row['table_name'] ?? '')) ?>.<?= e((string) ($row['constraint_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                    </div>
                <?php endif; ?>

                <?php if (!empty($structureSyncPreview['changed_views']) || !empty($structureSyncPreview['extra_views']) || !empty($structureSyncPreview['changed_triggers']) || !empty($structureSyncPreview['extra_triggers']) || !empty($structureSyncPreview['changed_routines']) || !empty($structureSyncPreview['extra_routines'])): ?>
                    <div class="grid grid-3" style="margin-top: 18px;">
                        <?php if (!empty($structureSyncPreview['changed_views'])): ?>
                            <section class="card">
                                <h3 class="section-title">Changed views</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['changed_views'] as $row): ?>
                                        <li><?= e((string) ($row['view_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['extra_views'])): ?>
                            <section class="card">
                                <h3 class="section-title">Extra views in target</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['extra_views'] as $row): ?>
                                        <li><?= e((string) ($row['view_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['changed_triggers'])): ?>
                            <section class="card">
                                <h3 class="section-title">Changed triggers</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['changed_triggers'] as $row): ?>
                                        <li><?= e((string) ($row['trigger_name'] ?? '')) ?><?php if (!empty($row['table_name'])): ?> on <?= e((string) $row['table_name']) ?><?php endif; ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['extra_triggers'])): ?>
                            <section class="card">
                                <h3 class="section-title">Extra triggers in target</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['extra_triggers'] as $row): ?>
                                        <li><?= e((string) ($row['trigger_name'] ?? '')) ?><?php if (!empty($row['table_name'])): ?> on <?= e((string) $row['table_name']) ?><?php endif; ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['changed_routines'])): ?>
                            <section class="card">
                                <h3 class="section-title">Changed routines</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['changed_routines'] as $row): ?>
                                        <li><?= e((string) ($row['routine_type'] ?? '')) ?> <?= e((string) ($row['routine_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                        <?php if (!empty($structureSyncPreview['extra_routines'])): ?>
                            <section class="card">
                                <h3 class="section-title">Extra routines in target</h3>
                                <ul class="stack compact-list">
                                    <?php foreach ($structureSyncPreview['extra_routines'] as $row): ?>
                                        <li><?= e((string) ($row['routine_type'] ?? '')) ?> <?= e((string) ($row['routine_name'] ?? '')) ?></li>
                                    <?php endforeach; ?>
                                </ul>
                            </section>
                        <?php endif; ?>
                    </div>
                <?php endif; ?>

                <div class="button-row" style="margin-top: 18px;">
                    <form method="POST" action="../process/download_structure_compare.php">
                        <input type="hidden" name="return_page" value="<?= e($returnPage) ?>">
                        <?= production_deployment_hidden_structure_config('source', $structureSyncSourceInput) ?>
                        <?= production_deployment_hidden_structure_config('target', $structureSyncTargetInput) ?>
                        <button class="button button-secondary" type="submit">Download compare JSON</button>
                    </form>
                    <form method="POST" action="../process/download_structure_patch.php">
                        <input type="hidden" name="return_page" value="<?= e($returnPage) ?>">
                        <?= production_deployment_hidden_structure_config('source', $structureSyncSourceInput) ?>
                        <?= production_deployment_hidden_structure_config('target', $structureSyncTargetInput) ?>
                        <input type="hidden" name="patch_scope" value="safe">
                        <button class="button button-secondary" type="submit">Download safe SQL</button>
                    </form>
                    <form method="POST" action="../process/download_structure_patch.php">
                        <input type="hidden" name="return_page" value="<?= e($returnPage) ?>">
                        <?= production_deployment_hidden_structure_config('source', $structureSyncSourceInput) ?>
                        <?= production_deployment_hidden_structure_config('target', $structureSyncTargetInput) ?>
                        <input type="hidden" name="patch_scope" value="manual">
                        <button class="button button-secondary" type="submit">Download manual-only patch</button>
                    </form>
                    <form method="POST" action="../process/download_structure_patch.php">
                        <input type="hidden" name="return_page" value="<?= e($returnPage) ?>">
                        <?= production_deployment_hidden_structure_config('source', $structureSyncSourceInput) ?>
                        <?= production_deployment_hidden_structure_config('target', $structureSyncTargetInput) ?>
                        <input type="hidden" name="patch_scope" value="combined">
                        <button class="button button-secondary" type="submit">Download full patch</button>
                    </form>
                </div>

                <div class="grid grid-2" style="margin-top: 12px;">
                    <section class="card">
                        <h3 class="section-title">Safe SQL patch</h3>
                        <textarea rows="14" readonly><?= e(implode(PHP_EOL . PHP_EOL, (array) ($structureSyncPreview['safe_sql'] ?? array()))) ?></textarea>
                    </section>
                    <section class="card">
                        <h3 class="section-title">Manual SQL / review notes</h3>
                        <textarea rows="14" readonly><?= e(implode(PHP_EOL . PHP_EOL, (array) ($structureSyncPreview['manual_sql'] ?? array()))) ?></textarea>
                    </section>
                </div>

                <?php if (!empty($structureSyncPreview['manual_apply_items']) && can_access($conn, 'maintenance_apply_database_structure')): ?>
                    <form method="POST" action="../process/run_data_maintenance.php" style="margin-top: 18px;">
                        <input type="hidden" name="maintenance_type" value="database_structure_sync_apply_manual">
                        <input type="hidden" name="return_page" value="<?= e($returnPage) ?>">
                        <?= production_deployment_hidden_structure_config('source', $structureSyncSourceInput) ?>
                        <?= production_deployment_hidden_structure_config('target', $structureSyncTargetInput) ?>
                        <div class="stack">
                            <h3 class="section-title">Select manual SQL items to apply</h3>
                            <p class="helper">Choose only the reviewed items you want to apply to Target DB (B). A backup will be created before execution.</p>
                            <div class="stack">
                                <?php foreach ((array) ($structureSyncPreview['manual_apply_items'] ?? array()) as $index => $manualItem): ?>
                                    <?php
                                    $sqlBlock = trim((string) ($manualItem['sql'] ?? ''));
                                    $manualLabel = trim((string) ($manualItem['label'] ?? ''));
                                    ?>
                                    <details class="card">
                                        <summary class="checkbox" style="cursor: pointer; user-select: none;">
                                            <input type="checkbox" name="selected_manual_sql[]" value="<?= e($sqlBlock) ?>">
                                            <span><?= e($manualLabel !== '' ? translate_text($manualLabel) : production_deployment_text('รายการ Manual SQL ', 'Manual SQL item ') . ($index + 1)) ?></span>
                                        </summary>
                                        <pre style="white-space: pre-wrap; margin: 12px 0 0; font-size: 12px;"><?= e($sqlBlock) ?></pre>
                                    </details>
                                <?php endforeach; ?>
                            </div>
                            <label>
                                <span><?= production_deployment_text('พิมพ์ <code>APPLY MANUAL STRUCTURE</code> เพื่อดำเนินการต่อ', 'Type <code>APPLY MANUAL STRUCTURE</code> to continue') ?></span>
                                <input type="text" name="confirm_phrase" required placeholder="APPLY MANUAL STRUCTURE">
                            </label>
                            <div class="button-row">
                                <button class="button button-danger" type="submit">Apply selected manual SQL</button>
                            </div>
                        </div>
                    </form>
                <?php endif; /*
                    <div class="card" style="margin-top: 18px;">
                        <h3 class="section-title"><?= e(production_deployment_text('ยังไม่มี Safe SQL ให้ Apply', 'No safe SQL to apply')) ?></h3>
                        <p class="helper"><?= e(production_deployment_text('ผล compare รอบนี้ไม่พบ safe SQL สำหรับอัปเดต ดังนั้นระบบจะยังไม่สร้างไฟล์สำรองจนกว่าจะมีรายการที่ต้อง apply จริง', 'This compare result does not contain any safe SQL updates, so no backup file will be created until there are actual changes to apply.')) ?></p>
                    </div>
                */ ?>

                <?php if (can_access($conn, 'maintenance_apply_database_structure')): ?>
                    <form method="POST" action="../process/run_data_maintenance.php" style="margin-top: 18px;">
                        <input type="hidden" name="maintenance_type" value="database_structure_sync_apply">
                        <input type="hidden" name="return_page" value="<?= e($returnPage) ?>">
                        <?= production_deployment_hidden_structure_config('source', $structureSyncSourceInput) ?>
                        <?= production_deployment_hidden_structure_config('target', $structureSyncTargetInput) ?>
                        <label>
                            <span><?= production_deployment_text('พิมพ์ <code>APPLY DATABASE STRUCTURE</code> เพื่อยืนยันการอัปเดตโครงสร้างฐานข้อมูลปลายทาง', 'Type <code>APPLY DATABASE STRUCTURE</code> to confirm applying database structure changes to the target database') ?></span>
                            <input type="text" name="confirm_phrase" required placeholder="APPLY DATABASE STRUCTURE">
                        </label>
                        <p class="helper is-danger" style="margin-top: 12px;"><?= e(production_deployment_text('ระบบจะสร้างไฟล์สำรองของ Target DB (B) อัตโนมัติทุกครั้ง แม้รอบนี้จะไม่มี Safe SQL ให้ apply', 'The system will always create an automatic backup of Target DB (B), even when this compare result has no safe SQL to apply.')) ?></p>
                        <div class="button-row" style="margin-top: 16px;">
                            <button class="button button-danger" type="submit"><?= e(production_deployment_text('อัปเดตโครงสร้างปลอดภัยไปยัง Target DB', 'Apply safe structure updates to Target DB')) ?></button>
                        </div>
                    </form>
                <?php endif; ?>
            </div>
        <?php endif; ?>
    </section>
<?php endif; ?>

<?php render_page_end(); ?>
