<?php

namespace App\Services;

use App\Models\SchoolSettingModel;
use App\Models\TeacherModel;
use App\Models\LearningDeviceProtaModel;
use App\Models\LearningDevicePromesModel;
use App\Models\LearningDeviceTpModel;
use App\Models\LearningDeviceModulModel;
use App\Models\LearningDeviceKktpModel;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\IOFactory;
use PhpOffice\PhpWord\SimpleType\Jc;
use PhpOffice\PhpWord\SimpleType\Border;
use Mpdf\Mpdf;

class DocumentExportService
{
    protected $settingModel;
    protected $teacherModel;
    protected $protaModel;
    protected $promesModel;
    protected $tpModel;
    protected $modulModel;
    protected $kktpModel;

    public function __construct()
    {
        \PhpOffice\PhpWord\Settings::setOutputEscapingEnabled(true);
        $this->settingModel = new SchoolSettingModel();
        $this->teacherModel = new TeacherModel();
        $this->protaModel   = new LearningDeviceProtaModel();
        $this->promesModel  = new LearningDevicePromesModel();
        $this->tpModel      = new LearningDeviceTpModel();
        $this->modulModel   = new LearningDeviceModulModel();
        $this->kktpModel    = new LearningDeviceKktpModel();
    }

    protected function parseJson($field): array
    {
        if (is_array($field)) {
            return $field;
        }
        if (is_string($field)) {
            return json_decode($field, true) ?: [];
        }
        return [];
    }

    /**
     * Get formal Kop (Header) HTML for PDF
     */
    protected function getPdfHeaderHtml(array $settings, string $docTitle): string
    {
        $schoolName = ($settings['school_name'] ?? 'SIMAK MADRASAH');
        $kemenag = $settings['letter_kemenag_office'] ?? '';
        $address = $settings['address'] ?? '';
        $phone = $settings['phone'] ?? '';
        $email = $settings['email'] ?? '';
        $website = $settings['website'] ?? '';
        
        $html = "
        <div style='text-align: center; font-family: sans-serif; margin-bottom: 20px; border-bottom: 3px double #000; padding-bottom: 8px;'>
            <h2 style='margin: 0; font-size: 14px; font-weight: bold;'>{$kemenag}</h2>
            <h1 style='margin: 2px 0; font-size: 18px; font-weight: bold;'>{$schoolName}</h1>
            <p style='margin: 2px 0; font-size: 10px; font-style: italic;'>{$address} | Telp: {$phone}</p>
            <p style='margin: 2px 0; font-size: 10px; font-style: italic;'>Email: {$email} | Web: {$website}</p>
        </div>
        <div style='text-align: center; font-family: sans-serif; margin-bottom: 20px;'>
            <h3 style='margin: 0; font-size: 14px; font-weight: bold; text-decoration: underline;'>{$docTitle}</h3>
        </div>";
        
        return $html;
    }

    /**
     * Get Meta Table HTML for PDF
     */
    protected function getPdfMetaTableHtml(array $device): string
    {
        $schoolTypeLabel = $device['school_type'] === 'madrasah' ? 'Madrasah' : 'Sekolah Umum';
        return "
        <table class='meta-table' style='width: 100%; border: none; font-size: 10pt; font-family: sans-serif; margin-bottom: 15px;'>
            <tr>
                <td style='width: 18%; border: none; padding: 2px 0;'>Mata Pelajaran</td>
                <td style='width: 3%; border: none; padding: 2px 0;'>:</td>
                <td style='width: 30%; border: none; padding: 2px 0;'><strong>{$device['subject_name']}</strong></td>
                <td style='width: 18%; border: none; padding: 2px 0;'>Tahun Pelajaran</td>
                <td style='width: 3%; border: none; padding: 2px 0;'>:</td>
                <td style='width: 30%; border: none; padding: 2px 0;'>{$device['academic_year_name']}</td>
            </tr>
            <tr>
                <td style='border: none; padding: 2px 0;'>Kelas / Tingkat</td>
                <td style='border: none; padding: 2px 0;'>:</td>
                <td style='border: none; padding: 2px 0;'>Kelas {$device['grade_name']}</td>
                <td style='border: none; padding: 2px 0;'>Fase Kurikulum</td>
                <td style='border: none; padding: 2px 0;'>:</td>
                <td style='border: none; padding: 2px 0;'>Fase {$device['phase']}</td>
            </tr>
            <tr>
                <td style='border: none; padding: 2px 0;'>Jenis Lembaga</td>
                <td style='border: none; padding: 2px 0;'>:</td>
                <td style='border: none; padding: 2px 0;'>{$schoolTypeLabel}</td>
                <td style='border: none; padding: 2px 0;'>&nbsp;</td>
                <td style='border: none; padding: 2px 0;'>&nbsp;</td>
                <td style='border: none; padding: 2px 0;'>&nbsp;</td>
            </tr>
        </table>
        <hr style='border: 0.5px solid #ccc; margin-bottom: 15px;'>";
    }

    /**
     * Get Signatures HTML for PDF
     */
    protected function getPdfSignaturesHtml(array $settings, array $device): string
    {
        $principalName = $settings['principal_name'] ?? '[Nama Kepala Sekolah]';
        $principalNip = $settings['principal_nip'] ?? '-';
        $teacherName = $device['teacher_name'] ?? '[Nama Guru]';
        $teacherNip = $device['teacher_nip'] ?? '-';
        $teacherIdLabel = guess_id_label($teacherNip);
        $city = $settings['letter_city'] ?? 'Semarang';
        $date = date('d F Y');
        
        return "
        <br><br>
        <table style='width: 100%; border: none; font-family: sans-serif; font-size: 10px; margin-top: 30px;'>
            <tr>
                <td style='width: 50%; border: none; text-align: center; vertical-align: top;'>
                    Mengetahui,<br>
                    Kepala Sekolah<br><br><br><br><br>
                    <strong><u>{$principalName}</u></strong><br>
                    NIP. {$principalNip}
                </td>
                <td style='width: 50%; border: none; text-align: center; vertical-align: top;'>
                    {$city}, {$date}<br>
                    Guru Mata Pelajaran<br><br><br><br><br>
                    <strong><u>{$teacherName}</u></strong><br>
                    {$teacherIdLabel}. {$teacherNip}
                </td>
            </tr>
        </table>";
    }

    /**
     * Render Promes PDF Table
     */
    protected function getPromesPdfTable(array $data, int $semester): string
    {
        $months = ($semester == 1) ? [7, 8, 9, 10, 11, 12] : [1, 2, 3, 4, 5, 6];
        $monthNames = [
            1 => 'Januari', 2 => 'Februari', 3 => 'Maret', 4 => 'April', 5 => 'Mei', 6 => 'Juni',
            7 => 'Juli', 8 => 'Agustus', 9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Desember'
        ];

        $html = "<table style='font-size: 7.5pt; width: 100%; border-collapse: collapse; font-family: sans-serif; margin-bottom: 20px;'>
            <thead>
                <tr>
                    <th rowspan='2' width='5%' style='text-align: center; vertical-align: middle; border: 1px solid #000;'>No</th>
                    <th rowspan='2' width='10%' style='text-align: center; vertical-align: middle; border: 1px solid #000;'>Kode</th>
                    <th rowspan='2' style='text-align: center; vertical-align: middle; border: 1px solid #000;'>Tujuan Pembelajaran (TP)</th>
                    <th rowspan='2' width='6%' style='text-align: center; vertical-align: middle; border: 1px solid #000;'>JP</th>";
        
        foreach ($months as $m) {
            $html .= "<th colspan='5' style='text-align: center; border: 1px solid #000; font-size: 7.5pt; font-weight: bold; background-color: #f3f4f6;'>" . $monthNames[$m] . "</th>";
        }
        $html .= "</tr><tr>";
        foreach ($months as $m) {
            for ($w = 1; $w <= 5; $w++) {
                $html .= "<th width='2.8%' style='text-align: center; font-size: 6.5pt; border: 1px solid #000; font-weight: normal;'>W{$w}</th>";
            }
        }
        $html .= "</tr></thead><tbody>";

        $no = 1;
        $promesMap = $data['promesMap'] ?? [];
        foreach ($data['tps'] as $tp) {
            $tpId = $tp['id'];
            $tpSemester = 1;
            if (isset($data['protaMap'][$tpId])) {
                $tpSemester = $data['protaMap'][$tpId]['semester'];
            }
            if ($tpSemester != $semester) continue;

            $html .= "<tr>
                <td style='text-align: center; border: 1px solid #ddd;'>{$no}</td>
                <td style='text-align: center; border: 1px solid #ddd;'><strong>{$tp['code']}</strong></td>
                <td style='border: 1px solid #ddd;'>" . esc($tp['description']) . "</td>
                <td style='text-align: center; border: 1px solid #ddd;'>{$tp['allocated_hours']}</td>";
            
            foreach ($months as $m) {
                for ($w = 1; $w <= 5; $w++) {
                    $val = $promesMap[$tpId][$m][$w] ?? '';
                    $html .= "<td style='text-align: center; border: 1px solid #ddd; font-weight: bold; background-color: " . ($val !== '' ? '#dbeafe' : '') . "'>{$val}</td>";
                }
            }
            $html .= "</tr>";
            $no++;
        }
        
        $html .= "</tbody></table>";
        return $html;
    }

    /**
     * Export to PDF
     */
    public function exportPdf(array $device, string $type, array $data): string
    {
        $settings = $this->settingModel->getSettings() ?? [];
        
        $html = "<html><head><style>
            body { font-family: 'Arial', sans-serif; font-size: 10pt; color: #333; line-height: 1.5; }
            table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 9.5pt; }
            th { background-color: #f3f4f6; padding: 6px; border: 1px solid #999; font-weight: bold; text-align: left; }
            td { padding: 6px; border: 1px solid #ccc; vertical-align: top; }
            .meta-table { width: 100%; border: none; margin-bottom: 20px; font-size: 10pt; }
            .meta-table td { border: none; padding: 2px 8px; }
            .section-title { font-weight: bold; font-size: 11pt; margin-top: 15px; border-bottom: 2px solid #333; padding-bottom: 3px; }
        </style></head><body>";

        if ($type === 'atp') {
            $html .= $this->getPdfHeaderHtml($settings, "ALUR TUJUAN PEMBELAJARAN (ATP)");
            $html .= $this->getPdfMetaTableHtml($device);
            
            $html .= "<div class='section-title'>CAPAIAN PEMBELAJARAN (CP) ELEMEN</div>";
            $html .= "<div style='margin-top: 8px; text-align: justify;'>" . nl2br(esc($device['cp_content'])) . "</div>";

            $html .= "<div class='section-title'>ALUR TUJUAN PEMBELAJARAN</div>";
            $html .= "<table><thead><tr><th width='5%'>No</th><th width='15%'>Kode TP</th><th>Tujuan Pembelajaran (TP)</th><th width='15%'>Alokasi JP</th></tr></thead><tbody>";
            foreach ($data['tps'] as $idx => $tp) {
                $no = $idx + 1;
                $html .= "<tr><td>{$no}</td><td><strong>{$tp['code']}</strong></td><td>" . nl2br(esc($tp['description'])) . "</td><td>{$tp['allocated_hours']} JP</td></tr>";
            }
            $html .= "</tbody></table>";
            $html .= $this->getPdfSignaturesHtml($settings, $device);
        } elseif ($type === 'prota') {
            $html .= $this->getPdfHeaderHtml($settings, "PROGRAM TAHUNAN (PROTA)");
            $html .= $this->getPdfMetaTableHtml($device);
            
            $html .= "<table><thead><tr><th width='5%'>No</th><th width='12%'>Kode TP</th><th>Tujuan Pembelajaran</th><th width='15%'>Semester</th><th width='12%'>Minggu</th><th width='12%'>Alokasi JP</th><th>Keterangan</th></tr></thead><tbody>";
            foreach ($data['prota'] as $idx => $p) {
                $no = $idx + 1;
                $semesterLabel = "Semester " . ($p['semester'] == 1 ? "1 (Ganjil)" : "2 (Genap)");
                $html .= "<tr>
                    <td>{$no}</td>
                    <td><strong>{$p['tp_code']}</strong></td>
                    <td>" . nl2br(esc($p['tp_description'])) . "</td>
                    <td>{$semesterLabel}</td>
                    <td>{$p['allocated_weeks']} Mgg</td>
                    <td>{$p['allocated_hours']} JP</td>
                    <td>" . esc($p['notes']) . "</td>
                </tr>";
            }
            $html .= "</tbody></table>";
            $html .= $this->getPdfSignaturesHtml($settings, $device);
        } elseif ($type === 'promes') {
            $html .= $this->getPdfHeaderHtml($settings, "PROGRAM SEMESTER (PROMES)");
            $html .= $this->getPdfMetaTableHtml($device);

            $html .= "<h4 style='margin: 10px 0 5px 0; font-weight: bold;'>Semester 1 (Ganjil)</h4>";
            $html .= $this->getPromesPdfTable($data, 1);
            
            $html .= "<pagebreak />";
            
            $html .= $this->getPdfHeaderHtml($settings, "PROGRAM SEMESTER (PROMES)");
            $html .= $this->getPdfMetaTableHtml($device);
            $html .= "<h4 style='margin: 10px 0 5px 0; font-weight: bold;'>Semester 2 (Genap)</h4>";
            $html .= $this->getPromesPdfTable($data, 2);
            
            $html .= $this->getPdfSignaturesHtml($settings, $device);
        
        } elseif ($type === 'modul') {
            $html .= $this->getPdfHeaderHtml($settings, "MODUL AJAR");
            $html .= $this->getPdfMetaTableHtml($device);
            $html .= "<div style='text-align: center; margin-top: 50px;'>";
            $html .= "<h3>Pemberitahuan</h3>";
            $html .= "<p>Dokumen Modul Ajar sangat kompleks dan panjang. Agar format tabel dan skenario tetap rapi, silakan gunakan fitur <strong>Export ke Word (DOCX)</strong>.</p>";
            $html .= "</div>";
        } elseif ($type === 'kktp') {
            $html .= $this->getPdfHeaderHtml($settings, "KRITERIA KETERCAPAIAN TUJUAN PEMBELAJARAN (KKTP)");
            $html .= $this->getPdfMetaTableHtml($device);
            
            $intervals = $data['intervals'] ?? [
                'bimbingan' => 59,
                'cukup'     => 69,
                'baik'      => 84
            ];
            $bimbinganMax = $intervals['bimbingan'] ?? 59;
            $cukupMin = $bimbinganMax + 1;
            $cukupMax = $intervals['cukup'] ?? 69;
            $baikMin = $cukupMax + 1;
            $baikMax = $intervals['baik'] ?? 84;
            $sangatBaikMin = $baikMax + 1;
            
            $html .= "<div class='section-title'>A. Pendekatan dan Cara Penggunaan KKTP</div>";
            $html .= "<p style='text-align: justify; margin-top: 8px;'>Kriteria Ketercapaian Tujuan Pembelajaran (KKTP) ini disusun menggunakan pendekatan kombinasi: (1) deskripsi kriteria kualitatif yang menjelaskan capaian peserta didik pada empat level, dan (2) interval nilai/skor kuantitatif (skala 0–100) sebagai pedoman konversi hasil asesmen ke dalam laporan hasil belajar.</p>";
            $html .= "<p style='margin-top: 8px;'>Empat level pencapaian yang digunakan secara konsisten untuk seluruh TP adalah sebagai berikut:</p>";
            
            $html .= "<table style='width: 100%; border-collapse: collapse; margin-top: 10px; margin-bottom: 15px;'>
                <thead>
                    <tr>
                        <th style='width: 25%; text-align: center; border: 1px solid #999; font-weight: bold;'>Level Pencapaian</th>
                        <th style='width: 25%; text-align: center; border: 1px solid #999; font-weight: bold;'>Interval Nilai</th>
                        <th style='border: 1px solid #999; font-weight: bold;'>Makna</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td style='text-align: center; font-weight: bold; background-color: #fee2e2; border: 1px solid #ccc; padding: 6px;'>Perlu Bimbingan</td>
                        <td style='text-align: center; border: 1px solid #ccc; padding: 6px;'>0 – {$bimbinganMax}</td>
                        <td style='border: 1px solid #ccc; padding: 6px;'>Peserta didik belum menguasai sebagian besar indikator TP dan memerlukan pembelajaran remedial secara intensif.</td>
                    </tr>
                    <tr>
                        <td style='text-align: center; font-weight: bold; background-color: #fef3c7; border: 1px solid #ccc; padding: 6px;'>Cukup</td>
                        <td style='text-align: center; border: 1px solid #ccc; padding: 6px;'>{$cukupMin} – {$cukupMax}</td>
                        <td style='border: 1px solid #ccc; padding: 6px;'>Peserta didik mulai menguasai sebagian indikator TP, namun masih memerlukan bimbingan/remedial pada beberapa indikator.</td>
                    </tr>
                    <tr>
                        <td style='text-align: center; font-weight: bold; background-color: #d1fae5; border: 1px solid #ccc; padding: 6px;'>Baik</td>
                        <td style='text-align: center; border: 1px solid #ccc; padding: 6px;'>{$baikMin} – {$baikMax}</td>
                        <td style='border: 1px solid #ccc; padding: 6px;'>Peserta didik menguasai sebagian besar indikator TP dan telah memenuhi kriteria ketercapaian (tuntas).</td>
                    </tr>
                    <tr>
                        <td style='text-align: center; font-weight: bold; background-color: #dbeafe; border: 1px solid #ccc; padding: 6px;'>Sangat Baik</td>
                        <td style='text-align: center; border: 1px solid #ccc; padding: 6px;'>{$sangatBaikMin} – 100</td>
                        <td style='border: 1px solid #ccc; padding: 6px;'>Peserta didik menguasai seluruh indikator TP secara konsisten dan dapat diberikan pengayaan.</td>
                    </tr>
                </tbody>
            </table>";
            
            $html .= "<p style='text-align: justify; margin-bottom: 20px;'>Ketuntasan TP ditetapkan pada batas minimal nilai {$baikMin} (level \"Baik\"). Peserta didik yang memperoleh nilai di bawah {$baikMin} pada suatu TP wajib mengikuti pembelajaran remedial, sedangkan peserta didik yang mencapai level \"Sangat Baik\" (&ge; {$sangatBaikMin}) dapat diberikan pengayaan.</p>";
            
            $html .= "<div class='section-title'>B. KKTP per Tujuan Pembelajaran (TP)</div>";
            $html .= "<p style='text-align: justify; margin-top: 8px; margin-bottom: 15px;'>Setiap TP berikut dilengkapi indikator ketercapaian serta rubrik kriteria pada empat level pencapaian beserta interval nilainya.</p>";
            
            if (empty($data['kktps'])) {
                $html .= "<div style='padding: 20px; border: 1px dashed #ccc; text-align: center;'>Belum ada data KKTP yang disusun atau di-generate untuk perangkat ini.</div>";
            } else {
                foreach ($data['kktps'] as $k) {
                    $html .= "<div style='margin-bottom: 25px; page-break-inside: avoid;'>
                        <div style='background-color: #e0e7ff; padding: 8px; font-weight: bold; border: 1px solid #b4c6fc;'>
                            " . esc($k['code']) . " : " . esc($k['tp_description']) . "
                        </div>
                        <div style='border-left: 1px solid #ccc; border-right: 1px solid #ccc; padding: 8px; background-color: #fafafa;'>
                            <strong>Indikator Ketercapaian:</strong><br>" . nl2br(esc($k['indicators'])) . "
                        </div>
                        <table style='width: 100%; border-collapse: collapse; margin-top: 0;'>
                            <thead>
                                <tr>
                                    <th style='width: 25%; font-size: 8.5pt; text-align: center; background-color: #fee2e2; border: 1px solid #ccc; padding: 5px; color: #000;'>Perlu Bimbingan<br>(0 - {$bimbinganMax})</th>
                                    <th style='width: 25%; font-size: 8.5pt; text-align: center; background-color: #fef3c7; border: 1px solid #ccc; padding: 5px; color: #000;'>Cukup<br>({$cukupMin} - {$cukupMax})</th>
                                    <th style='width: 25%; font-size: 8.5pt; text-align: center; background-color: #d1fae5; border: 1px solid #ccc; padding: 5px; color: #000;'>Baik<br>({$baikMin} - {$baikMax})</th>
                                    <th style='width: 25%; font-size: 8.5pt; text-align: center; background-color: #dbeafe; border: 1px solid #ccc; padding: 5px; color: #000;'>Sangat Baik<br>({$sangatBaikMin} - 100)</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr>
                                    <td style='font-size: 8.5pt; border: 1px solid #ccc; padding: 5px; text-align: justify;'>" . nl2br(esc($k['rubric_bimbingan'])) . "</td>
                                    <td style='font-size: 8.5pt; border: 1px solid #ccc; padding: 5px; text-align: justify;'>" . nl2br(esc($k['rubric_cukup'])) . "</td>
                                    <td style='font-size: 8.5pt; border: 1px solid #ccc; padding: 5px; text-align: justify;'>" . nl2br(esc($k['rubric_baik'])) . "</td>
                                    <td style='font-size: 8.5pt; border: 1px solid #ccc; padding: 5px; text-align: justify;'>" . nl2br(esc($k['rubric_sangat_baik'])) . "</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>";
                }
            }
            
            $html .= "<div class='section-title'>C. Catatan Implementasi</div>";
            $html .= "<ul style='padding-left: 20px; text-align: justify;'>
                <li>KKTP ini digunakan sebagai acuan penyusunan instrumen asesmen formatif dan sumatif pada setiap TP " . esc($device['subject_name']) . " Kelas " . esc($device['grade_name']) . ".</li>
                <li>Guru dapat mengembangkan indikator ketercapaian menjadi kisi-kisi soal atau rubrik penilaian yang lebih rinci sesuai bentuk asesmen yang digunakan.</li>
                <li>KKTP ini bersifat dinamis dan dapat disesuaikan oleh guru mata pelajaran berdasarkan hasil evaluasi pembelajaran.</li>
            </ul>";
            
            $html .= $this->getPdfSignaturesHtml($settings, $device);
        } elseif ($type === 'rpe') {
            $html .= $this->getPdfHeaderHtml($settings, "RINCIAN MINGGU EFEKTIF (RPE)");
            $html .= $this->getPdfMetaTableHtml($device);
            
            // Semester 1 Table
            $html .= "<div class='section-title'>A. Rincian Pekan Efektif Semester Ganjil (Semester 1)</div>";
            $html .= "<table style='width: 100%; border-collapse: collapse; margin-top: 5px; margin-bottom: 15px;'>
                <thead>
                    <tr>
                        <th style='width: 25%; text-align: center; border: 1px solid #999; font-weight: bold;'>Bulan</th>
                        <th style='width: 15%; text-align: center; border: 1px solid #999; font-weight: bold;'>Jml Minggu</th>
                        <th style='width: 15%; text-align: center; border: 1px solid #999; font-weight: bold;'>Mgg Efektif</th>
                        <th style='width: 15%; text-align: center; border: 1px solid #999; font-weight: bold;'>Mgg Tdk Efektif</th>
                        <th style='border: 1px solid #999; font-weight: bold;'>Keterangan Kegiatan / Alasan</th>
                    </tr>
                </thead>
                <tbody>";
            
            $monthsS1 = [7 => 'Juli', 8 => 'Agustus', 9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Desember'];
            $totW1 = 0; $totE1 = 0; $totNE1 = 0;
            foreach ($monthsS1 as $mNum => $mName) {
                $mRpe = $data['rpeData']['sem1'][$mNum] ?? [];
                $w = intval($mRpe['total_weeks'] ?? 4);
                $e = intval($mRpe['effective_weeks'] ?? 0);
                $ne = intval($mRpe['non_effective_weeks'] ?? 0);
                $note = esc($mRpe['note'] ?? '');
                
                $totW1 += $w; $totE1 += $e; $totNE1 += $ne;
                
                $html .= "<tr>
                    <td style='border: 1px solid #ccc; padding: 6px; font-weight: bold;'>{$mName}</td>
                    <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$w}</td>
                    <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$e}</td>
                    <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$ne}</td>
                    <td style='border: 1px solid #ccc; padding: 6px;'>{$note}</td>
                </tr>";
            }
            $html .= "<tr style='background-color: #f3f4f6; font-weight: bold;'>
                <td style='border: 1px solid #ccc; padding: 6px; text-align: right;'>TOTAL</td>
                <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$totW1}</td>
                <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$totE1}</td>
                <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$totNE1}</td>
                <td style='border: 1px solid #ccc; padding: 6px;'></td>
            </tr>";
            $html .= "</tbody></table>";

            // Semester 2 Table
            $html .= "<div class='section-title'>B. Rincian Pekan Efektif Semester Genap (Semester 2)</div>";
            $html .= "<table style='width: 100%; border-collapse: collapse; margin-top: 5px; margin-bottom: 15px;'>
                <thead>
                    <tr>
                        <th style='width: 25%; text-align: center; border: 1px solid #999; font-weight: bold;'>Bulan</th>
                        <th style='width: 15%; text-align: center; border: 1px solid #999; font-weight: bold;'>Jml Minggu</th>
                        <th style='width: 15%; text-align: center; border: 1px solid #999; font-weight: bold;'>Mgg Efektif</th>
                        <th style='width: 15%; text-align: center; border: 1px solid #999; font-weight: bold;'>Mgg Tdk Efektif</th>
                        <th style='border: 1px solid #999; font-weight: bold;'>Keterangan Kegiatan / Alasan</th>
                    </tr>
                </thead>
                <tbody>";
            
            $monthsS2 = [1 => 'Januari', 2 => 'Februari', 3 => 'Maret', 4 => 'April', 5 => 'Mei', 6 => 'Juni'];
            $totW2 = 0; $totE2 = 0; $totNE2 = 0;
            foreach ($monthsS2 as $mNum => $mName) {
                $mRpe = $data['rpeData']['sem2'][$mNum] ?? [];
                $w = intval($mRpe['total_weeks'] ?? 4);
                $e = intval($mRpe['effective_weeks'] ?? 0);
                $ne = intval($mRpe['non_effective_weeks'] ?? 0);
                $note = esc($mRpe['note'] ?? '');
                
                $totW2 += $w; $totE2 += $e; $totNE2 += $ne;
                
                $html .= "<tr>
                    <td style='border: 1px solid #ccc; padding: 6px; font-weight: bold;'>{$mName}</td>
                    <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$w}</td>
                    <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$e}</td>
                    <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$ne}</td>
                    <td style='border: 1px solid #ccc; padding: 6px;'>{$note}</td>
                </tr>";
            }
            $html .= "<tr style='background-color: #f3f4f6; font-weight: bold;'>
                <td style='border: 1px solid #ccc; padding: 6px; text-align: right;'>TOTAL</td>
                <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$totW2}</td>
                <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$totE2}</td>
                <td style='border: 1px solid #ccc; padding: 6px; text-align: center;'>{$totNE2}</td>
                <td style='border: 1px solid #ccc; padding: 6px;'></td>
            </tr>";
            $html .= "</tbody></table>";

            // Summary Section
            $totAnnualEff = $totE1 + $totE2;
            $html .= "<div class='section-title'>C. Rekapitulasi Efektif Tahunan</div>";
            $html .= "<table style='width: 100%; border-collapse: collapse; margin-top: 5px; margin-bottom: 20px;'>
                <tr>
                    <td style='border: 1px solid #ccc; padding: 6px; width: 60%;'>Total Minggu Efektif Semester 1 (Ganjil)</td>
                    <td style='border: 1px solid #ccc; padding: 6px; font-weight: bold;'>{$totE1} Pekan</td>
                </tr>
                <tr>
                    <td style='border: 1px solid #ccc; padding: 6px;'>Total Minggu Efektif Semester 2 (Genap)</td>
                    <td style='border: 1px solid #ccc; padding: 6px; font-weight: bold;'>{$totE2} Pekan</td>
                </tr>
                <tr style='background-color: #f3f4f6; font-weight: bold;'>
                    <td style='border: 1px solid #ccc; padding: 6px;'>Total Minggu Efektif Setahun</td>
                    <td style='border: 1px solid #ccc; padding: 6px;'>{$totAnnualEff} Pekan</td>
                </tr>
            </table>";
            
            $html .= $this->getPdfSignaturesHtml($settings, $device);
        }

        $mpdf = new \Mpdf\Mpdf([
            'mode' => 'utf-8', 
            'format' => 'A4', 
            'orientation' => 'P',
            'margin_top' => 15,
            'margin_bottom' => 15,
            'margin_left' => 15,
            'margin_right' => 15
        ]);
        $mpdf->WriteHTML($html);
        return $mpdf->Output('', 'S');
    }

    /**
     * Export to DOCX
     */
    public function exportDocx(array $device, string $type, array $data): string
    {
        $phpWord = new \PhpOffice\PhpWord\PhpWord();
        $phpWord->setDefaultFontName("Arial");
        $phpWord->setDefaultFontSize(11);
        $settings = $this->settingModel->getSettings() ?? [];

        // Set paper size & margins & orientation
        $sectionSettings = [
            'paperSize'    => 'A4',
            'marginTop'    => 800,
            'marginBottom' => 800,
            'marginLeft'   => 800,
            'marginRight'  => 800,
        ];
        if ($type === 'promes') {
            $sectionSettings['orientation'] = 'landscape';
        }
        $section = $phpWord->addSection($sectionSettings);

        if ($type === 'atp') {
            $this->addWordHeader($section, $settings, "ALUR TUJUAN PEMBELAJARAN (ATP)");
            $this->addWordMetaTable($section, $device);
        } elseif ($type === 'prota') {
            $this->addWordHeader($section, $settings, "PROGRAM TAHUNAN (PROTA)");
            $this->addWordMetaTable($section, $device);

            // Capaian Pembelajaran Elemen
            $cpElements = $this->parseJson($device['cp_elements'] ?? '[]');
            if (!empty($cpElements)) {
                $section->addText('A. Capaian Pembelajaran (CP) Elemen', ['bold' => true, 'size' => 11]);
                $cpTable = $section->addTable(['borderSize' => 6, 'borderColor' => '999999', 'cellMargin' => 80]);
                
                $cpTable->addRow();
                $cpTable->addCell(3000, ['bgColor' => '1a3c6e'])->addText('Elemen', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
                $cpTable->addCell(7000, ['bgColor' => '1a3c6e'])->addText('Capaian Pembelajaran', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
                
                foreach ($cpElements as $el) {
                    $cpTable->addRow();
                    $cpTable->addCell(3000)->addText($el['name'] ?? '', ['bold' => true]);
                    $cpTable->addCell(7000)->addText($el['description'] ?? '');
                }
                $section->addTextBreak(1);
            }

            $section->addText('B. Program Tahunan — Pemetaan Materi', ['bold' => true, 'size' => 11]);
            
            $table = $section->addTable(['borderSize' => 6, 'borderColor' => '999999', 'cellMargin' => 60]);
            $table->addRow();
            $table->addCell(600, ['bgColor' => '1a3c6e'])->addText('No', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $table->addCell(1200, ['bgColor' => '1a3c6e'])->addText('Kode TP', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $table->addCell(4100, ['bgColor' => '1a3c6e'])->addText('Tujuan Pembelajaran', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $table->addCell(1400, ['bgColor' => '1a3c6e'])->addText('Semester', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $table->addCell(1000, ['bgColor' => '1a3c6e'])->addText('Minggu', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $table->addCell(1000, ['bgColor' => '1a3c6e'])->addText('Alokasi JP', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $table->addCell(1000, ['bgColor' => '1a3c6e'])->addText('Keterangan', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);

            $no = 1;
            $totalJp = 0;
            $totalWeeks = 0;
            
            $protaList = $data['prota'] ?? [];
            foreach ($protaList as $p) {
                $table->addRow();
                $table->addCell(600)->addText($no++, null, ['alignment' => Jc::CENTER]);
                $table->addCell(1200)->addText($p['tp_code'] ?? '', ['bold' => true], ['alignment' => Jc::CENTER]);
                $table->addCell(4100)->addText($p['tp_description'] ?? '', ['size' => 11]);
                
                $semesterLabel = "Semester " . (($p['semester'] ?? 1) == 1 ? "1 (Ganjil)" : "2 (Genap)");
                $table->addCell(1400)->addText($semesterLabel, null, ['alignment' => Jc::CENTER]);
                
                $table->addCell(1000)->addText(($p['allocated_weeks'] ?? 0) . " Mgg", null, ['alignment' => Jc::CENTER]);
                $table->addCell(1000)->addText(($p['allocated_hours'] ?? 0) . " JP", null, ['alignment' => Jc::CENTER]);
                $table->addCell(1000)->addText($p['notes'] ?? '');

                $totalJp += intval($p['allocated_hours'] ?? 0);
                $totalWeeks += intval($p['allocated_weeks'] ?? 0);
            }

            // Total Row
            $table->addRow();
            $table->addCell(5600, ['gridSpan' => 3, 'bgColor' => 'F3F4F6'])->addText('TOTAL ALOKASI WAKTU', ['bold' => true], ['alignment' => Jc::RIGHT]);
            $table->addCell(1400, ['bgColor' => 'F3F4F6'])->addText('', null, ['alignment' => Jc::CENTER]);
            $table->addCell(1000, ['bgColor' => 'F3F4F6'])->addText($totalWeeks . " Mgg", ['bold' => true], ['alignment' => Jc::CENTER]);
            $table->addCell(1000, ['bgColor' => 'F3F4F6'])->addText($totalJp . " JP", ['bold' => true], ['alignment' => Jc::CENTER]);
            $table->addCell(1000, ['bgColor' => 'F3F4F6'])->addText('', null, ['alignment' => Jc::CENTER]);

            
            $section->addTextBreak(1);

            $principalName = $settings['principal_name'] ?? $settings['headmaster_name'] ?? '[Kepala Sekolah]';
            $principalNip = $settings['principal_nip'] ?? $settings['headmaster_nip'] ?? '-';
            $teacherName = $device['teacher_name'] ?? 'Guru';
            $teacherNip = $device['teacher_nip'] ?? '-';
            $city = $settings['letter_city'] ?? $settings['city'] ?? '........';
            $ttdTable = $section->addTable(['borderColor' => 'FFFFFF', 'borderSize' => 0]);
            $ttdTable->addRow();
            $kiri = $ttdTable->addCell(7600);
            $kiri->addText('Mengetahui,', ['size' => 11], ['alignment' => Jc::CENTER]);
            $kiri->addText(($device['school_type'] === 'madrasah' ? 'Kepala Madrasah' : 'Kepala Sekolah') . ',', ['size' => 11], ['alignment' => Jc::CENTER]);
            $kiri->addTextBreak(4);
            $kiri->addText($principalName, ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $kiri->addText('NIP. ' . $principalNip, ['size' => 11], ['alignment' => Jc::CENTER]);
            $kanan = $ttdTable->addCell(7600);
            $kanan->addText($city . ', ...............', ['size' => 11], ['alignment' => Jc::CENTER]);
            $kanan->addText('Guru Mata Pelajaran,', ['size' => 11], ['alignment' => Jc::CENTER]);
            $kanan->addTextBreak(4);
            $kanan->addText($teacherName, ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $kanan->addText(guess_id_label($teacherNip) . '. ' . $teacherNip, ['size' => 11], ['alignment' => Jc::CENTER]);
            $section->addTextBreak(1);

        } elseif ($type === 'promes') {
            // Semester 1
            $this->addWordHeader($section, $settings, "PROGRAM SEMESTER (PROMES) — SEMESTER GANJIL");
            $this->addWordMetaTable($section, $device, 16000);
            
            // Table A: Rincian Pekan Efektif S1
            $section->addText('A. Rincian Minggu Efektif Semester Ganjil', ['bold' => true, 'size' => 11]);
            $rpeTable = $section->addTable(['borderSize' => 6, 'borderColor' => '999999', 'cellMargin' => 60]);
            $rpeTable->addRow();
            $rpeTable->addCell(3800, ['bgColor' => '1a3c6e'])->addText('Bulan', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Jml Minggu', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Mgg Tdk Efektif', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Mgg Efektif', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(6200, ['bgColor' => '1a3c6e'])->addText('Keterangan', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);

            $monthsS1 = [7 => 'Juli', 8 => 'Agustus', 9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Desember'];
            $totW = 0; $totNE = 0; $totE = 0;
            foreach ($monthsS1 as $mNum => $mName) {
                $mRpe = $data['rpeData']['sem1'][$mNum] ?? [];
                $w = intval($mRpe['total_weeks'] ?? 4);
                $ne = intval($mRpe['non_effective_weeks'] ?? 0);
                $e = intval($mRpe['effective_weeks'] ?? 0);
                $n = $mRpe['note'] ?? '';
                $rpeTable->addRow();
                $rpeTable->addCell(3800)->addText($mName, ['bold' => true]);
                $rpeTable->addCell(2000)->addText($w, null, ['alignment' => Jc::CENTER]);
                $rpeTable->addCell(2000)->addText($ne, null, ['alignment' => Jc::CENTER]);
                $rpeTable->addCell(2000)->addText($e, null, ['alignment' => Jc::CENTER]);
                $rpeTable->addCell(6200)->addText($n);
 
                $totW += $w; $totNE += $ne; $totE += $e;
            }
            $rpeTable->addRow();
            $rpeTable->addCell(3800, ['bgColor' => 'F3F4F6'])->addText('TOTAL', ['bold' => true], ['alignment' => Jc::RIGHT]);
            $rpeTable->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totW, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totNE, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totE, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(6200, ['bgColor' => 'F3F4F6'])->addText('', null, ['alignment' => Jc::CENTER]);

            $section->addTextBreak(1);

            $section->addText('B. Distribusi Materi & Alokasi Waktu per Bulan', ['bold' => true, 'size' => 11]);
            if (method_exists($this, 'addPromesWordTable')) {
                $this->addPromesWordTable($section, $data, 1);
            }

            // Page Break for Semester 2
            $section->addPageBreak();

            // Semester 2
            $this->addWordHeader($section, $settings, "PROGRAM SEMESTER (PROMES) — SEMESTER GENAP");
            $this->addWordMetaTable($section, $device, 16000);

            // Table A: Rincian Pekan Efektif S2
            $section->addText('A. Rincian Minggu Efektif Semester Genap', ['bold' => true, 'size' => 11]);
            $rpeTable2 = $section->addTable(['borderSize' => 6, 'borderColor' => '999999', 'cellMargin' => 60]);
            $rpeTable2->addRow();
            $rpeTable2->addCell(3800, ['bgColor' => '1a3c6e'])->addText('Bulan', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Jml Minggu', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Mgg Tdk Efektif', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Mgg Efektif', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(6200, ['bgColor' => '1a3c6e'])->addText('Keterangan', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);

            $monthsS2 = [1 => 'Januari', 2 => 'Februari', 3 => 'Maret', 4 => 'April', 5 => 'Mei', 6 => 'Juni'];
            $totW = 0; $totNE = 0; $totE = 0;
            foreach ($monthsS2 as $mNum => $mName) {
                $mRpe = $data['rpeData']['sem2'][$mNum] ?? [];
                $w = intval($mRpe['total_weeks'] ?? 4);
                $ne = intval($mRpe['non_effective_weeks'] ?? 0);
                $e = intval($mRpe['effective_weeks'] ?? 0);
                $n = $mRpe['note'] ?? '';
                $rpeTable2->addRow();
                $rpeTable2->addCell(3800)->addText($mName, ['bold' => true]);
                $rpeTable2->addCell(2000)->addText($w, null, ['alignment' => Jc::CENTER]);
                $rpeTable2->addCell(2000)->addText($ne, null, ['alignment' => Jc::CENTER]);
                $rpeTable2->addCell(2000)->addText($e, null, ['alignment' => Jc::CENTER]);
                $rpeTable2->addCell(6200)->addText($n);
 
                $totW += $w; $totNE += $ne; $totE += $e;
            }
            $rpeTable2->addRow();
            $rpeTable2->addCell(3800, ['bgColor' => 'F3F4F6'])->addText('TOTAL', ['bold' => true], ['alignment' => Jc::RIGHT]);
            $rpeTable2->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totW, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totNE, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totE, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(6200, ['bgColor' => 'F3F4F6'])->addText('', null, ['alignment' => Jc::CENTER]);

            $section->addTextBreak(1);

            $section->addText('B. Distribusi Materi & Alokasi Waktu per Bulan', ['bold' => true, 'size' => 11]);
            if (method_exists($this, 'addPromesWordTable')) {
                $this->addPromesWordTable($section, $data, 2);
            }
            
            
            $section->addTextBreak(1);

            $principalName = $settings['principal_name'] ?? $settings['headmaster_name'] ?? '[Kepala Sekolah]';
            $principalNip = $settings['principal_nip'] ?? $settings['headmaster_nip'] ?? '-';
            $teacherName = $device['teacher_name'] ?? 'Guru';
            $teacherNip = $device['teacher_nip'] ?? '-';
            $city = $settings['letter_city'] ?? $settings['city'] ?? '........';
            $ttdTable = $section->addTable(['borderColor' => 'FFFFFF', 'borderSize' => 0]);
            $ttdTable->addRow();
            $kiri = $ttdTable->addCell(7600);
            $kiri->addText('Mengetahui,', ['size' => 11], ['alignment' => Jc::CENTER]);
            $kiri->addText(($device['school_type'] === 'madrasah' ? 'Kepala Madrasah' : 'Kepala Sekolah') . ',', ['size' => 11], ['alignment' => Jc::CENTER]);
            $kiri->addTextBreak(4);
            $kiri->addText($principalName, ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $kiri->addText('NIP. ' . $principalNip, ['size' => 11], ['alignment' => Jc::CENTER]);
            $kanan = $ttdTable->addCell(7600);
            $kanan->addText($city . ', ...............', ['size' => 11], ['alignment' => Jc::CENTER]);
            $kanan->addText('Guru Mata Pelajaran,', ['size' => 11], ['alignment' => Jc::CENTER]);
            $kanan->addTextBreak(4);
            $kanan->addText($teacherName, ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $kanan->addText(guess_id_label($teacherNip) . '. ' . $teacherNip, ['size' => 11], ['alignment' => Jc::CENTER]);
            $section->addTextBreak(1);

        } elseif ($type === 'modul') {
            $m = $data['modul'];
            $identity = $this->parseJson($m['identity']);
            $core = $this->parseJson($m['core_components']);
            $diff = $this->parseJson($m['differentiation']);
            $assessment = $this->parseJson($m['assessment']);
            $followUp = $this->parseJson($m['follow_up']);
            $reflection = $this->parseJson($m['reflection']);
            $char = $this->parseJson($m['character_integration']); // Lampiran data

            $this->addWordHeader($section, $settings, "MODUL AJAR - " . strtoupper($m['topic']));
            $this->addWordMetaTable($section, $device);

            $section->addText('A. IDENTITAS DIRI & INFORMASI UMUM', ['bold' => true, 'size' => 11]);
            $table = $section->addTable(['borderSize' => 6, 'borderColor' => '999999', 'cellMargin' => 80]);
            
            $table->addRow();
            $table->addCell(3000)->addText('Nama Sekolah');
            $table->addCell(7000)->addText($identity['school_name'] ?? $settings['school_name'] ?? '');

            $table->addRow();
            $table->addCell(3000)->addText('Mata Pelajaran');
            $table->addCell(7000)->addText($identity['subject'] ?? $device['subject_name'] ?? '');

            $table->addRow();
            $table->addCell(3000)->addText('Kelas / Tingkat');
            $table->addCell(7000)->addText("Kelas " . ($identity['grade'] ?? $device['grade_name'] ?? ''));

            $section->addTextBreak(1);
            $section->addText('B. KOMPETENSI INTI & MATERI ESENSIAL', ['bold' => true, 'size' => 11]);
            $section->addText("Tujuan Pembelajaran: ", ['bold' => true]);
            $section->addText($core['tp'] ?? $m['topic'] ?? '');
            
            $section->addText("Materi Esensial: ", ['bold' => true]);
            $materi = $core['materi_esensial'] ?? '';
            if (is_array($materi)) {
                $section->addText(implode(', ', $materi));
            } else {
                // Strip HTML tags if any and replace newlines with TextBreak
                $materiText = strip_tags($materi);
                $lines = explode("\n", $materiText);
                foreach ($lines as $line) {
                    if (trim($line) !== '') $section->addText(trim($line));
                }
            }

            $section->addText("Pemahaman Bermakna: ", ['bold' => true]);
            $section->addText($core['pemahaman_bermakna'] ?? '');

            $section->addText("Pertanyaan Pemantik: ", ['bold' => true]);
            $pemantiks = $core['pemantik'] ?? [];
            if (is_array($pemantiks)) {
                foreach ($pemantiks as $p) {
                    $section->addText("- " . $p);
                }
            }

            $section->addTextBreak(1);
            $section->addText('C. KEGIATAN PEMBELAJARAN (' . ($core['model_pembelajaran'] ?? 'PBL/PjBL') . ')', ['bold' => true, 'size' => 11]);
            $kegiatans = $core['kegiatan_pembelajaran'] ?? [];
            if (is_array($kegiatans)) {
                foreach ($kegiatans as $keg) {
                    $section->addText("Pertemuan Ke-" . ($keg['pertemuan'] ?? 1), ['bold' => true]);
                    $section->addText("Pendahuluan: " . ($keg['tahap_pendahuluan'] ?? ''));
                    $section->addText("Kegiatan Inti: " . ($keg['tahap_inti'] ?? ''));
                    $section->addText("Penutup: " . ($keg['tahap_penutup'] ?? ''));
                    $section->addTextBreak(1);
                }
            }

            $section->addText('D. STRATEGI PEMBELAJARAN DIFERENSIASI', ['bold' => true, 'size' => 11]);
            $section->addText("Diferensiasi Konten: " . (isset($diff['konten']) ? implode(', ', (array)$diff['konten']) : '-'));
            $section->addText("Diferensiasi Proses: " . (isset($diff['proses']) ? implode(', ', (array)$diff['proses']) : '-'));
            $section->addText("Diferensiasi Produk: " . (isset($diff['produk']) ? implode(', ', (array)$diff['produk']) : '-'));
            $section->addTextBreak(1);

            $section->addText('E. ASESMEN & REFLEKSI', ['bold' => true, 'size' => 11]);
            $section->addText("Asesmen Diagnostik (Awal): " . ($assessment['diagnostik'] ?? '-'));
            $section->addText("Asesmen Formatif (Proses): " . ($assessment['formatif'] ?? '-'));
            $section->addText("Asesmen Sumatif (Akhir): " . ($assessment['sumatif'] ?? '-'));
            $section->addText("Refleksi Guru: " . (isset($reflection['refleksi_guru']) ? implode(', ', (array)$reflection['refleksi_guru']) : '-'));
            $section->addText("Refleksi Siswa: " . (isset($reflection['refleksi_siswa']) ? implode(', ', (array)$reflection['refleksi_siswa']) : '-'));
            $section->addTextBreak(1);

            $section->addText('F. TINDAK LANJUT', ['bold' => true, 'size' => 11]);
            $section->addText("Remedial: " . ($followUp['remedial'] ?? '-'));
            $section->addText("Pengayaan: " . ($followUp['pengayaan'] ?? '-'));
            $section->addTextBreak(1);

            $section->addText('G. LAMPIRAN', ['bold' => true, 'size' => 11]);
            $section->addText("Kerangka LKPD: " . (is_array($char['lkpd'] ?? '') ? implode(', ', $char['lkpd']) : ($char['lkpd'] ?? '-')));
            $section->addText("Glosarium: " . (isset($char['glosarium']) ? implode(', ', (array)$char['glosarium']) : '-'));

            $this->addWordSignatures($section, $settings, $device);
        } elseif ($type === 'kktp') {
            $this->addWordHeader($section, $settings, "KRITERIA KETERCAPAIAN TUJUAN PEMBELAJARAN (KKTP)");
            $this->addWordMetaTable($section, $device);

            $intervals = $data['intervals'] ?? [
                'bimbingan' => 59,
                'cukup'     => 69,
                'baik'      => 84
            ];
            $bimbinganMax = $intervals['bimbingan'] ?? 59;
            $cukupMin = $bimbinganMax + 1;
            $cukupMax = $intervals['cukup'] ?? 69;
            $baikMin = $cukupMax + 1;
            $baikMax = $intervals['baik'] ?? 84;
            $sangatBaikMin = $baikMax + 1;

            $section->addText('A. Pendekatan dan Cara Penggunaan KKTP', ['bold' => true, 'size' => 11]);
            $section->addText(
                'Kriteria Ketercapaian Tujuan Pembelajaran (KKTP) ini disusun menggunakan pendekatan kombinasi: (1) deskripsi kriteria kualitatif yang menjelaskan capaian peserta didik pada empat level, dan (2) interval nilai/skor kuantitatif (skala 0–100) sebagai pedoman konversi hasil asesmen ke dalam laporan hasil belajar.',
                ['size' => 11],
                ['alignment' => Jc::BOTH]
            );
            $section->addTextBreak(1);

            // Table of intervals
            $tableIntervals = $section->addTable(['borderSize' => 6, 'borderColor' => '999999', 'cellMargin' => 80]);
            
            $tableIntervals->addRow();
            $tableIntervals->addCell(3000, ['bgColor' => 'F3F4F6'])->addText('Level Pencapaian', ['bold' => true], ['alignment' => Jc::CENTER]);
            $tableIntervals->addCell(2000, ['bgColor' => 'F3F4F6'])->addText('Interval Nilai', ['bold' => true], ['alignment' => Jc::CENTER]);
            $tableIntervals->addCell(5000, ['bgColor' => 'F3F4F6'])->addText('Makna', ['bold' => true], ['alignment' => Jc::CENTER]);

            $tableIntervals->addRow();
            $tableIntervals->addCell(3000, ['bgColor' => 'FEE2E2'])->addText('Perlu Bimbingan', ['bold' => true, 'color' => 'B91C1C'], ['alignment' => Jc::CENTER]);
            $tableIntervals->addCell(2000)->addText("0 – {$bimbinganMax}", ['bold' => true], ['alignment' => Jc::CENTER]);
            $tableIntervals->addCell(5000)->addText('Peserta didik belum menguasai sebagian besar indikator TP dan memerlukan pembelajaran remedial secara intensif.');

            $tableIntervals->addRow();
            $tableIntervals->addCell(3000, ['bgColor' => 'FEF3C7'])->addText('Cukup', ['bold' => true, 'color' => '92400E'], ['alignment' => Jc::CENTER]);
            $tableIntervals->addCell(2000)->addText("{$cukupMin} – {$cukupMax}", ['bold' => true], ['alignment' => Jc::CENTER]);
            $tableIntervals->addCell(5000)->addText('Peserta didik mulai menguasai sebagian indikator TP, namun masih memerlukan bimbingan/remedial pada beberapa indikator.');

            $tableIntervals->addRow();
            $tableIntervals->addCell(3000, ['bgColor' => 'D1FAE5'])->addText('Baik', ['bold' => true, 'color' => '065F46'], ['alignment' => Jc::CENTER]);
            $tableIntervals->addCell(2000)->addText("{$baikMin} – {$baikMax}", ['bold' => true], ['alignment' => Jc::CENTER]);
            $tableIntervals->addCell(5000)->addText('Peserta didik menguasai sebagian besar indikator TP dan telah memenuhi kriteria ketercapaian (tuntas).');

            $tableIntervals->addRow();
            $tableIntervals->addCell(3000, ['bgColor' => 'DBEAFE'])->addText('Sangat Baik', ['bold' => true, 'color' => '1E40AF'], ['alignment' => Jc::CENTER]);
            $tableIntervals->addCell(2000)->addText("{$sangatBaikMin} – 100", ['bold' => true], ['alignment' => Jc::CENTER]);
            $tableIntervals->addCell(5000)->addText('Peserta didik menguasai seluruh indikator TP secara konsisten dan dapat diberikan pengayaan.');

            $section->addTextBreak(1);
            $section->addText(
                "Ketuntasan TP ditetapkan pada batas minimal nilai {$baikMin} (level \"Baik\"). Peserta didik yang memperoleh nilai di bawah {$baikMin} pada suatu TP wajib mengikuti pembelajaran remedial, sedangkan peserta didik yang mencapai level \"Sangat Baik\" (>= {$sangatBaikMin}) dapat diberikan pengayaan.",
                ['size' => 11],
                ['alignment' => Jc::BOTH]
            );
            $section->addTextBreak(1);

            $section->addText('B. KKTP per Tujuan Pembelajaran (TP)', ['bold' => true, 'size' => 11]);
            $section->addText(
                'Setiap TP berikut dilengkapi indikator ketercapaian serta rubrik kriteria pada empat level pencapaian beserta interval nilainya.',
                ['size' => 11]
            );
            $section->addTextBreak(1);

            if (empty($data['kktps'])) {
                $section->addText('Belum ada data KKTP.', ['italic' => true]);
            } else {
                foreach ($data['kktps'] as $k) {
                    // TP Header table / container
                    $tpTable = $section->addTable(['borderSize' => 6, 'borderColor' => 'CCCCCC', 'cellMargin' => 80]);
                    
                    // Header Row
                    $tpTable->addRow();
                    $tpCell = $tpTable->addCell(10000, ['bgColor' => 'E0E7FF']);
                    $tpCell->addText($k['code'] . " : " . $k['tp_description'], ['bold' => true, 'size' => 11, 'color' => '1a3c6e']);

                    // Indicators Row
                    $tpTable->addRow();
                    $indCell = $tpTable->addCell(10000, ['bgColor' => 'FAFAFA']);
                    $indCell->addText('Indikator Ketercapaian:', ['bold' => true, 'size' => 11]);
                    
                    $lines = explode("\n", $k['indicators'] ?? '');
                    foreach ($lines as $line) {
                        if (trim($line) !== '') $indCell->addText(trim($line), ['size' => 11]);
                    }

                    $section->addTextBreak(1);

                    // Rubric Table
                    $rubricTable = $section->addTable(['borderSize' => 6, 'borderColor' => '999999', 'cellMargin' => 60]);
                    
                    $rubricTable->addRow();
                    $rubricTable->addCell(2500, ['bgColor' => 'FEE2E2'])->addText("Perlu Bimbingan (0–{$bimbinganMax})", ['bold' => true, 'size' => 8.5, 'color' => 'B91C1C'], ['alignment' => Jc::CENTER]);
                    $rubricTable->addCell(2500, ['bgColor' => 'FEF3C7'])->addText("Cukup ({$cukupMin}–{$cukupMax})", ['bold' => true, 'size' => 8.5, 'color' => '92400E'], ['alignment' => Jc::CENTER]);
                    $rubricTable->addCell(2500, ['bgColor' => 'D1FAE5'])->addText("Baik ({$baikMin}–{$baikMax})", ['bold' => true, 'size' => 8.5, 'color' => '065F46'], ['alignment' => Jc::CENTER]);
                    $rubricTable->addCell(2500, ['bgColor' => 'DBEAFE'])->addText("Sangat Baik ({$sangatBaikMin}–100)", ['bold' => true, 'size' => 8.5, 'color' => '1E40AF'], ['alignment' => Jc::CENTER]);

                    $rubricTable->addRow();
                    
                    // Add cell content
                    $linesB = explode("\n", $k['rubric_bimbingan'] ?? '');
                    $cellB = $rubricTable->addCell(2500);
                    foreach ($linesB as $l) {
                        if (trim($l) !== '') $cellB->addText(trim($l), ['size' => 8.5]);
                    }

                    $linesC = explode("\n", $k['rubric_cukup'] ?? '');
                    $cellC = $rubricTable->addCell(2500);
                    foreach ($linesC as $l) {
                        if (trim($l) !== '') $cellC->addText(trim($l), ['size' => 8.5]);
                    }

                    $linesBa = explode("\n", $k['rubric_baik'] ?? '');
                    $cellBa = $rubricTable->addCell(2500);
                    foreach ($linesBa as $l) {
                        if (trim($l) !== '') $cellBa->addText(trim($l), ['size' => 8.5]);
                    }

                    $linesSb = explode("\n", $k['rubric_sangat_baik'] ?? '');
                    $cellSb = $rubricTable->addCell(2500);
                    foreach ($linesSb as $l) {
                        if (trim($l) !== '') $cellSb->addText(trim($l), ['size' => 8.5]);
                    }

                    $section->addTextBreak(2);
                }
            }

            $section->addText('C. Catatan Implementasi', ['bold' => true, 'size' => 11]);
            $section->addText("- KKTP ini digunakan sebagai acuan penyusunan instrumen asesmen formatif dan sumatif pada setiap TP " . $device['subject_name'] . " Kelas " . $device['grade_name'] . ".", ['size' => 11]);
            $section->addText("- Guru dapat mengembangkan indikator ketercapaian menjadi kisi-kisi soal atau rubrik penilaian yang lebih rinci sesuai bentuk asesmen yang digunakan.", ['size' => 11]);
            $section->addText("- KKTP ini bersifat dinamis dan dapat disesuaikan oleh guru mata pelajaran berdasarkan hasil evaluasi pembelajaran.", ['size' => 11]);

            $this->addWordSignatures($section, $settings, $device);
        } elseif ($type === 'rpe') {
            $this->addWordHeader($section, $settings, "RINCIAN PEKAN EFEKTIF (RPE)");
            $this->addWordMetaTable($section, $device);
            
            // Semester 1
            $section->addText('A. Rincian Pekan Efektif Semester Ganjil (Semester 1)', ['bold' => true, 'size' => 11]);
            $rpeTable = $section->addTable(['borderSize' => 6, 'borderColor' => '999999', 'cellMargin' => 60]);
            $rpeTable->addRow();
            $rpeTable->addCell(3800, ['bgColor' => '1a3c6e'])->addText('Bulan', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Jml Minggu', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Mgg Efektif', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Mgg Tdk Efektif', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(6200, ['bgColor' => '1a3c6e'])->addText('Keterangan', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);

            $monthsS1 = [7 => 'Juli', 8 => 'Agustus', 9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'Desember'];
            $totW = 0; $totNE = 0; $totE = 0;
            foreach ($monthsS1 as $mNum => $mName) {
                $mRpe = $data['rpeData']['sem1'][$mNum] ?? [];
                $w = intval($mRpe['total_weeks'] ?? 4);
                $ne = intval($mRpe['non_effective_weeks'] ?? 0);
                $e = intval($mRpe['effective_weeks'] ?? 0);
                $n = $mRpe['note'] ?? '';
                $rpeTable->addRow();
                $rpeTable->addCell(3800)->addText($mName, ['bold' => true]);
                $rpeTable->addCell(2000)->addText($w, null, ['alignment' => Jc::CENTER]);
                $rpeTable->addCell(2000)->addText($e, null, ['alignment' => Jc::CENTER]);
                $rpeTable->addCell(2000)->addText($ne, null, ['alignment' => Jc::CENTER]);
                $rpeTable->addCell(6200)->addText($n);
 
                $totW += $w; $totNE += $ne; $totE += $e;
            }
            $rpeTable->addRow();
            $rpeTable->addCell(3800, ['bgColor' => 'F3F4F6'])->addText('TOTAL', ['bold' => true], ['alignment' => Jc::RIGHT]);
            $rpeTable->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totW, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totE, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totNE, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable->addCell(6200, ['bgColor' => 'F3F4F6'])->addText('', null, ['alignment' => Jc::CENTER]);

            $section->addTextBreak(1);
            $s1Eff = $totE;

            // Semester 2
            $section->addText('B. Rincian Pekan Efektif Semester Genap (Semester 2)', ['bold' => true, 'size' => 11]);
            $rpeTable2 = $section->addTable(['borderSize' => 6, 'borderColor' => '999999', 'cellMargin' => 60]);
            $rpeTable2->addRow();
            $rpeTable2->addCell(3800, ['bgColor' => '1a3c6e'])->addText('Bulan', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Jml Minggu', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Mgg Efektif', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Mgg Tdk Efektif', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(6200, ['bgColor' => '1a3c6e'])->addText('Keterangan', ['bold' => true, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);

            $monthsS2 = [1 => 'Januari', 2 => 'Februari', 3 => 'Maret', 4 => 'April', 5 => 'Mei', 6 => 'Juni'];
            $totW = 0; $totNE = 0; $totE = 0;
            foreach ($monthsS2 as $mNum => $mName) {
                $mRpe = $data['rpeData']['sem2'][$mNum] ?? [];
                $w = intval($mRpe['total_weeks'] ?? 4);
                $ne = intval($mRpe['non_effective_weeks'] ?? 0);
                $e = intval($mRpe['effective_weeks'] ?? 0);
                $n = $mRpe['note'] ?? '';
                $rpeTable2->addRow();
                $rpeTable2->addCell(3800)->addText($mName, ['bold' => true]);
                $rpeTable2->addCell(2000)->addText($w, null, ['alignment' => Jc::CENTER]);
                $rpeTable2->addCell(2000)->addText($e, null, ['alignment' => Jc::CENTER]);
                $rpeTable2->addCell(2000)->addText($ne, null, ['alignment' => Jc::CENTER]);
                $rpeTable2->addCell(6200)->addText($n);
 
                $totW += $w; $totNE += $ne; $totE += $e;
            }
            $rpeTable2->addRow();
            $rpeTable2->addCell(3800, ['bgColor' => 'F3F4F6'])->addText('TOTAL', ['bold' => true], ['alignment' => Jc::RIGHT]);
            $rpeTable2->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totW, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totE, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(2000, ['bgColor' => 'F3F4F6'])->addText($totNE, ['bold' => true], ['alignment' => Jc::CENTER]);
            $rpeTable2->addCell(6200, ['bgColor' => 'F3F4F6'])->addText('', null, ['alignment' => Jc::CENTER]);

            $section->addTextBreak(1);
            $s2Eff = $totE;

            // Summary Info
            $section->addText('C. Rekapitulasi Efektif Tahunan', ['bold' => true, 'size' => 11]);
            $annualTable = $section->addTable(['borderSize' => 6, 'borderColor' => '999999', 'cellMargin' => 60]);
            $annualTable->addRow();
            $annualTable->addCell(5000)->addText('Total Minggu Efektif Semester 1 (Ganjil)');
            $annualTable->addCell(3000)->addText($s1Eff . ' Pekan', ['bold' => true]);
            $annualTable->addRow();
            $annualTable->addCell(5000)->addText('Total Minggu Efektif Semester 2 (Genap)');
            $annualTable->addCell(3000)->addText($s2Eff . ' Pekan', ['bold' => true]);
            $annualTable->addRow();
            $annualTable->addCell(5000)->addText('Total Minggu Efektif Setahun');
            $annualTable->addCell(3000)->addText(($s1Eff + $s2Eff) . ' Pekan', ['bold' => true]);

            $section->addTextBreak(1);
            $this->addWordSignatures($section, $settings, $device);
        }

        // Save Word document to temporary buffer
        $tempFile = tempnam(sys_get_temp_dir(), 'ld_docx_');
        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        $objWriter->save($tempFile);
        
        $content = file_get_contents($tempFile);
        unlink($tempFile);
        
        return $content;
    }

    /**
     * Helper to write Kop to Word Document
     */
    protected function addWordHeader($section, array $settings, string $docTitle)
    {
        // ── Judul Dokumen — bersih tanpa KOP ─────────────────────────────
        // Guru bisa menambahkan KOP sekolah sendiri sesuai format resmi masing-masing.

        // Deteksi orientasi halaman secara dinamis untuk menentukan lebar dxa yang pas
        $orientation = $section->getStyle()->getOrientation();
        $isLandscape = ($orientation === 'landscape');
        $totalWidth  = $isLandscape ? 15200 : 10300;

        // Judul utama dalam kotak header dengan lebar penuh dxa menyentuh margin
        $titleTable = $section->addTable([
            'borderSize'  => 12,
            'borderColor' => '1a3c6e',
            'cellMargin'  => 120,
            'width'       => $totalWidth,
            'unit'        => 'dxa',
        ]);
        $titleTable->addRow();
        $cell = $titleTable->addCell($totalWidth, ['bgColor' => '1a3c6e']);
        $cell->addText($docTitle, ['bold' => true, 'size' => 13, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $section->addTextBreak(1);
    }

    /**
     * Helper to write Signatures to Word Document
     */
    protected function addWordSignatures($section, array $settings, array $device)
    {
        $principalName = $settings['principal_name'] ?? '[Nama Kepala Sekolah]';
        $principalNip = $settings['principal_nip'] ?? '-';
        $teacherName = $device['teacher_name'] ?? '[Nama Guru]';
        $teacherNip = $device['teacher_nip'] ?? '-';
        $city = $settings['letter_city'] ?? $settings['city'] ?? '........................';
        if (empty(trim($city, '. '))) {
            $city = '........................';
        }

        $section->addTextBreak(2);
        $table = $section->addTable(['borderColor' => 'FFFFFF', 'borderSize' => 0]);
        $table->addRow();
        
        $cell1 = $table->addCell(6000);
        $cell1->addText('Mengetahui,', null, ['alignment' => Jc::CENTER]);
        $cell1->addText(($device['school_type'] === 'madrasah' ? 'Kepala Madrasah' : 'Kepala Sekolah') . ',', null, ['alignment' => Jc::CENTER]);
        $cell1->addTextBreak(3);
        $cell1->addText($principalName, ['bold' => true, 'underline' => 'single'], ['alignment' => Jc::CENTER]);
        $cell1->addText("NIP. {$principalNip}", null, ['alignment' => Jc::CENTER]);

        $cell2 = $table->addCell(6000);
        $cell2->addText("{$city}, ......................................", null, ['alignment' => Jc::CENTER]);
        $cell2->addText('Guru Mata Pelajaran,', null, ['alignment' => Jc::CENTER]);
        $cell2->addTextBreak(3);
        $cell2->addText($teacherName, ['bold' => true, 'underline' => 'single'], ['alignment' => Jc::CENTER]);
        $cell2->addText(guess_id_label($teacherNip) . ". " . $teacherNip, null, ['alignment' => Jc::CENTER]);
    }

    /**
     * Helper to write Meta Table to Word Document
     */
    protected function addWordMetaTable($section, array $device)
    {
        $settings = $this->settingModel->getSettings() ?? [];
        $schoolName = $settings['school_name'] ?? 'SIMAK';
        $schoolLabel = ($device['school_type'] === 'madrasah') ? 'Nama Madrasah' : 'Nama Sekolah';
        
        $teacherName = $device['teacher_name'] ?? '-';
        $teacherNip  = $device['teacher_nip'] ?? '-';
        $fontStyle   = ['size' => 11];
        $boldStyle   = ['size' => 11, 'bold' => true];

        // Deteksi orientasi halaman secara dinamis untuk menentukan lebar dxa yang pas
        $orientation = $section->getStyle()->getOrientation();
        $isLandscape = ($orientation === 'landscape');
        $totalWidth  = $isLandscape ? 15200 : 10300;

        // Distribusi lebar kolom 30% : 70%
        $col1Width = round($totalWidth * 0.3);
        $col2Width = $totalWidth - $col1Width;

        // Tabel dengan lebar penuh dxa menyentuh margin kiri dan kanan
        $table = $section->addTable([
            'borderColor' => 'CCCCCC',
            'borderSize'  => 6,
            'cellMargin'  => 80,
            'width'       => $totalWidth,
            'unit'        => 'dxa'
        ]);

        // Baris 1: Nama Lembaga
        $table->addRow();
        $table->addCell($col1Width, ['bgColor' => 'F9FAFB'])->addText($schoolLabel, $fontStyle);
        $table->addCell($col2Width)->addText($schoolName, $boldStyle);

        // Baris 2: Mata Pelajaran
        $table->addRow();
        $table->addCell($col1Width, ['bgColor' => 'F9FAFB'])->addText('Mata Pelajaran', $fontStyle);
        $table->addCell($col2Width)->addText($device['subject_name'], $boldStyle);

        // Baris 3: Kelas / Fase
        $table->addRow();
        $table->addCell($col1Width, ['bgColor' => 'F9FAFB'])->addText('Kelas / Fase', $fontStyle);
        $table->addCell($col2Width)->addText('Kelas ' . $device['grade_name'] . ' / Fase ' . $device['phase'], $boldStyle);

        // Baris 4: Tahun Ajaran
        $table->addRow();
        $table->addCell($col1Width, ['bgColor' => 'F9FAFB'])->addText('Tahun Ajaran', $fontStyle);
        $table->addCell($col2Width)->addText($device['academic_year_name'], $boldStyle);

        // Baris 5: Guru Pengampu
        $table->addRow();
        $table->addCell($col1Width, ['bgColor' => 'F9FAFB'])->addText('Guru Pengampu', $fontStyle);
        $table->addCell($col2Width)->addText($teacherName, $boldStyle);

        // Baris 6: NIP
        $table->addRow();
        $table->addCell($col1Width, ['bgColor' => 'F9FAFB'])->addText(guess_id_label($teacherNip), $fontStyle);
        $table->addCell($col2Width)->addText($teacherNip ?: '-', $boldStyle);

        $section->addTextBreak(1);
    }

    /**
     * Promes Word Table Helper
     */
    protected function addPromesWordTable($section, array $data, int $semester)
    {
        $months = ($semester == 1) ? [7, 8, 9, 10, 11, 12] : [1, 2, 3, 4, 5, 6];
        $monthNames = [
            1 => 'Jan', 2 => 'Feb', 3 => 'Mar', 4 => 'Apr', 5 => 'Mei', 6 => 'Jun',
            7 => 'Jul', 8 => 'Agu', 9 => 'Sep', 10 => 'Okt', 11 => 'Nov', 12 => 'Des'
        ];

        $table = $section->addTable(['borderSize' => 6, 'borderColor' => '999999', 'cellMargin' => 40]);
        
        // Row 1: Headers
        $table->addRow();
        $table->addCell(600, ['vMerge' => 'restart', 'bgColor' => 'F3F4F6'])->addText('No', ['bold' => true]);
        $table->addCell(1000, ['vMerge' => 'restart', 'bgColor' => 'F3F4F6'])->addText('Kode', ['bold' => true]);
        $table->addCell(3000, ['vMerge' => 'restart', 'bgColor' => 'F3F4F6'])->addText('Tujuan Pembelajaran', ['bold' => true]);
        $table->addCell(600, ['vMerge' => 'restart', 'bgColor' => 'F3F4F6'])->addText('JP', ['bold' => true]);

        foreach ($months as $m) {
            $table->addCell(1800, ['gridSpan' => 5, 'bgColor' => 'DBEAFE'])->addText($monthNames[$m], ['bold' => true, 'color' => '1E40AF'], ['alignment' => Jc::CENTER]);
        }

        // Row 2: Weeks
        $table->addRow();
        $table->addCell(600, ['vMerge' => 'continue']);
        $table->addCell(1000, ['vMerge' => 'continue']);
        $table->addCell(3000, ['vMerge' => 'continue']);
        $table->addCell(600, ['vMerge' => 'continue']);

        $semKey = ($semester == 1) ? 'sem1' : 'sem2';
        $rpeSem = $data['rpeData'][$semKey] ?? [];

        foreach ($months as $m) {
            $mRpe = $rpeSem[$m] ?? [];
            $weekStatuses = $mRpe['week_statuses'] ?? [];
            for ($w = 1; $w <= 5; $w++) {
                $isEffective = (bool)($weekStatuses[$w] ?? ($weekStatuses[(string)$w] ?? true));
                $bgColor = $isEffective ? 'FFFFFF' : 'E5E7EB';
                $table->addCell(360, ['bgColor' => $bgColor])->addText("W{$w}", ['size' => 7], ['alignment' => Jc::CENTER]);
            }
        }

        // Rows content
        $no = 1;
        $promesMap = $data['promesMap'] ?? [];
        foreach ($data['tps'] as $tp) {
            $tpId = $tp['id'];
            $tpSemester = 1;
            if (isset($data['protaMap'][$tpId])) {
                $tpSemester = $data['protaMap'][$tpId]['semester'];
            }
            if ($tpSemester != $semester) continue;

            $table->addRow();
            $table->addCell(600)->addText($no);
            $table->addCell(1000)->addText($tp['code'], ['bold' => true]);
            $table->addCell(3000)->addText($tp['description'], ['size' => 11]);
            $table->addCell(600)->addText($tp['allocated_hours'], null, ['alignment' => Jc::CENTER]);

            foreach ($months as $m) {
                $mRpe = $rpeSem[$m] ?? [];
                $weekStatuses = $mRpe['week_statuses'] ?? [];
                for ($w = 1; $w <= 5; $w++) {
                    $isEffective = (bool)($weekStatuses[$w] ?? ($weekStatuses[(string)$w] ?? true));
                    $val = $promesMap[$tpId][$m][$w] ?? '';
                    
                    $bgColor = 'FFFFFF';
                    if (!$isEffective) {
                        $bgColor = 'E5E7EB'; // Shaded gray for non-effective week
                    } elseif ($val !== '') {
                        $bgColor = 'DBEAFE'; // Light blue for allocated hours
                    }
                    $table->addCell(360, ['bgColor' => $bgColor])->addText($val, ['bold' => true], ['alignment' => Jc::CENTER]);
                }
            }
            $no++;
        }
    }

    /**
     * Bundle all device documents into a ZIP package
     */
    public function exportPackageZip(int $deviceId, array $device): string
    {
        $tps = $this->tpModel->getByDevice($deviceId);
        $prota = $this->protaModel->getDetailedProta($deviceId);
        $promes = $this->promesModel->getPromesData($deviceId);
        
        $promesMap = [];
        foreach ($promes as $pr) {
            $promesMap[$pr['tp_id']][$pr['month']][$pr['week_number']] = $pr['allocated_hours'];
        }

        $protaMap = [];
        foreach ($prota as $p) {
            $protaMap[$p['tp_id']] = $p;
        }

        $moduls = $this->modulModel->where('learning_device_id', $deviceId)->findAll();

        $pekanEfektifModel = new \App\Models\LearningDevicePekanEfektifModel();
        $rpeRecord = $pekanEfektifModel->where('learning_device_id', $deviceId)->first();
        if ($rpeRecord) {
            $rpeData = json_decode($rpeRecord['content_json'], true);
        } else {
            $rpeData = ['sem1' => [], 'sem2' => []];
        }

        $zip = new \ZipArchive();
        $tempZip = tempnam(sys_get_temp_dir(), 'ld_zip_');
        
        if ($zip->open($tempZip, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
            throw new \Exception('Failed to create temporary ZIP file');
        }

        // Subject name cleaning
        $subjectClean = preg_replace('/[^a-zA-Z0-9_]/', '_', $device['subject_name']);
        $gradeClean = preg_replace('/[^a-zA-Z0-9_]/', '_', $device['grade_name']);
        $prefix = "Perangkat_Pembelajaran_{$subjectClean}_Kelas_{$gradeClean}";

        // 1. Export RPE (DOCX only)
        $rpeDocx = $this->exportDocx($device, 'rpe', ['rpeData' => $rpeData]);
        $zip->addFromString("{$prefix}/01_RPE_{$subjectClean}.docx", $rpeDocx);

        // 2. Export CP & TP (DOCX only)
        $cpElements = json_decode($device['cp_elements'] ?? '[]', true);
        $chapters = json_decode($device['chapters'] ?? '[]', true) ?: [];
        $settings = $this->settingModel->getSettings() ?? [];
        $cpTpDocx = $this->exportCpTPWord($device, $tps, $chapters, $cpElements, $settings);
        $zip->addFromString("{$prefix}/02_CP_TP_{$subjectClean}.docx", $cpTpDocx);

        // 3. Export ATP (DOCX only)
        $chapterDplMap = json_decode($device['chapter_dpl'] ?? '{}', true) ?: [];
        $chapterKbcMap = json_decode($device['chapter_kbc'] ?? '{}', true) ?: [];
        $atpDocx = $this->exportAtpWord($device, $tps, $chapters, $chapterDplMap, $chapterKbcMap, $settings);
        $zip->addFromString("{$prefix}/03_ATP_{$subjectClean}.docx", $atpDocx);

        // 4. Export Prota (DOCX only)
        $protaDocx = $this->exportDocx($device, 'prota', ['prota' => $prota]);
        $zip->addFromString("{$prefix}/04_Prota_{$subjectClean}.docx", $protaDocx);

        // 5. Export Promes (DOCX only)
        $promesData = ['tps' => $tps, 'promesMap' => $promesMap, 'protaMap' => $protaMap, 'rpeData' => $rpeData];
        $promesDocx = $this->exportDocx($device, 'promes', $promesData);
        $zip->addFromString("{$prefix}/05_Promes_{$subjectClean}.docx", $promesDocx);

        // 6. Export KKTP (DOCX only)
        $kktpsData = $this->kktpModel->getByDevice($deviceId);
        $intervalsJson = $device['kktp_intervals'] ?? '';
        $intervals = json_decode($intervalsJson, true) ?: [
            'bimbingan' => 59,
            'cukup'     => 69,
            'baik'      => 84
        ];
        $kktpData = ['kktps' => $kktpsData, 'intervals' => $intervals];
        $kktpDocx = $this->exportDocx($device, 'kktp', $kktpData);
        $zip->addFromString("{$prefix}/06_KKTP_{$subjectClean}.docx", $kktpDocx);

        // 7. Export Modul Ajar (DOCX only)
        $chapters = json_decode($device['chapters'] ?? '[]', true) ?: [];
        foreach ($moduls as $index => $m) {
            $num = sprintf("%02d", $index + 1);
            $chapterIndex = $m['chapter_index'] ?? 0;
            $chapterName = $chapters[$chapterIndex] ?? 'Materi Pokok';

            $chapterTps = array_values(array_filter($tps, function ($tp) use ($chapterName) {
                return ($tp['chapter'] ?? '') === $chapterName;
            }));
            if (empty($chapterTps)) {
                $chapterTps = $tps; 
            }

            $totalJp = 0;
            foreach ($chapterTps as $tp) $totalJp += (int) ($tp['allocated_hours'] ?? 0);

            $totHours = 0;
            foreach ($chapterTps as $tp) {
                $tpIdTmp = $tp['id'];
                if (isset($promesMap[$tpIdTmp])) {
                    foreach ($promesMap[$tpIdTmp] as $mNum => $weeks) {
                        foreach ($weeks as $w => $hours) {
                            $totHours += intval($hours);
                        }
                    }
                }
            }
            $jumlahPertemuan = max(1, (int)ceil($totHours / 4));
            
            $cpElementsDisplay = '';
            $cpElements = json_decode($device['cp_elements'] ?? '[]', true);
            $chapterCpMap = json_decode($device['chapter_cp_map'] ?? '{}', true);
            $selectedCpElement = $chapterCpMap[$chapterIndex] ?? '';
            if (!empty($selectedCpElement)) {
                $cpElementsDisplay = is_array($selectedCpElement) ? implode(', ', $selectedCpElement) : $selectedCpElement;
            } elseif (is_array($cpElements)) {
                $names = array_column($cpElements, 'name');
                $cpElementsDisplay = implode(', ', $names);
            }

            $chapterDplMap = json_decode($device['chapter_dpl'] ?? '{}', true) ?: [];
            $chapterKbcMap = json_decode($device['chapter_kbc'] ?? '{}', true) ?: [];
            $dplChapterDisplay = implode(', ', $chapterDplMap[$chapterIndex] ?? []);
            $kbcChapterDisplay = implode(', ', $chapterKbcMap[$chapterIndex] ?? []);
            if (empty($dplChapterDisplay)) {
                $dplArr = json_decode($device['dpl'] ?? '[]', true) ?: [];
                $dplChapterDisplay = implode(', ', $dplArr);
            }
            if (empty($kbcChapterDisplay)) {
                $kbcArr = json_decode($device['panca_cinta'] ?? '[]', true) ?: [];
                $kbcChapterDisplay = implode(', ', $kbcArr);
            }

            $skenario = [];
            if (!empty($m['skenario_pembelajaran'])) {
                $skenario = is_string($m['skenario_pembelajaran'])
                    ? json_decode($m['skenario_pembelajaran'], true) ?? []
                    : $m['skenario_pembelajaran'];
            }

            $daftarPustaka = $m['daftar_pustaka'] ?? '';
            if (empty($daftarPustaka)) {
                $daftarPustaka = "Kementerian Pendidikan, Kebudayaan, Riset, dan Teknologi. Buku Panduan Guru dan Buku Siswa " . ($device['subject_name'] ?? 'Mata Pelajaran') . " Kelas " . ($device['grade_name'] ?? '-') . ". Jakarta.";
            }

            $exportData = [
                'device'       => $device,
                'settings'     => $settings,
                'modul'        => $m,
                'chapterName'  => $chapterName,
                'chapterTps'   => $chapterTps,
                'totalJp'      => $totalJp,
                'jumlahPertemuan' => $jumlahPertemuan,
                'cpElementsDisplay' => $cpElementsDisplay,
                'dplChapterDisplay' => $dplChapterDisplay,
                'kbcChapterDisplay' => $kbcChapterDisplay,
                'daftarPustaka' => $daftarPustaka,
                'skenario'     => $skenario,
            ];

            $modulDocx = $this->exportModulBaru($exportData);
            
            $tpCode = $m['topic'] ? substr($m['topic'], 0, 15) : 'Modul';
            $tpCodeClean = preg_replace('/[^a-zA-Z0-9_]/', '_', $tpCode);
            $zip->addFromString("{$prefix}/07_Modul_Ajar/Modul_{$num}_{$tpCodeClean}.docx", $modulDocx);
        }

        $zip->close();
        
        $content = file_get_contents($tempZip);
        unlink($tempZip);

        return $content;
    }

    /**
     * Export Modul Ajar DOCX — format rapi seperti KKTP
     */
    public function exportModulBaru(array $data): string
    {
        $phpWord = new \PhpOffice\PhpWord\PhpWord();
        $device = $data['device'];
        $settings = $data['settings'];
        $modul = $data['modul'];
        $chapterName = $data['chapterName'];
        $chapterTps = $data['chapterTps'];
        $totalJp = $data['totalJp'];
        $jumlahPertemuan = $data['jumlahPertemuan'];
        $cpElementsDisplay = $data['cpElementsDisplay'];
        $dplChapterDisplay = $data['dplChapterDisplay'] ?? '';
        $kbcChapterDisplay = $data['kbcChapterDisplay'] ?? '';
        $daftarPustaka = $data['daftarPustaka'];
        $subject = $device['subject_name'] ?? '';
        $grade = $device['grade_name'] ?? '';
        $phase = $device['phase'] ?? '';
        $semester = ($chapterTps[0]['semester'] ?? 1) == 1 ? 'Ganjil' : 'Genap';
        $acYear = $device['academic_year_name'] ?? '-';

        $section = $phpWord->addSection([
            'paperSize'    => 'A4',
            'marginTop'    => 800,
            'marginBottom' => 800,
            'marginLeft'   => 800,
            'marginRight'  => 800,
        ]);

        // ─────────────────────────────────────────────
        // TITLE — langsung MODUL AJAR tanpa KOP (Konsisten)
        // ─────────────────────────────────────────────
        $this->addWordHeader($section, $settings, "MODUL AJAR: " . strtoupper($subject));

        // ═════════════════════════════════════════════
        // I. INFORMASI UMUM
        // ═════════════════════════════════════════════
        $this->addSubtitleWord($section, 'I. INFORMASI UMUM');

        $section->addText('1. Identitas Modul', ['bold' => true, 'size' => 11]);
        $section->addTextBreak(1);

        $tbl = $section->addTable(['borderSize' => 6, 'borderColor' => '222222']);
        $rows = [
            ['Nama Penyusun', $device['teacher_name'] ?? '-'],
            [guess_id_label($device['teacher_nip'] ?? '-'), $device['teacher_nip'] ?? '-'],
            ['Institusi', $settings['school_name'] ?? '-'],
            ['Jenjang', $device['school_type'] === 'madrasah' ? 'Madrasah Tsanawiyah (MTs)' : 'SMP'],
            ['Mata Pelajaran', $subject],
            ['Fase / Kelas', 'Fase ' . $phase . ' / Kelas ' . $grade],
            ['Tahun Ajaran', $acYear],
            ['Semester', $semester . ' (' . ($chapterTps[0]['semester'] ?? 1) . ')'],
            ['Bab / Materi', $chapterName],
            ['Alokasi Waktu', $totalJp . ' JP (' . $jumlahPertemuan . ' pertemuan)'],
            ['Profil Lulusan', $dplChapterDisplay ?: (is_string($device['dpl'] ?? '') ? $device['dpl'] : (is_array($device['dpl'] ?? '') ? implode(', ', $device['dpl']) : '-'))],
            ['Topik KBC', $kbcChapterDisplay ?: (is_string($device['panca_cinta'] ?? '') ? $device['panca_cinta'] : (is_array($device['panca_cinta'] ?? '') ? implode(', ', $device['panca_cinta']) : '-'))],
            ['Elemen CP', $cpElementsDisplay],
        ];
        foreach ($rows as $r) {
            $tbl->addRow();
            $tbl->addCell(3090, ['bgColor' => 'F5F5F5'])->addText($r[0], ['bold' => true, 'size' => 11]);
            $tbl->addCell(7210)->addText($r[1], ['size' => 11]);
        }
        $section->addTextBreak(1);

        // Field-field sisanya — pakai smart parser
        $this->smartField($section, '2. Kompetensi Awal (Prasyarat)', $modul['kompetensi_awal'] ?? '');
        $this->smartField($section, '3. Sarana & Prasarana', $modul['sarana_prasarana'] ?? '');
        $this->smartField($section, '4. Target Peserta Didik', $modul['target_peserta_didik'] ?? '');
        $this->smartField($section, '5. Model & Pendekatan Pembelajaran', $modul['model_pembelajaran'] ?? '');

        // ═════════════════════════════════════════════
        // II. KOMPONEN INTI
        // ═════════════════════════════════════════════
        $this->addSubtitleWord($section, 'II. KOMPONEN INTI');

        $section->addText('1. Capaian Pembelajaran (CP)', ['bold' => true, 'size' => 11]);
        $cpLines = explode("\n", $device['cp_content'] ?? '');
        $cpLines = array_map('trim', $cpLines);
        $cpLines = array_filter($cpLines, fn($l) => $l !== '');
        $cpLines = array_values($cpLines);
        if (!empty($cpLines)) {
            // Teks pertama (header) sebagai paragraf
            $section->addText($cpLines[0], ['size' => 11], ['alignment' => Jc::BOTH]);
            // Sisanya jika numbered → tabel
            $restLines = array_slice($cpLines, 1);
            if (!empty($restLines) && preg_match('/^\d+\.\s/', $restLines[0])) {
                $t = $section->addTable(['borderSize' => 6, 'borderColor' => '222222']);
                $t->addRow();
                $t->addCell(500, ['bgColor' => 'E8E8E8'])->addText('No', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
                $t->addCell(9800, ['bgColor' => 'E8E8E8'])->addText('Capaian Pembelajaran', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
                $n = 0;
                foreach ($restLines as $rl) {
                    if (preg_match('/^\d+\.\s+(.+)/', $rl, $m)) {
                        $n++; $t->addRow();
                        $t->addCell(500)->addText($n.'.', ['size' => 11], ['alignment' => Jc::CENTER]);
                        $t->addCell(9800)->addText(trim($m[1]), ['size' => 11]);
                    }
                }
            } else {
                foreach ($restLines as $rl) $section->addText($rl, ['size' => 11], ['alignment' => Jc::BOTH]);
            }
        }
        $section->addTextBreak(1);

        $section->addText('2. Tujuan Pembelajaran (TP) & Indikator Ketercapaian', ['bold' => true, 'size' => 11]);
        $tpTable = $section->addTable(['borderSize' => 6, 'borderColor' => '222222']);
        $tpTable->addRow();
        $tpTable->addCell(1200, ['bgColor' => 'E8E8E8'])->addText('Kode', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
        $tpTable->addCell(9100, ['bgColor' => 'E8E8E8'])->addText('Tujuan Pembelajaran', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
        foreach ($chapterTps as $ctp) {
            $tpTable->addRow();
            $tpTable->addCell(1200)->addText($ctp['code'], ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $tpTable->addCell(9100)->addText($ctp['description'], ['size' => 11]);
        }
        $section->addTextBreak(1);

        $this->smartField($section, '3. Pemahaman Bermakna', $modul['pemahaman_bermakna'] ?? '');
        $this->smartField($section, '4. Pertanyaan Pemantik', $modul['pertanyaan_pemantik'] ?? '');
        $this->smartField($section, '5. Materi Esensial / Pokok', $modul['materi_esensial'] ?? '');

        // ═════════════════════════════════════════════
        // III. KEGIATAN PEMBELAJARAN
        // ═════════════════════════════════════════════
        $this->addSubtitleWord($section, 'III. KEGIATAN PEMBELAJARAN');

        $skenario = [];
        if (!empty($modul['skenario_pembelajaran'])) {
            $skenario = is_string($modul['skenario_pembelajaran'])
                ? json_decode($modul['skenario_pembelajaran'], true) ?? []
                : $modul['skenario_pembelajaran'];
        }
        if (!empty($skenario)) {
            foreach ($skenario as $sk) {
                $pert = $sk['pertemuan'] ?? 1;
                $section->addText('Pertemuan ' . $pert, ['bold' => true, 'size' => 11]);
                // Materi (sub_materi)
                $materi = $sk['sub_materi'] ?? '';
                if (!empty($materi)) {
                    $section->addText('Materi', ['bold' => true, 'size' => 11]);
                    $section->addText($materi, ['size' => 11]);
                    $section->addTextBreak(1);
                }
                // IKTP
                $iktpList = $sk['iktp'] ?? [];
                if (!empty($iktpList) && is_array($iktpList)) {
                    $section->addText('IKTP Pertemuan ' . $pert . ' :', ['bold' => true, 'size' => 11]);
                    $iktpTable = $section->addTable(['borderSize' => 0, 'borderColor' => 'FFFFFF']);
                    $no = 1;
                    foreach ($iktpList as $ik) {
                        $iktpTable->addRow();
                        $iktpTable->addCell(500)->addText($no . '.', ['size' => 11]);
                        $iktpTable->addCell(9800)->addText($ik, ['size' => 11]);
                        $no++;
                    }
                    $section->addTextBreak(1);
                }
                // A. Pendahuluan
                $section->addText('A. Pendahuluan', ['bold' => true, 'size' => 11]);
                $this->smartField($section, null, $sk['pendahuluan'] ?? '');
                $section->addTextBreak(1);
                // B. Kegiatan Inti
                $section->addText('B. Kegiatan Inti', ['bold' => true, 'size' => 11]);
                $this->smartField($section, null, $sk['inti'] ?? '');
                $section->addTextBreak(1);
                // C. Penutup
                $section->addText('C. Penutup', ['bold' => true, 'size' => 11]);
                $this->smartField($section, null, $sk['penutup'] ?? '');
                $section->addTextBreak(1);
            }
        }
        $section->addTextBreak(1);

        // IV. ASESMEN
        // ═════════════════════════════════════════════
        $this->addSubtitleWord($section, 'IV. ASESMEN (PENILAIAN)');
        
        $diag = $modul['asesmen_diagnostik'] ?? '';
        if (empty(trim(is_array($diag) ? '' : $diag)) && !empty($modul['assessment']['diagnostik'])) {
            $diag = $modul['assessment']['diagnostik'];
        }
        $this->smartField($section, '1. Asesmen Awal / Diagnostik', $diag);
        
        $form = $modul['asesmen_formatif'] ?? '';
        if (empty(trim(is_array($form) ? '' : $form)) && !empty($modul['assessment']['formatif'])) {
            $form = $modul['assessment']['formatif'];
        }
        $this->smartField($section, '2. Asesmen Formatif (Proses)', $form);
        
        $sum = $modul['asesmen_sumatif'] ?? '';
        if (empty(trim(is_array($sum) ? '' : $sum)) && !empty($modul['assessment']['sumatif'])) {
            $sum = $modul['assessment']['sumatif'];
        }
        $this->smartField($section, '3. Asesmen Sumatif (Akhir)', $sum);

        // ═════════════════════════════════════════════
        // V. PENGAYAAN & REMEDIAL
        // ═════════════════════════════════════════════
        $this->addSubtitleWord($section, 'V. PENGAYAAN & REMEDIAL');
        $this->smartField($section, '1. Program Pengayaan', $modul['pengayaan'] ?? '');
        $this->smartField($section, '2. Program Remedial', $modul['remedial'] ?? '');

        // ═════════════════════════════════════════════
        // VI. LAMPIRAN
        // ═════════════════════════════════════════════
        $this->addSubtitleWord($section, 'VI. LAMPIRAN');
        $this->smartField($section, '1. Glosarium', $modul['glosarium'] ?? '');

        $section->addText('2. Daftar Pustaka', ['bold' => true, 'size' => 11]);
        $lines = explode("\n", $daftarPustaka);
        foreach ($lines as $l) {
            if (trim($l) !== '') $section->addText('    ' . trim($l), ['size' => 11]);
        }
        $section->addTextBreak(2);

        // ═════════════════════════════════════════════
        // LKPD — 1 halaman per pertemuan
        // ═════════════════════════════════════════════
        $firstLkpd = true;
        foreach ($skenario as $sk) {
            if ($firstLkpd) {
                $section->addPageBreak();
                $firstLkpd = false;
            } else {
                $section->addPageBreak();
            }

            $pert = $sk['pertemuan'] ?? 1;
            $materi = $sk['sub_materi'] ?? '';

            $section->addText('LEMBAR KERJA PESERTA DIDIK (LKPD)', ['bold' => true, 'size' => 13], ['alignment' => Jc::CENTER]);
            $section->addTextBreak(1);
            $section->addText('Pertemuan ' . $pert . ($materi ? ': ' . $materi : ''), ['bold' => true, 'size' => 11]);
            $section->addTextBreak(1);

            $tblLkpd = $section->addTable(['borderSize' => 6, 'borderColor' => '222222']);

            // Baris identitas
            $tblLkpd->addRow();
            $tblLkpd->addCell(3090, ['bgColor' => 'F5F5F5'])->addText('Identitas', ['bold' => true, 'size' => 11]);
            $cellId = $tblLkpd->addCell(7210);
            $cellId->addText('Nama          : ........................................', ['size' => 11]);
            $cellId->addText('Kelas         : ........................................', ['size' => 11]);
            $cellId->addText('Pertemuan ke- : ' . $pert, ['size' => 11]);

            // Baris tujuan
            $tblLkpd->addRow();
            $tblLkpd->addCell(3090, ['bgColor' => 'F5F5F5'])->addText('Tujuan', ['bold' => true, 'size' => 11]);
            $iktpList = $sk['iktp'] ?? [];
            $cellTujuan = $tblLkpd->addCell(7210);
            if (!empty($iktpList) && is_array($iktpList)) {
                foreach ($iktpList as $ik) {
                    $cellTujuan->addText('- ' . $ik, ['size' => 11]);
                }
            } else {
                $cellTujuan->addText('........................................', ['size' => 11]);
            }

            // Baris langkah kegiatan
            $tblLkpd->addRow();
            $tblLkpd->addCell(3090, ['bgColor' => 'F5F5F5'])->addText('Langkah Kegiatan', ['bold' => true, 'size' => 11]);
            $cellLangkah = $tblLkpd->addCell(7210);
            $lkpdLangkah = trim($sk['lkpd_langkah'] ?? '');
            if (!empty($lkpdLangkah)) {
                $cellLangkah->addText($lkpdLangkah, ['size' => 11]);
            } else {
                $cellLangkah->addText('........................................', ['size' => 11]);
            }

            // Baris soal/tugas
            $tblLkpd->addRow();
            $tblLkpd->addCell(3090, ['bgColor' => 'F5F5F5'])->addText('Soal/Tugas', ['bold' => true, 'size' => 11]);
            $cellSoal = $tblLkpd->addCell(7210);
            $lkpdSoal = trim($sk['lkpd_soal'] ?? '');
            if (!empty($lkpdSoal)) {
                $cellSoal->addText($lkpdSoal, ['size' => 11]);
            } else {
                $cellSoal->addText('........................................', ['size' => 11]);
            }

            // Baris ruang jawab (merge 2 kolom) — tempat siswa menulis
            $tblLkpd->addRow();
            $cellJawab = $tblLkpd->addCell(null, ['gridSpan' => 2]);
            $cellJawab->addText('', ['size' => 11]);
            $cellJawab->addText('', ['size' => 11]);
            $cellJawab->addText('', ['size' => 11]);
            $cellJawab->addText('', ['size' => 11]);
            $cellJawab->addText('', ['size' => 11]);

            // Baris kesimpulan
            $tblLkpd->addRow();
            $tblLkpd->addCell(3090, ['bgColor' => 'F5F5F5'])->addText('Kesimpulan', ['bold' => true, 'size' => 11]);
            $cellKesimpulan = $tblLkpd->addCell(7210);
            $lkpdKesimpulan = trim($sk['lkpd_kesimpulan'] ?? '');
            if (!empty($lkpdKesimpulan)) {
                $cellKesimpulan->addText($lkpdKesimpulan, ['size' => 11]);
            } else {
                $cellKesimpulan->addText('........................................', ['size' => 11]);
            }

            // Baris ruang refleksi (merge 2 kolom) — tempat siswa menulis
            $tblLkpd->addRow();
            $cellRefleksi = $tblLkpd->addCell(null, ['gridSpan' => 2]);
            $cellRefleksi->addText('', ['size' => 11]);
            $cellRefleksi->addText('', ['size' => 11]);
            $cellRefleksi->addText('', ['size' => 11]);

            $section->addTextBreak(1);
        }

        // Page break setelah LKPD terakhir
        $section->addPageBreak();

        // ═════════════════════════════════════════════
        // LEMBAR PENGESAHAN
        // ═════════════════════════════════════════════
        $this->addSubtitleWord($section, 'LEMBAR PENGESAHAN MODUL AJAR');
        $this->addWordSignatures($section, $settings, $device);

        // ─── SAVE ──────────────────────────────────────
        $tempFile = tempnam(sys_get_temp_dir(), 'modul_') . '.docx';
        $writer = IOFactory::createWriter($phpWord, 'Word2007');
        $writer->save($tempFile);

        $content = file_get_contents($tempFile);
        unlink($tempFile);

        return $content;
    }

    /**
     * Helper: subtitle dengan border (seperti tabel di KKTP)
     */
    private function addSubtitleWord(\PhpOffice\PhpWord\Element\Section $section, string $title): void
    {
        $table = $section->addTable(['borderSize' => 6, 'borderColor' => '222222']);
        $table->addRow();
        $cell = $table->addCell(10300, ['bgColor' => 'E8E8E8']);
        $cell->addText($title, ['bold' => true, 'size' => 12], ['alignment' => Jc::CENTER]);
        $section->addTextBreak(1);
    }

    /**
     * Smart field writer: auto-detect format dan render sesuai
     * - [Kategori] : [Isi]      → tabel 2 kolom
     * - [K] : [D] : [S]        → tabel 3 kolom
     * - 1. ...                  → numbered
     * - - ...                   → bullet
     * - TAHAP 1                 → bold heading
     * - Sangat Baik:            → rubrik tabel warna
     * - Lainnya                 → paragraf justify
     */
    private function smartField($section, ?string $label, string $value): void
    {
        if (empty(trim($value))) return;
        $lines = explode("\n", trim($value));
        $lines = array_map('trim', $lines);
        $lines = array_filter($lines, fn($l) => $l !== '');
        $lines = array_values($lines);
        if (empty($lines)) return;
        if (count($lines) === 1 && strlen($lines[0]) > 200) {
            $s = $lines[0];
            $sp = preg_split('/(?=(?:A\.|B\.|C\.)\s+(?:PILIHAN|URAIAN|PRAKTIK|SOAL|ESAI))/i', $s);
            if (count($sp) > 1) $lines = array_map('trim', $sp);
            else { $sp2 = preg_split('/(?=(?:JUDUL|PETUNJUK|SOAL\/TUGAS|KESIMPULAN):)/i', $s); if (count($sp2) > 1) $lines = array_map('trim', $sp2); }
        }
        if ($label) $section->addText($label, ['bold' => true, 'size' => 11]);

        // 🟡 Format BENTUK ASESMEN + INSTRUMEN + RUBRIK
        $firstLineClean = str_replace('**', '', $lines[0]);
        if (count($lines) >= 3 && preg_match('/^BENTUK ASESMEN/i', $firstLineClean)) {
            $ri = -1;
            foreach ($lines as $i => $l) {
                $lClean = str_replace('**', '', $l);
                if (preg_match('/^RUBRIK PENILAIAN/i', $lClean)) {
                    $ri = $i;
                    break;
                }
            }
            if ($ri > 0) {
                $atas = array_slice($lines, 0, $ri);
                $t1 = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
                $t1->addRow();
                $t1->addCell(3090, ['bgColor' => 'E8E8E8'])->addText('Item', ['bold' => true, 'size' => 9.5], ['alignment' => Jc::CENTER]);
                $t1->addCell(7210, ['bgColor' => 'E8E8E8'])->addText('Rincian', ['bold' => true, 'size' => 9.5], ['alignment' => Jc::CENTER]);
                foreach ($atas as $line) {
                    $lineClean = str_replace('**', '', $line);
                    $p = strpos($lineClean, ':');
                    if ($p !== false) {
                        $t1->addRow();
                        $t1->addCell(3090, ['bgColor' => 'F5F5F5'])->addText(trim(substr($lineClean, 0, $p)), ['bold' => true, 'size' => 9.5]);
                        $t1->addCell(7210)->addText(trim(substr($lineClean, $p + 1)), ['size' => 9.5]);
                    }
                }
                $section->addTextBreak(1);
                $section->addText('RUBRIK PENILAIAN', ['bold' => true, 'size' => 10]);
                $bawah = array_values(array_filter(array_slice($lines, $ri + 1), fn($l) => trim($l) !== ''));
                if (!empty($bawah)) {
                    $colors = ['Sangat Baik' => 'DBEAFE', 'Baik' => 'D1FAE5', 'Cukup' => 'FEF3C7', 'Kurang' => 'FEE2E2', 'Perlu Bimbingan' => 'FEE2E2'];
                    $t2 = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
                    $t2->addRow();
                    $t2->addCell(2575, ['bgColor' => 'E8E8E8'])->addText('Level', ['bold' => true, 'size' => 9.5], ['alignment' => Jc::CENTER]);
                    $t2->addCell(7725, ['bgColor' => 'E8E8E8'])->addText('Deskripsi', ['bold' => true, 'size' => 9.5], ['alignment' => Jc::CENTER]);
                    foreach ($bawah as $line) {
                        $lineClean = str_replace('**', '', $line);
                        $p = strpos($lineClean, ':');
                        if ($p === false) $p = strpos($lineClean, "\t");
                        if ($p === false) continue;
                        $lvl = trim(substr($lineClean, 0, $p));
                        $desc = trim(substr($lineClean, $p + 1));
                        $t2->addRow();
                        $t2->addCell(2575, ['bgColor' => ($colors[$lvl] ?? 'FFFFFF')])->addText($lvl, ['bold' => true, 'size' => 9.5], ['alignment' => Jc::CENTER]);
                        $t2->addCell(7725)->addText($desc, ['size' => 9.5]);
                    }
                    $section->addTextBreak(1);
                }
                return;
            }
        }

        // 0a. Pipe-separated 4 kolom: No|Tahap|Kegiatan Guru|Kegiatan Siswa  (Inti)
        $pipe4Match = false;
        $checkLine = $lines[0] ?? '';
        if (preg_match('/^\d+\|.+\|.+\|.+/', $checkLine)) {
            $pipe4Match = true;
        } elseif (count($lines) >= 2 && preg_match('/^No\|/i', $checkLine) && preg_match('/^\d+\|.+\|.+\|.+/', $lines[1])) {
            $pipe4Match = true;
            array_shift($lines);
        }
        if ($pipe4Match && count(explode('|', $checkLine)) >= 4) {
            $t = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
            $t->addRow();
            $t->addCell(400, ['bgColor' => 'E8E8E8'])->addText('No', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $t->addCell(2500, ['bgColor' => 'E8E8E8'])->addText('Tahap', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $t->addCell(3500, ['bgColor' => 'E8E8E8'])->addText('Kegiatan Guru', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $t->addCell(3600, ['bgColor' => 'E8E8E8'])->addText('Kegiatan Siswa', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            foreach ($lines as $line) {
                $parts = explode('|', $line);
                if (count($parts) >= 4) {
                    $t->addRow();
                    $t->addCell(500)->addText(trim($parts[0]), ['size' => 11], ['alignment' => Jc::CENTER]);
                    $t->addCell(2600, ['bgColor' => 'F5F5F5'])->addText(trim($parts[1]), ['bold' => true, 'size' => 11]);
                    $t->addCell(3600)->addText(trim($parts[2]), ['size' => 11]);
                    $t->addCell(3600)->addText(trim($parts[3]), ['size' => 11]);
                }
            }
            $section->addTextBreak(1); return;
        }

        // 0b. Pipe-separated 3 kolom: No|Komponen|Deskripsi  (Pendahuluan)
        // Deteksi: baris pertama bisa header (No|...), baris kedua data (\d+|...)
        $pipe3Match = false;
        $checkLine = $lines[0] ?? '';
        if (preg_match('/^\d+\|.+\|.+/', $checkLine)) {
            $pipe3Match = true;
        } elseif (count($lines) >= 2 && preg_match('/^No\|\w+/i', $checkLine) && preg_match('/^\d+\|.+\|.+/', $lines[1])) {
            $pipe3Match = true;
            array_shift($lines); // buang header
        }
        if ($pipe3Match && count(explode('|', $checkLine)) >= 3) {
            $t = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
            $t->addRow();
            $t->addCell(400, ['bgColor' => 'E8E8E8'])->addText('No', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $t->addCell(2500, ['bgColor' => 'E8E8E8'])->addText('Komponen', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $t->addCell(7100, ['bgColor' => 'E8E8E8'])->addText('Deskripsi', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            foreach ($lines as $line) {
                $parts = explode('|', $line, 3);
                if (count($parts) >= 3) {
                    $t->addRow();
                    $t->addCell(500)->addText(trim($parts[0]), ['size' => 11], ['alignment' => Jc::CENTER]);
                    $t->addCell(2600, ['bgColor' => 'F5F5F5'])->addText(trim($parts[1]), ['bold' => true, 'size' => 11]);
                    $t->addCell(7200)->addText(trim($parts[2]), ['size' => 11]);
                }
            }
            $section->addTextBreak(1); return;
        }

        // 1. TAHAP
        if (preg_match('/^TAHAP\s+\d/i', $lines[0])) {
            foreach ($lines as $line) {
                if (preg_match('/^(TAHAP\s+\d+\s*[-–]\s*[^:]+):(.*)/i', $line, $m)) { $section->addText(trim($m[1]), ['bold' => true, 'size' => 11]); $section->addText(trim($m[2]), ['size' => 11], ['alignment' => Jc::BOTH]); }
                else $section->addText($line, ['size' => 11], ['alignment' => Jc::BOTH]);
            } $section->addTextBreak(1); return;
        }
        // 2. Rubrik
        if (preg_match('/^(Sangat Baik|Baik|Cukup|Kurang)\s*:/i', $lines[0])) {
            $colors = ['Sangat Baik' => 'DBEAFE', 'Baik' => 'D1FAE5', 'Cukup' => 'FEF3C7', 'Kurang' => 'FEE2E2'];
            $t = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
            $t->addRow(); $t->addCell(2575, ['bgColor' => 'E8E8E8'])->addText('Level', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(7725, ['bgColor' => 'E8E8E8'])->addText('Deskripsi', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            foreach ($lines as $line) { $p = strpos($line, ':'); if ($p === false) continue; $l = trim(substr($line, 0, $p)); $d = trim(substr($line, $p + 1)); $t->addRow(); $t->addCell(2575, ['bgColor' => $colors[$l] ?? 'FFFFFF'])->addText($l, ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(7725)->addText($d, ['size' => 11]); }
            $section->addTextBreak(1); return;
        }
        // 3. Numbered + →
        if (preg_match('/^\d+\.\s/', $lines[0]) && strpos($lines[0], '→') !== false) {
            $t = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
            $t->addRow(); $t->addCell(400, ['bgColor' => 'E8E8E8'])->addText('No', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(4800, ['bgColor' => 'E8E8E8'])->addText('Pertanyaan', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(4800, ['bgColor' => 'E8E8E8'])->addText('Respons', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $n = 0; foreach ($lines as $line) { if (preg_match('/^\d+\.\s+(.+?)\s*→\s*(.+)/', $line, $m)) { $n++; $t->addRow(); $t->addCell(400)->addText($n.'.', ['size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(4800)->addText(trim($m[1]), ['size' => 11]); $t->addCell(4800)->addText(trim($m[2]), ['size' => 11]); } }
            $section->addTextBreak(1); return;
        }
        // 4. Numbered + colon → tabel 3 kolom
        if (preg_match('/^\d+\.\s+\S+.*:.*\S/', $lines[0])) {
            $t = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
            $t->addRow(); $t->addCell(400, ['bgColor' => 'E8E8E8'])->addText('No', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(2500, ['bgColor' => 'E8E8E8'])->addText('Komponen', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(7100, ['bgColor' => 'E8E8E8'])->addText('Uraian', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $n = 0; foreach ($lines as $line) { if (preg_match('/^\d+\.\s+([^:]+):\s*(.+)/', $line, $m)) { $n++; $t->addRow(); $t->addCell(500)->addText($n.'.', ['size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(2600, ['bgColor' => 'F5F5F5'])->addText(trim($m[1]), ['bold' => true, 'size' => 11]); $t->addCell(7200)->addText(trim($m[2]), ['size' => 11]); } }
            $section->addTextBreak(1); return;
        }
        // 5. Numbered biasa → tabel 2 kolom
        if (preg_match('/^\d+\.\s/', $lines[0])) {
            $t = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
            $t->addRow(); $t->addCell(500, ['bgColor' => 'E8E8E8'])->addText('No', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(9800, ['bgColor' => 'E8E8E8'])->addText('Uraian', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
            $n = 0; foreach ($lines as $line) { if (preg_match('/^\d+\.\s+(.+)/', $line, $m)) { $n++; $t->addRow(); $t->addCell(500)->addText($n.'.', ['size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(9800)->addText(trim($m[1]), ['size' => 11]); } }
            $section->addTextBreak(1); return;
        }
        // 6. Tabel (2/3 kolom)
        if (count($lines) >= 2) {
            $hc = true; foreach ($lines as $l) { if (strpos($l, ':') === false) { $hc = false; break; } }
            $sk = preg_match('/^(Sangat Baik|Baik|Cukup|Kurang|TAHAP|\d+\.)/i', $lines[0]);
            if ($hc && !$sk) {
                $three = (substr_count($lines[0], ':') >= 2);
                $t = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
                if ($three) {
                    $t->addRow(); $t->addCell(2500, ['bgColor' => 'E8E8E8'])->addText('Kategori', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(3500, ['bgColor' => 'E8E8E8'])->addText('Deskripsi', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(4000, ['bgColor' => 'E8E8E8'])->addText('Strategi', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
                    foreach ($lines as $line) { $parts = explode(':', $line, 3); if (count($parts) >= 3) { $t->addRow(); $t->addCell(2500, ['bgColor' => 'F5F5F5'])->addText(trim($parts[0]), ['bold' => true, 'size' => 11]); $t->addCell(3600)->addText(trim($parts[1]), ['size' => 11]); $t->addCell(4200)->addText(trim($parts[2]), ['size' => 11]); } }
                } else {
                    $t->addRow(); $t->addCell(3090, ['bgColor' => 'E8E8E8'])->addText('Item', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]); $t->addCell(7210, ['bgColor' => 'E8E8E8'])->addText('Rincian', ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
                    foreach ($lines as $line) { $p = strpos($line, ':'); if ($p !== false) { $t->addRow(); $t->addCell(3090, ['bgColor' => 'F5F5F5'])->addText(trim(substr($line, 0, $p)), ['bold' => true, 'size' => 11]); $t->addCell(7210)->addText(trim(substr($line, $p + 1)), ['size' => 11]); } }
                }
                $section->addTextBreak(1); return;
            }
        }
        // 7. Sub-heading A./B./C.
        if (preg_match('/^[A-C]\.\s+(PILIHAN|URAIAN|PRAKTIK|ISIAN\s+SINGKAT|ESAI)/i', $lines[0])) {
            foreach ($lines as $line) { if (preg_match('/^[A-C]\.\s+/i', $line)) $section->addText($line, ['bold' => true, 'size' => 11]); else $section->addText($line, ['size' => 11]); }
            $section->addTextBreak(1); return;
        }
        // 8. Bullet
        if (str_starts_with($lines[0], '- ')) { foreach ($lines as $line) $section->addText($line, ['size' => 11], ['alignment' => Jc::BOTH]); $section->addTextBreak(1); return; }
        // 9. LKPD
        if (preg_match('/^(JUDUL|PETUNJUK|SOAL|KESIMPULAN):/i', $lines[0])) {
            foreach ($lines as $line) { if (preg_match('/^(JUDUL|PETUNJUK|SOAL\/TUGAS|KESIMPULAN):/i', $line)) $section->addText($line, ['bold' => true, 'size' => 11]); else $section->addText($line, ['size' => 11], ['alignment' => Jc::BOTH]); }
            $section->addTextBreak(1); return;
        }
        // 10. Default
        foreach ($lines as $line) $section->addText($line, ['size' => 11], ['alignment' => Jc::BOTH]);
        $section->addTextBreak(1);
    }

    // ================================================================
    // EXPORT: CP + TP (Landscape)
    // ================================================================
    public function exportCpTPWord(array $device, array $tps, array $chapters, array $elements, ?array $settings, array $chapterDplMap = [], array $chapterKbcMap = [], array $chapterCpMap = []): string
    {
        $phpWord = new \PhpOffice\PhpWord\PhpWord();
        $phpWord->setDefaultFontName('Arial');
        $phpWord->setDefaultFontSize(11);
        $section = $phpWord->addSection([
            'orientation'  => 'landscape',
            'marginTop'    => 800,
            'marginBottom' => 800,
            'marginLeft'   => 800,
            'marginRight'  => 800,
            'pageSizeW'    => \PhpOffice\PhpWord\Shared\Converter::cmToTwip(29.7),
            'pageSizeH'    => \PhpOffice\PhpWord\Shared\Converter::cmToTwip(21.0)
        ]);
        // Available width: 15200

        $schoolName = $settings['school_name'] ?? 'Sekolah';
        $tahunAjaran = $device['academic_year_name'] ?? date('Y') . '/' . (date('Y') + 1);

        $this->addWordHeader($section, $settings, "CAPAIAN PEMBELAJARAN (CP) DAN TUJUAN PEMBELAJARAN (TP)");

        $this->addWordMetaTable($section, $device);

        // CP — borderless table untuk numbering rapi (wrap lurus)
        $section->addText('Capaian Pembelajaran', ['bold' => true, 'size' => 11]);
        $section->addText('Pada akhir fase, murid mampu :', ['size' => 11]);
        $cpText = trim($device['cp_content'] ?? '');
        $lines = preg_split('/\n+/', $cpText);
        $cpTable = $section->addTable(['borderColor' => 'FFFFFF', 'borderSize' => 0, 'cellMargin' => 40]);
        $num = 0;
        foreach ($lines as $line) {
            $line = trim($line);
            if (empty($line)) continue;
            $num++;
            $clean = preg_replace('/^\d+\s*[\.\)]\s*/', '', $line);
            $cpTable->addRow();
            $cpTable->addCell(400)->addText($num . '.', ['size' => 11]);
            $cpTable->addCell(14800)->addText($clean, ['size' => 11]);
        }
        $section->addTextBreak(1);

        // Tabel: No | Elemen CP | Materi | TP — total 15200
        $section->addText('Tujuan Pembelajaran', ['bold' => true, 'size' => 11]);
        $isMadrasah = ($device['school_type'] ?? '') === 'madrasah';
        // Available width: 15200
        // Columns: No(500) | Materi(2200) | ElemCP(1800) | KodeTP(900) | TP(5800) | JP(600) | DPL(2000) | KBC(1400 if madrasah)
        $table = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
        $table->addRow(null, 300);
        $table->addCell(500,  ['bgColor' => '1a3c6e'])->addText('No',          ['bold' => true, 'size' => 10, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(2200, ['bgColor' => '1a3c6e'])->addText('Materi/Bab', ['bold' => true, 'size' => 10, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(1800, ['bgColor' => '1a3c6e'])->addText('Elemen CP',  ['bold' => true, 'size' => 10, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(900,  ['bgColor' => '1a3c6e'])->addText('Kode TP',    ['bold' => true, 'size' => 10, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(5800, ['bgColor' => '1a3c6e'])->addText('Tujuan Pembelajaran', ['bold' => true, 'size' => 10, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(600,  ['bgColor' => '1a3c6e'])->addText('JP',         ['bold' => true, 'size' => 10, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Dim. Profil Lulusan', ['bold' => true, 'size' => 10, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        if ($isMadrasah) {
            $table->addCell(1400, ['bgColor' => '1a3c6e'])->addText('Panca Cinta KBC', ['bold' => true, 'size' => 10, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        }

        $tpByChapter = [];
        foreach ($tps as $tp) {
            $chap = $tp['chapter'] ?? '';
            $tpByChapter[$chap][] = $tp;
        }
        $chapterCpMap = json_decode($device['chapter_cp_map'] ?? '{}', true);
        $no = 0;

        foreach ($chapters as $ci => $chap) {
            // Elemen CP per bab
            $chapCpArr = $chapterCpMap[$ci] ?? $chapterCpMap[(string)$ci] ?? [];
            if (!empty($elements) && empty($chapCpArr)) {
                $chapCpArr = array_column($elements, 'name');
            }
            $elementName = is_array($chapCpArr) ? implode(', ', $chapCpArr) : $chapCpArr;
            // DPL per bab
            $chapDpl = $chapterDplMap[$ci] ?? $chapterDplMap[(string)$ci] ?? [];
            $dplText = implode(', ', (array)$chapDpl);
            // KBC per bab
            $chapKbc = $chapterKbcMap[$ci] ?? $chapterKbcMap[(string)$ci] ?? [];
            $kbcText = implode(', ', (array)$chapKbc);

            $chapTps = $tpByChapter[$chap] ?? [];
            if (empty($chapTps)) {
                $no++;
                $table->addRow();
                $table->addCell(500)->addText((string)$no, ['size' => 10], ['alignment' => Jc::CENTER]);
                $table->addCell(2200)->addText($chap, ['bold' => true, 'size' => 10]);
                $table->addCell(1800)->addText($elementName, ['size' => 10]);
                $table->addCell(900)->addText('-', ['size' => 10], ['alignment' => Jc::CENTER]);
                $table->addCell(5800)->addText('-', ['size' => 10]);
                $table->addCell(600)->addText('-', ['size' => 10], ['alignment' => Jc::CENTER]);
                $table->addCell(2000)->addText($dplText, ['size' => 10]);
                if ($isMadrasah) $table->addCell(1400)->addText($kbcText, ['size' => 10]);
            } else {
                foreach ($chapTps as $tpi => $tp) {
                    $no++;
                    $table->addRow();
                    $table->addCell(500)->addText((string)$no, ['size' => 10], ['alignment' => Jc::CENTER]);
                    if ($tpi === 0) {
                        $table->addCell(2200, ['vMerge' => 'restart'])->addText($chap, ['bold' => true, 'size' => 10]);
                        $table->addCell(1800, ['vMerge' => 'restart'])->addText($elementName, ['size' => 10]);
                    } else {
                        $table->addCell(2200, ['vMerge' => 'continue']);
                        $table->addCell(1800, ['vMerge' => 'continue']);
                    }
                    $table->addCell(900)->addText($tp['code'] ?? '', ['size' => 10], ['alignment' => Jc::CENTER]);
                    $table->addCell(5800)->addText($tp['description'] ?? '', ['size' => 10]);
                    $table->addCell(600)->addText((string)($tp['allocated_hours'] ?? '-'), ['size' => 10], ['alignment' => Jc::CENTER]);
                    if ($tpi === 0) {
                        $table->addCell(2000, ['vMerge' => 'restart'])->addText($dplText, ['size' => 10]);
                        if ($isMadrasah) $table->addCell(1400, ['vMerge' => 'restart'])->addText($kbcText, ['size' => 10]);
                    } else {
                        $table->addCell(2000, ['vMerge' => 'continue']);
                        if ($isMadrasah) $table->addCell(1400, ['vMerge' => 'continue']);
                    }
                }
            }
        }
        $section->addTextBreak(1);

        // Tanda tangan
        $principalName = $settings['principal_name'] ?? '[Kepala Sekolah]';
        $principalNip = $settings['principal_nip'] ?? '-';
        $teacherName = $device['teacher_name'] ?? 'Guru';
        $teacherNip = $device['teacher_nip'] ?? '-';
        $city = $settings['letter_city'] ?? $settings['city'] ?? '........................';
        if (empty(trim($city, '. '))) {
            $city = '........................';
        }
        $headLabel = ($device['school_type'] === 'madrasah') ? 'Kepala Madrasah' : 'Kepala Sekolah';
        $ttdTable = $section->addTable(['borderColor' => 'FFFFFF', 'borderSize' => 0]);
        $ttdTable->addRow();
        $kiri = $ttdTable->addCell(7600);
        $kiri->addText('Mengetahui,', ['size' => 11], ['alignment' => Jc::CENTER]);
        $kiri->addText($headLabel . ',', ['size' => 11], ['alignment' => Jc::CENTER]);
        $kiri->addTextBreak(4);
        $kiri->addText($principalName, ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
        $kiri->addText('NIP. ' . $principalNip, ['size' => 11], ['alignment' => Jc::CENTER]);
        $kanan = $ttdTable->addCell(7600);
        $kanan->addText("{$city}, ......................................", ['size' => 11], ['alignment' => Jc::CENTER]);
        $kanan->addText('Guru Mata Pelajaran,', ['size' => 11], ['alignment' => Jc::CENTER]);
        $kanan->addTextBreak(4);
        $kanan->addText($teacherName, ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
        $kanan->addText(guess_id_label($teacherNip) . '. ' . $teacherNip, ['size' => 11], ['alignment' => Jc::CENTER]);

        $tempFile = tempnam(sys_get_temp_dir(), 'cp_tp_') . '.docx';
        $writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        $writer->save($tempFile);
        $content = file_get_contents($tempFile);
        unlink($tempFile);
        return $content;
    }

    // ================================================================
    // EXPORT: ATP (Landscape)
    // ================================================================
    public function exportAtpWord(array $device, array $tps, array $chapters, array $chapterDplMap, array $chapterKbcMap, ?array $settings): string
    {
        $phpWord = new \PhpOffice\PhpWord\PhpWord();
        $phpWord->setDefaultFontName('Arial');
        $phpWord->setDefaultFontSize(11);
        $section = $phpWord->addSection([
            'orientation'  => 'landscape',
            'marginTop'    => 800,
            'marginBottom' => 800,
            'marginLeft'   => 800,
            'marginRight'  => 800,
            'pageSizeW'    => \PhpOffice\PhpWord\Shared\Converter::cmToTwip(29.7),
            'pageSizeH'    => \PhpOffice\PhpWord\Shared\Converter::cmToTwip(21.0)
        ]);
        // Available width: 15200

        $this->addWordHeader($section, $settings, "ALUR TUJUAN PEMBELAJARAN (ATP)");
        $this->addWordMetaTable($section, $device);

        // Tabel: No | TP | Materi | Semester | JP | DPL | PC — total 15200
        $table = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 40]);
        $table->addRow(null, 300);
        $table->addCell(500, ['bgColor' => '1a3c6e'])->addText('No', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(4300, ['bgColor' => '1a3c6e'])->addText('Tujuan Pembelajaran', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(2100, ['bgColor' => '1a3c6e'])->addText('Materi', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(800, ['bgColor' => '1a3c6e'])->addText('Semester', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(700, ['bgColor' => '1a3c6e'])->addText('JP', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(3300, ['bgColor' => '1a3c6e'])->addText('Dimensi Profil Lulusan', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $table->addCell(3500, ['bgColor' => '1a3c6e'])->addText('Dimensi Panca Cinta', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);

        $tpByChapter = [];
        foreach ($tps as $tp) {
            $chap = $tp['chapter'] ?? '';
            $tpByChapter[$chap][] = $tp;
        }
        $no = 0;

        foreach ($chapters as $ci => $chap) {
            $dplText = implode(', ', $chapterDplMap[$ci] ?? []);
            $pcText = implode(', ', $chapterKbcMap[$ci] ?? []);
            if (empty($dplText)) $dplText = $device['dpl'] ?? '-';
            if (empty($pcText)) $pcText = $device['panca_cinta'] ?? '-';
            $chapTps = $tpByChapter[$chap] ?? [];
            if (!empty($chapTps)) {
                foreach ($chapTps as $tpi => $tp) {
                    $no++;
                    $table->addRow();
                    $table->addCell(500)->addText((string)$no, ['size' => 11], ['alignment' => Jc::CENTER]);
                    $table->addCell(4300)->addText($tp['code'] . ': ' . $tp['description'], ['size' => 11]);
                    if ($tpi === 0) {
                        $table->addCell(2100, ['vMerge' => 'restart'])->addText($chap, ['bold' => true, 'size' => 11]);
                        $table->addCell(800, ['vMerge' => 'restart'])->addText('Smt ' . ($tp['semester'] ?? 1), ['size' => 11], ['alignment' => Jc::CENTER]);
                        $table->addCell(700, ['vMerge' => 'restart'])->addText((string)($tp['allocated_hours'] ?? 0), ['size' => 11], ['alignment' => Jc::CENTER]);
                        $table->addCell(3300, ['vMerge' => 'restart'])->addText($dplText, ['size' => 8]);
                        $table->addCell(3500, ['vMerge' => 'restart'])->addText($pcText, ['size' => 8]);
                    } else {
                        $table->addCell(2100, ['vMerge' => 'continue']);
                        $table->addCell(800, ['vMerge' => 'continue']);
                        $table->addCell(700, ['vMerge' => 'continue']);
                        $table->addCell(3300, ['vMerge' => 'continue']);
                        $table->addCell(3500, ['vMerge' => 'continue']);
                    }
                }
            }
        }
        $section->addTextBreak(1);

        // Tanda tangan
        $principalName = $settings['principal_name'] ?? '[Kepala Sekolah]';
        $principalNip = $settings['principal_nip'] ?? '-';
        $teacherName = $device['teacher_name'] ?? 'Guru';
        $teacherNip = $device['teacher_nip'] ?? '-';
        $city = $settings['letter_city'] ?? $settings['city'] ?? '........................';
        if (empty(trim($city, '. '))) {
            $city = '........................';
        }
        $headLabel = ($device['school_type'] === 'madrasah') ? 'Kepala Madrasah' : 'Kepala Sekolah';
        $ttdTable = $section->addTable(['borderColor' => 'FFFFFF', 'borderSize' => 0]);
        $ttdTable->addRow();
        $kiri = $ttdTable->addCell(7600);
        $kiri->addText('Mengetahui,', ['size' => 11], ['alignment' => Jc::CENTER]);
        $kiri->addText($headLabel . ',', ['size' => 11], ['alignment' => Jc::CENTER]);
        $kiri->addTextBreak(4);
        $kiri->addText($principalName, ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
        $kiri->addText('NIP. ' . $principalNip, ['size' => 11], ['alignment' => Jc::CENTER]);
        $kanan = $ttdTable->addCell(7600);
        $kanan->addText("{$city}, ......................................", ['size' => 11], ['alignment' => Jc::CENTER]);
        $kanan->addText('Guru Mata Pelajaran,', ['size' => 11], ['alignment' => Jc::CENTER]);
        $kanan->addTextBreak(4);
        $kanan->addText($teacherName, ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
        $kanan->addText(guess_id_label($teacherNip) . '. ' . $teacherNip, ['size' => 11], ['alignment' => Jc::CENTER]);

        $tempFile = tempnam(sys_get_temp_dir(), 'atp_') . '.docx';
        $writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        $writer->save($tempFile);
        $content = file_get_contents($tempFile);
        unlink($tempFile);
        return $content;
    }

    // ================================================================
    // EXPORT: KKTP (Landscape)
    // ================================================================
    public function exportKktpWord(array $device, array $kktps, array $intervals, ?array $settings): string
    {
        $phpWord = new \PhpOffice\PhpWord\PhpWord();
        $phpWord->setDefaultFontName('Arial');
        $phpWord->setDefaultFontSize(11);
        $section = $phpWord->addSection([
            'orientation'  => 'landscape',
            'marginTop'    => 800,
            'marginBottom' => 800,
            'marginLeft'   => 800,
            'marginRight'  => 800,
            'pageSizeW'    => \PhpOffice\PhpWord\Shared\Converter::cmToTwip(29.7),
            'pageSizeH'    => \PhpOffice\PhpWord\Shared\Converter::cmToTwip(21.0)
        ]);

        $schoolName = $settings['school_name'] ?? 'SIMAK';
        $this->addWordHeader($section, $settings, "KRITERIA KETERCAPAIAN TUJUAN PEMBELAJARAN (KKTP)");
        $this->addWordMetaTable($section, $device);

        // Level pencapaian
        $bimbinganMax = $intervals['bimbingan'] ?? 59;
        $cukupMin = $bimbinganMax + 1;
        $cukupMax = $intervals['cukup'] ?? 69;
        $baikMin = $cukupMax + 1;
        $baikMax = $intervals['baik'] ?? 84;
        $sangatBaikMin = $baikMax + 1;

        $section->addText('A. Pendekatan dan Cara Penggunaan KKTP', ['bold' => true, 'size' => 11]);
        $section->addText('Kriteria Ketercapaian Tujuan Pembelajaran (KKTP) ini disusun menggunakan pendekatan kombinasi: (1) deskripsi kriteria kualitatif yang menjelaskan capaian murid pada empat level, dan (2) interval nilai/skor kuantitatif (skala 0-100) sebagai pedoman konversi hasil asesmen ke dalam laporan hasil belajar.', ['size' => 11]);
        $section->addText('Empat level pencapaian:', ['size' => 11]);

        $levelTable = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
        $levelTable->addRow();
        $levelTable->addCell(3000, ['bgColor' => '1a3c6e'])->addText('Level Pencapaian', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $levelTable->addCell(2000, ['bgColor' => '1a3c6e'])->addText('Interval Nilai', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $levelTable->addCell(10200, ['bgColor' => '1a3c6e'])->addText('Makna', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
        $makna = [
            ['Perlu Bimbingan', '0 - ' . $bimbinganMax, 'Murid belum menguasai sebagian besar indikator TP dan memerlukan remedial.'],
            ['Cukup', $cukupMin . ' - ' . $cukupMax, 'Murid mulai menguasai sebagian indikator TP, namun masih perlu bimbingan.'],
            ['Baik', $baikMin . ' - ' . $baikMax, 'Murid menguasai sebagian besar indikator TP (tuntas).'],
            ['Sangat Baik', $sangatBaikMin . ' - 100', 'Murid menguasai seluruh indikator TP secara konsisten.'],
        ];
        foreach ($makna as $m) {
            $levelTable->addRow();
            $levelTable->addCell(3000)->addText($m[0], ['bold' => true, 'size' => 11]);
            $levelTable->addCell(2000)->addText($m[1], ['size' => 11], ['alignment' => Jc::CENTER]);
            $levelTable->addCell(10200)->addText($m[2], ['size' => 11]);
        }
        $section->addTextBreak(1);

        // B. KKTP per TP
        $section->addText('B. KKTP per Tujuan Pembelajaran (TP)', ['bold' => true, 'size' => 11]);

        foreach ($kktps as $k) {
            $section->addText($k['code'] . ' : ' . $k['tp_description'], ['bold' => true, 'size' => 11]);

            // Indikator - borderless table
            $section->addText('Indikator Ketercapaian:', ['bold' => true, 'size' => 11]);
            $indLines = explode("\n", $k['indicators'] ?? '');
            $indTable = $section->addTable(['borderColor' => 'FFFFFF', 'borderSize' => 0, 'cellMargin' => 20]);
            $no = 0;
            foreach ($indLines as $line) {
                $line = trim($line);
                if (empty($line)) continue;
                $no++;
                $indTable->addRow();
                $indTable->addCell(300)->addText($no . '.', ['size' => 11]);
                $indTable->addCell(14900)->addText($line, ['size' => 11]);
            }

            // Rubrik 4 level
            $rubTable = $section->addTable(['borderSize' => 6, 'borderColor' => '222222', 'cellMargin' => 60]);
            $rubTable->addRow();
            $rubTable->addCell(3800, ['bgColor' => '1a3c6e'])->addText('Perlu Bimbingan (0 - ' . $bimbinganMax . ')', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rubTable->addCell(3800, ['bgColor' => '1a3c6e'])->addText('Cukup (' . $cukupMin . ' - ' . $cukupMax . ')', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rubTable->addCell(3800, ['bgColor' => '1a3c6e'])->addText('Baik (' . $baikMin . ' - ' . $baikMax . ')', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rubTable->addCell(3800, ['bgColor' => '1a3c6e'])->addText('Sangat Baik (' . $sangatBaikMin . ' - 100)', ['bold' => true, 'size' => 11, 'color' => 'FFFFFF'], ['alignment' => Jc::CENTER]);
            $rubTable->addRow();
            $rubTable->addCell(3800)->addText($k['rubric_bimbingan'] ?? '-', ['size' => 11]);
            $rubTable->addCell(3800)->addText($k['rubric_cukup'] ?? '-', ['size' => 11]);
            $rubTable->addCell(3800)->addText($k['rubric_baik'] ?? '-', ['size' => 11]);
            $rubTable->addCell(3800)->addText($k['rubric_sangat_baik'] ?? '-', ['size' => 11]);
            $section->addTextBreak(1);
        }

        // C. Catatan Implementasi
        $section->addText('C. Catatan Implementasi', ['bold' => true, 'size' => 11]);
        $catatan = [
            'KKTP ini digunakan sebagai acuan penyusunan instrumen asesmen formatif dan sumatif pada setiap TP ' . $device['subject_name'] . ' Kelas ' . $device['grade_name'] . '.',
            'Guru dapat mengembangkan indikator ketercapaian menjadi kisi-kisi soal atau rubrik yang lebih rinci.',
            'Skor akhir suatu TP diperoleh dari rata-rata beberapa bentuk asesmen sesuai kebijakan satuan pendidikan.',
            'KKTP ini bersifat dinamis dan dapat disesuaikan berdasarkan hasil evaluasi pembelajaran dan karakteristik murid di ' . $schoolName . '.',
        ];
        $catTable = $section->addTable(['borderColor' => 'FFFFFF', 'borderSize' => 0, 'cellMargin' => 20]);
        foreach ($catatan as $ci => $c) {
            $catTable->addRow();
            $catTable->addCell(300)->addText(($ci + 1) . '.', ['size' => 11]);
            $catTable->addCell(14900)->addText($c, ['size' => 11]);
        }
        $section->addTextBreak(1);

        // Tanda tangan
        $principalName = $settings['principal_name'] ?? $settings['headmaster_name'] ?? '[Kepala Sekolah]';
        $principalNip = $settings['principal_nip'] ?? $settings['headmaster_nip'] ?? '-';
        $teacherName = $device['teacher_name'] ?? 'Guru';
        $teacherNip = $device['teacher_nip'] ?? '-';
        $city = $settings['letter_city'] ?? $settings['city'] ?? '........................';
        if (empty(trim($city, '. '))) {
            $city = '........................';
        }
        $ttdTable = $section->addTable(['borderColor' => 'FFFFFF', 'borderSize' => 0]);
        $ttdTable->addRow();
        $kiri = $ttdTable->addCell(7600);
        $kiri->addText('Mengetahui,', ['size' => 11], ['alignment' => Jc::CENTER]);
        $kiri->addText(($device['school_type'] === 'madrasah' ? 'Kepala Madrasah' : 'Kepala Sekolah') . ',', ['size' => 11], ['alignment' => Jc::CENTER]);
        $kiri->addTextBreak(4);
        $kiri->addText($principalName, ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
        $kiri->addText('NIP. ' . $principalNip, ['size' => 11], ['alignment' => Jc::CENTER]);
        $kanan = $ttdTable->addCell(7600);
        $kanan->addText("{$city}, ......................................", ['size' => 11], ['alignment' => Jc::CENTER]);
        $kanan->addText('Guru Mata Pelajaran,', ['size' => 11], ['alignment' => Jc::CENTER]);
        $kanan->addTextBreak(4);
        $kanan->addText($teacherName, ['bold' => true, 'size' => 11], ['alignment' => Jc::CENTER]);
        $kanan->addText(guess_id_label($teacherNip) . '. ' . $teacherNip, ['size' => 11], ['alignment' => Jc::CENTER]);

        $tempFile = tempnam(sys_get_temp_dir(), 'kktp_') . '.docx';
        $writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        $writer->save($tempFile);
        $content = file_get_contents($tempFile);
        unlink($tempFile);
        return $content;
    }

    /**
     * Helper to get Indonesian Date format
     */
    private function getIndonesianDate(): string
    {
        $months = [
            'January' => 'Januari', 'February' => 'Februari', 'March' => 'Maret',
            'April' => 'April', 'May' => 'Mei', 'June' => 'Juni',
            'July' => 'Juli', 'August' => 'Agustus', 'September' => 'September',
            'October' => 'Oktober', 'November' => 'November', 'December' => 'Desember'
        ];
        return date('d') . ' ' . ($months[date('F')] ?? date('F')) . ' ' . date('Y');
    }
}
