<?php

namespace App\Controllers\Guru;

use App\Controllers\BaseController;
use App\Models\TeacherModel;
use App\Models\SchoolSettingModel;
use App\Models\LearningDeviceModel;
use App\Models\LearningDeviceTpModel;
use App\Models\LearningDeviceProtaModel;
use App\Models\LearningDevicePromesModel;
use App\Models\LearningDeviceModulModel;
use App\Models\LearningDeviceKktpModel;
use App\Controllers\Guru\Traits\DeviceHelperTrait;

class LearningDeviceController extends BaseController
{
    use DeviceHelperTrait;

    protected $teacherModel;
    protected $deviceModel;
    protected $deviceTpModel;
    protected $protaModel;
    protected $promesModel;
    protected $modulModel;
    protected $kktpModel;

    public function __construct()
    {
        $this->teacherModel  = new TeacherModel();
        $this->deviceModel   = new LearningDeviceModel();
        $this->deviceTpModel = new LearningDeviceTpModel();
        $this->protaModel    = new LearningDeviceProtaModel();
        $this->promesModel   = new LearningDevicePromesModel();
        $this->modulModel    = new LearningDeviceModulModel();
        $this->kktpModel     = new LearningDeviceKktpModel();
    }

    // ================================================================
    // RPM (Rencana Pelaksanaan Mengajar / Modul Ajar)
    // ================================================================

    /**
     * Halaman RPM - Daftar Modul per Bab
     */
    public function rpm($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $teacher = $this->getTeacher();
        if (!$teacher) {
            return redirect()->to('/dashboard')->with('error', 'Data guru tidak ditemukan!');
        }

        $device = $this->deviceModel->getDetail($id, $teacher['user_id']);
        if (!$device) {
            return redirect()->to('/guru/learning-devices')->with('error', 'Dokumen tidak ditemukan.');
        }

        $tps = $this->deviceTpModel->getByDevice($id);

        if (empty($tps)) {
            return redirect()->to('/guru/learning-devices/tp/' . $id)->with('error', 'Harap rumuskan Tujuan Pembelajaran (TP) terlebih dahulu!');
        }

        $chapters = json_decode($device['chapters'] ?? '[]', true) ?: [];
        $chaptersData = [];

        if (!empty($chapters)) {
            foreach ($chapters as $idx => $chapter) {
                $chaptersData[] = [
                    'index'    => $idx,
                    'name'     => $chapter,
                    'tps'      => [],
                    'totalJp'  => 0,
                ];
            }

            $currentChapIdx = 0;
            foreach ($tps as $tp) {
                $chapName = $tp['chapter'] ?? '';
                $foundIdx = null;
                if (!empty($chapName)) {
                    foreach ($chaptersData as $ci => $cd) {
                        if ($cd['name'] === $chapName) {
                            $foundIdx = $ci;
                            break;
                        }
                    }
                }
                if ($foundIdx === null) {
                    $foundIdx = min($currentChapIdx, count($chaptersData) - 1);
                }
                $chaptersData[$foundIdx]['tps'][] = $tp;
                $chaptersData[$foundIdx]['totalJp'] += (int) ($tp['allocated_hours'] ?? 0);
                $currentChapIdx = $foundIdx + 1;
                if ($currentChapIdx >= count($chaptersData)) {
                    $currentChapIdx = count($chaptersData) - 1;
                }
            }
        } else {
            $totalJp = 0;
            foreach ($tps as $tp) $totalJp += (int) ($tp['allocated_hours'] ?? 0);
            $chaptersData[] = [
                'index'   => 0,
                'name'    => 'Materi Pokok',
                'tps'     => $tps,
                'totalJp' => $totalJp,
            ];
        }

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

        $modulMap = [];
        foreach ($moduls as $m) {
            $ci = (int) ($m['chapter_index'] ?? 0);
            $modulMap[$ci] = $m;
        }

        foreach ($chaptersData as &$cd) {
            $cd['totalPertemuan'] = $this->hitungPertemuanDariPromes($id, $cd['tps']);
        }
        unset($cd);

        $data = [
            'title'         => 'Rencana Pelaksanaan Mengajar (RPM) / Modul Ajar',
            'device'        => $device,
            'chaptersData'  => $chaptersData,
            'modulMap'      => $modulMap,
        ];

        return view('guru/learning_device/rpm', $data);
    }

    /**
     * POST: Generate Modul Ajar via AI (3-stage sequential — OLD system)
     */
    public function generateModul($id)
    {
        if ($redirect = $this->checkLogin()) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Sesi berakhir, silakan login kembali.']);
        }

        $teacher = $this->getTeacher();
        $device = $this->deviceModel->getDetail($id, $teacher['user_id']);
        if (!$device) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Dokumen tidak ditemukan.']);
        }

        $tpId = $this->request->getPost('tp_id');
        $step = (int) $this->request->getPost('step');

        $tp = $this->deviceTpModel->where('id', $tpId)->where('learning_device_id', $id)->first();
        if (!$tp) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Tujuan Pembelajaran tidak ditemukan.']);
        }

        $aiService = new \App\Services\LearningDeviceAiService();
        $existing = $this->modulModel->where('learning_device_id', $id)->where('tp_id', $tpId)->first();

        $dplSelected = $device['school_type'] === 'madrasah' ? '8 DPL (Dimensi Profil Lulusan Kemenag)' : 'Profil Pelajar Pancasila';
        $kbcSelected = $device['school_type'] === 'madrasah' ? 'Panca Cinta KBC Kemenag' : '-';

        if ($step === 1 || empty($step)) {
            $res = $aiService->generateModulStage1($tp, $device['subject_name'], $device['phase'], $device['grade_name'], $device['school_type'], $dplSelected, $kbcSelected);
            if ($res['status'] === 'error') return $this->response->setJSON($res);

            $modulData = $res['data'];
            $dataUpdate = [
                'learning_device_id'    => $id,
                'tp_id'                 => $tpId,
                'topic'                 => $tp['description'],
                'identity'              => json_encode($modulData['identity'] ?? []),
                'core_components'       => json_encode($modulData['core_components'] ?? []),
                'differentiation'       => '[]',
                'assessment'            => '[]',
                'follow_up'             => '[]',
                'reflection'            => '[]',
                'character_integration' => '[]',
            ];

            if ($existing) {
                $this->modulModel->update($existing['id'], $dataUpdate);
            } else {
                $this->modulModel->insert($dataUpdate);
            }

            return $this->response->setJSON(['status' => 'success', 'step' => 1, 'message' => 'Tahap 1 Selesai']);
        }

        if ($step === 2) {
            if (!$existing) return $this->response->setJSON(['status' => 'error', 'message' => 'Data Tahap 1 tidak ditemukan']);

            $stage1Data = is_string($existing['core_components']) ? json_decode($existing['core_components'], true) : $existing['core_components'];

            $res = $aiService->generateModulStage2($tp, $stage1Data, $device['school_type'], $dplSelected, $kbcSelected);
            if ($res['status'] === 'error') return $this->response->setJSON($res);

            $modulData = $res['data'];
            $stage1Data['kegiatan_pembelajaran'] = $modulData['kegiatan_pembelajaran'] ?? [];

            $dataUpdate = [
                'differentiation' => json_encode($modulData['differentiation'] ?? []),
                'core_components' => json_encode($stage1Data),
            ];

            $this->modulModel->update($existing['id'], $dataUpdate);
            return $this->response->setJSON(['status' => 'success', 'step' => 2, 'message' => 'Tahap 2 Selesai']);
        }

        if ($step === 3) {
            if (!$existing) return $this->response->setJSON(['status' => 'error', 'message' => 'Data Tahap 2 tidak ditemukan']);

            $stage2Data = is_string($existing['core_components']) ? json_decode($existing['core_components'], true) : $existing['core_components'];

            $res = $aiService->generateModulStage3($tp, $stage2Data);
            if ($res['status'] === 'error') return $this->response->setJSON($res);

            $modulData = $res['data'];
            $dataUpdate = [
                'assessment'            => json_encode($modulData['assessment'] ?? []),
                'follow_up'             => json_encode($modulData['follow_up'] ?? []),
                'reflection'            => json_encode($modulData['reflection'] ?? []),
                'character_integration' => json_encode($modulData['lampiran'] ?? []),
            ];

            $this->modulModel->update($existing['id'], $dataUpdate);

            return $this->response->setJSON([
                'status'  => 'success',
                'step'    => 3,
                'message' => 'Modul Ajar berhasil digenerate sepenuhnya oleh AI!',
                'data'    => $this->modulModel->where('learning_device_id', $id)->findAll()
            ]);
        }
    }

    /**
     * POST: Alias untuk generateModul
     */
    public function generateRpmAction($id)
    {
        return $this->generateModul($id);
    }

    // ================================================================
    // RPM FIELD-BY-FIELD EDIT SYSTEM (NEW)
    // ================================================================

    /**
     * GET: Halaman edit Modul Ajar per field (accordion)
     */
    public function rpmEdit($id, $chapterIndex)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $teacher = $this->getTeacher();
        $device = $this->deviceModel->getDetail($id, $teacher['user_id']);
        if (!$device) {
            return redirect()->to('/guru/learning-devices')->with('error', 'Dokumen tidak ditemukan.');
        }

        $chapters = json_decode($device['chapters'] ?? '[]', true) ?: [];
        $chapterIndex = (int) $chapterIndex;
        $chapterName = $chapters[$chapterIndex] ?? 'Materi Pokok';

        $allTps = $this->deviceTpModel->getByDevice($id);
        $chapterTps = array_filter($allTps, function ($tp) use ($chapterName) {
            return ($tp['chapter'] ?? '') === $chapterName;
        });
        $chapterTps = array_values($chapterTps);

        if (empty($chapterTps)) {
            return redirect()->to('/guru/learning-devices/rpm/' . $id)->with('error', 'Tidak ada TP untuk bab ini.');
        }

        $modul = $this->modulModel->firstOrCreateByChapter($id, $chapterIndex);

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

        $jumlahPertemuan = max(1, $this->hitungPertemuanDariPromes($id, $chapterTps));

        $schoolSettingModel = new SchoolSettingModel();
        $settings = $schoolSettingModel->getSettings();

        $chapterKktp = [];
        foreach ($chapterTps as $ctp) {
            $k = $this->kktpModel->where('tp_id', $ctp['id'])->first();
            if ($k) $chapterKktp[] = $k;
        }

        $skenarioData = [];
        $existingSkenario = $modul['skenario_pembelajaran'] ?? '';
        if (!empty($existingSkenario)) {
            $parsed = is_string($existingSkenario) ? json_decode($existingSkenario, true) ?? [] : $existingSkenario;
            $isNewFmt = false;
            foreach ((array)$parsed as $s) {
                if (isset($s['sub_materi']) && (is_string($s['sub_materi']) || isset($s['judul']))) {
                    $isNewFmt = true; break;
                }
            }
            if ($isNewFmt) $skenarioData = $parsed;
        }
        if (empty($skenarioData)) {
            $cntTmp = max(1, $this->hitungPertemuanDariPromes($id, $chapterTps));
            for ($p = 1; $p <= $cntTmp; $p++) {
                $skenarioData[] = ['pertemuan'=>$p, 'judul'=>'Pertemuan '.$p, 'sub_materi'=>'', 'pendahuluan'=>'', 'inti'=>'', 'penutup'=>'', 'iktp'=>[]];
            }
        }
        foreach ($skenarioData as &$s) {
            if (isset($s['sub_materi']) && is_array($s['sub_materi'])) {
                $s['sub_materi'] = implode(', ', $s['sub_materi']);
            }
            $s['sub_materi'] = (string)($s['sub_materi'] ?? '');
            if (!isset($s['iktp']) || !is_array($s['iktp'])) {
                $s['iktp'] = [];
            }
        }
        unset($s);
        $jumlahPertemuan = count($skenarioData);

        $subMateriList = array_map(function($s) {
            $sm = $s['sub_materi'] ?? '';
            return is_array($sm) ? implode(', ', $sm) : (string)$sm;
        }, $skenarioData);

        $iktpList = array_map(fn($s) => $s['iktp'] ?? [], $skenarioData);

        $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);
        }

        // Dynamically resolve cp_content if it's empty or space
        if (empty(trim($device['cp_content'] ?? ''))) {
            $device['cp_content'] = $this->resolveCpContentForChapter($device, $chapterIndex);
        }

        // Ambil DPL & KBC per-chapter
        $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)) $dplChapterDisplay = $device['dpl'] ?? '-';
        if (empty($kbcChapterDisplay)) $kbcChapterDisplay = $device['panca_cinta'] ?? '-';

        $daftarPustaka = $this->generateDaftarPustaka($device, $settings);

        $data = [
            'title'          => 'Edit Modul Ajar - ' . $device['subject_name'],
            'device'         => $device,
            'chapterIndex'   => $chapterIndex,
            'chapterName'    => $chapterName,
            'chapterTps'     => $chapterTps,
            'chapterKktp'    => $chapterKktp,
            'totalJp'        => $totalJp,
            'modul'          => $modul,
            'teacher'        => $teacher,
            'settings'       => $settings,
            'jumlahPertemuan' => $jumlahPertemuan,
            'skenarioData'    => $skenarioData,
            'subMateriList'   => $subMateriList,
            'iktpList'        => $iktpList,
            'cpElementsDisplay' => $cpElementsDisplay,
            'dplChapterDisplay' => $dplChapterDisplay,
            'kbcChapterDisplay' => $kbcChapterDisplay,
            'daftarPustaka'     => $daftarPustaka,
        ];

        return view('guru/learning_device/rpm_edit', $data);
    }

    /**
     * POST: Generate satu field menggunakan AI (AJAX)
     */
    public function rpmGenerateField($id)
    {
        if ($redirect = $this->checkLogin()) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Sesi berakhir.']);
        }

        $teacher = $this->getTeacher();
        $device = $this->deviceModel->getDetail($id, $teacher['user_id']);
        if (!$device) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Dokumen tidak ditemukan.']);
        }

        $tpId = $this->request->getPost('tp_id');
        $field = $this->request->getPost('field');
        $pertemuan = $this->request->getPost('pertemuan');
        $chapterIndex = $this->request->getPost('chapter_index');
        $subMateriCount = (int) $this->request->getPost('sub_materi_count');
        $subMateriText = $this->request->getPost('sub_materi');
        $iktpCount = (int) $this->request->getPost('iktp_count');
        $pertemuanIktp = $this->request->getPost('iktp_list');

        $modul = $this->modulModel->where('learning_device_id', $id)
            ->where('chapter_index', (int)$chapterIndex)->first();
        $modelPembelajaran = $modul['model_pembelajaran'] ?? '';

        $chapterKktpText = '';
        $chapterKktp = [];
        $allTps = $this->deviceTpModel->getByDevice($id);
        foreach ($allTps as $tp) {
            $k = $this->kktpModel->where('tp_id', $tp['id'])->first();
            if ($k) $chapterKktp[] = $k;
        }
        foreach ($chapterKktp as $ck) {
            $chapterKktpText .= ($ck['indicators'] ?? '') . "\n";
        }

        $allTps = $this->deviceTpModel->getByDevice($id);
        $chapters = json_decode($device['chapters'] ?? '[]', true) ?: [];
        $chapterName = $chapters[(int)$chapterIndex] ?? '';
        $chapterTps = array_values(array_filter($allTps, function ($tp) use ($chapterName) {
            return ($tp['chapter'] ?? '') === $chapterName;
        }));

        // Dynamically resolve cp_content for AI context if empty/space
        if (empty(trim($device['cp_content'] ?? ''))) {
            $device['cp_content'] = $this->resolveCpContentForChapter($device, (int)$chapterIndex);
        }

        $firstTp = $chapterTps[0] ?? null;
        if (!$firstTp) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'TP tidak ditemukan untuk bab ini.']);
        }

        $tp = $firstTp;
        $aiService = new \App\Services\LearningDeviceAiService();

        $iktpListArr = [];
        if (!empty($pertemuanIktp)) {
            $parsed = json_decode($pertemuanIktp, true);
            if (is_array($parsed)) $iktpListArr = $parsed;
        }
        // Ambil DPL & KBC per-chapter untuk bab ini
        $chapterDplMap = json_decode($device['chapter_dpl'] ?? '{}', true) ?: [];
        $chapterKbcMap = json_decode($device['chapter_kbc'] ?? '{}', true) ?: [];
        $dplChapter = $chapterDplMap[(int)$chapterIndex] ?? [];
        $kbcChapter = $chapterKbcMap[(int)$chapterIndex] ?? [];

        $context = [
            'device' => $device,
            'tp' => $tp,
            'pertemuan' => $pertemuan,
            'chapter_name' => $chapterName,
            'tp_descriptions' => array_map(fn($t) => $t['description'] ?? '', $chapterTps),
            'sub_materi_text' => $subMateriText ?? '',
            'dpl_text' => !empty($dplChapter) ? implode(', ', $dplChapter) : ($device['dpl'] ?? ''),
            'panca_cinta_text' => !empty($kbcChapter) ? implode(', ', $kbcChapter) : ($device['panca_cinta'] ?? ''),
            'model_pembelajaran' => $modelPembelajaran,
            'kktp_text' => $chapterKktpText,
            'iktp_list' => $iktpListArr,
        ];

        if ($field === 'sub_materi') {
            $context['sub_materi_count'] = max(1, $subMateriCount);
        }
        if ($field === 'iktp') {
            $context['iktp_count'] = max(1, $iktpCount);
        }
        if ($field === 'lkpd' && $modul) {
            $skenarioRaw = $modul['skenario_pembelajaran'] ?? '';
            $skenarioData = [];
            if (!empty($skenarioRaw)) {
                $skenarioData = is_string($skenarioRaw) ? json_decode($skenarioRaw, true) ?? [] : $skenarioRaw;
            }
            // Ambil data pertemuan spesifik untuk konteks LKPD
            $pertemuanData = [];
            foreach ((array)$skenarioData as $s) {
                if (($s['pertemuan'] ?? 0) == $pertemuan) {
                    $pertemuanData = $s;
                    break;
                }
            }
            $context['pertemuan_data'] = $pertemuanData;
            $context['skenario_data'] = $skenarioData;

            $result = $aiService->generateModulField($field, $context);

            if ($result['status'] === 'success') {
                return $this->response->setJSON([
                    'status' => 'success',
                    'data'   => [
                        'lkpd_langkah'   => $result['data']['lkpd_langkah'] ?? '',
                        'lkpd_soal'      => $result['data']['lkpd_soal'] ?? '',
                        'lkpd_kesimpulan'=> $result['data']['lkpd_kesimpulan'] ?? '',
                    ]
                ]);
            }

            return $this->response->setJSON($result);
        }

        $result = $aiService->generateModulField($field, $context);

        if ($result['status'] === 'success') {
            return $this->response->setJSON([
                'status' => 'success',
                'data'   => ['content' => $result['data']]
            ]);
        }

        return $this->response->setJSON($result);
    }

    /**
     * POST: Simpan satu field (AJAX)
     */
    public function rpmSaveField($id)
    {
        if ($redirect = $this->checkLogin()) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Sesi berakhir.']);
        }

        $teacher = $this->getTeacher();
        $device = $this->deviceModel->where('id', $id)->where('user_id', $teacher['user_id'])->first();
        if (!$device) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Dokumen tidak ditemukan.']);
        }

        $chapterIndex = (int) $this->request->getPost('chapter_index');
        $field = $this->request->getPost('field');
        $content = $this->request->getPost('content');

        $allowedFields = [
            'kompetensi_awal', 'sarana_prasarana', 'target_peserta_didik',
            'model_pembelajaran', 'pemahaman_bermakna', 'pertanyaan_pemantik',
            'materi_esensial', 'skenario_pembelajaran',
            'asesmen_diagnostik', 'asesmen_formatif', 'asesmen_sumatif',
            'pengayaan', 'remedial', 'lkpd', 'glosarium', 'daftar_pustaka',
            'topic',
        ];

        if ($field === 'skenario_pembelajaran_lkpd') {
            // Khusus untuk save LKPD — merge ke data skenario yang sudah ada
            $existing = $this->modulModel->where('learning_device_id', $id)->where('chapter_index', $chapterIndex)->first();
            $existingSkenario = $existing['skenario_pembelajaran'] ?? '[]';
            $skenarioData = is_string($existingSkenario) ? json_decode($existingSkenario, true) ?? [] : $existingSkenario;

            $lkpdData = json_decode($content, true) ?? [];
            foreach ($lkpdData as $lkpdItem) {
                $pertemuan = $lkpdItem['pertemuan'] ?? 0;
                foreach ($skenarioData as &$sk) {
                    if (($sk['pertemuan'] ?? 0) == $pertemuan) {
                        $sk['lkpd_langkah'] = $lkpdItem['lkpd_langkah'] ?? $sk['lkpd_langkah'] ?? $lkpdItem['lkpd_langkah'] ?? '';
                        $sk['lkpd_soal'] = $lkpdItem['lkpd_soal'] ?? $sk['lkpd_soal'] ?? $lkpdItem['lkpd_soal'] ?? '';
                        $sk['lkpd_kesimpulan'] = $lkpdItem['lkpd_kesimpulan'] ?? $sk['lkpd_kesimpulan'] ?? $lkpdItem['lkpd_kesimpulan'] ?? '';
                        break;
                    }
                }
                unset($sk);
            }

            $updateData = ['skenario_pembelajaran' => json_encode($skenarioData)];
            if ($existing) {
                $this->modulModel->update($existing['id'], $updateData);
            } else {
                $updateData['learning_device_id'] = $id;
                $updateData['topic'] = '';
                $this->modulModel->insert($updateData);
            }
            return $this->response->setJSON(['status' => 'success', 'message' => 'LKPD berhasil disimpan.']);
        }

        // Untuk skenario_pembelajaran dari auto-save — merge LKPD agar tidak hilang
        if ($field === 'skenario_pembelajaran') {
            $existing = $this->modulModel->where('learning_device_id', $id)->where('chapter_index', $chapterIndex)->first();
            $existingSkenario = $existing['skenario_pembelajaran'] ?? '[]';
            $existingData = is_string($existingSkenario) ? json_decode($existingSkenario, true) ?? [] : $existingSkenario;

            $newData = json_decode($content, true) ?? [];

            // Merge LKPD dari data lama ke data baru
            $existingLkpdMap = [];
            foreach ($existingData as $e) {
                $ep = $e['pertemuan'] ?? 0;
                if (!empty($e['lkpd_langkah']) || !empty($e['lkpd_soal']) || !empty($e['lkpd_kesimpulan'])) {
                    $existingLkpdMap[$ep] = [
                        'lkpd_langkah' => $e['lkpd_langkah'] ?? '',
                        'lkpd_soal' => $e['lkpd_soal'] ?? '',
                        'lkpd_kesimpulan' => $e['lkpd_kesimpulan'] ?? '',
                    ];
                }
            }

            foreach ($newData as &$nd) {
                $np = $nd['pertemuan'] ?? 0;
                if (isset($existingLkpdMap[$np])) {
                    // Hanya merge kalau field LKPD yang dikirim kosong tapi di DB ada isinya
                    if (empty($nd['lkpd_langkah']) && !empty($existingLkpdMap[$np]['lkpd_langkah'])) {
                        $nd['lkpd_langkah'] = $existingLkpdMap[$np]['lkpd_langkah'];
                    }
                    if (empty($nd['lkpd_soal']) && !empty($existingLkpdMap[$np]['lkpd_soal'])) {
                        $nd['lkpd_soal'] = $existingLkpdMap[$np]['lkpd_soal'];
                    }
                    if (empty($nd['lkpd_kesimpulan']) && !empty($existingLkpdMap[$np]['lkpd_kesimpulan'])) {
                        $nd['lkpd_kesimpulan'] = $existingLkpdMap[$np]['lkpd_kesimpulan'];
                    }
                }
            }
            unset($nd);

            $content = json_encode($newData);
        }

        if (!in_array($field, $allowedFields)) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Field tidak valid.']);
        }

        $existing = $this->modulModel->where('learning_device_id', $id)->where('chapter_index', $chapterIndex)->first();
        $updateData = [$field => $content];

        $chapters = json_decode($device['chapters'] ?? '[]', true) ?: [];
        $chapterName = $chapters[$chapterIndex] ?? 'Materi Pokok';
        if ($existing && empty($existing['topic'])) {
            $updateData['topic'] = $chapterName;
        }

        if ($existing) {
            $this->modulModel->update($existing['id'], $updateData);
        } else {
            $updateData['learning_device_id'] = $id;
            $updateData['topic'] = $chapterName;
            $this->modulModel->insert($updateData);
        }

        return $this->response->setJSON(['status' => 'success', 'message' => 'Field berhasil disimpan.']);
    }

    /**
     * POST: Clear all AI-generated fields (reset to defaults)
     */
    public function rpmClearAIFields($id)
    {
        if ($redirect = $this->checkLogin()) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Sesi berakhir.']);
        }

        $teacher = $this->getTeacher();
        $device = $this->deviceModel->where('id', $id)->where('user_id', $teacher['user_id'])->first();
        if (!$device) {
            return $this->response->setJSON(['status' => 'error', 'message' => 'Dokumen tidak ditemukan.']);
        }

        $chapterIndex = (int) $this->request->getPost('chapter_index');

        $existing = $this->modulModel->where('learning_device_id', $id)
            ->where('chapter_index', $chapterIndex)->first();
        if (!$existing) {
            return $this->response->setJSON(['status' => 'success', 'message' => 'Tidak ada data modul yang perlu dikosongkan.']);
        }

        $aiFields = [
            'kompetensi_awal', 'sarana_prasarana', 'target_peserta_didik', 'model_pembelajaran',
            'pemahaman_bermakna', 'pertanyaan_pemantik', 'materi_esensial',
            'asesmen_diagnostik', 'asesmen_formatif', 'asesmen_sumatif',
            'pengayaan', 'remedial', 'lkpd', 'glosarium',
            'skenario_pembelajaran',
        ];

        $updateData = [];
        foreach ($aiFields as $field) {
            $updateData[$field] = '';
            if ($field === 'skenario_pembelajaran') {
                $updateData[$field] = '[]';
            }
        }

        $this->modulModel->update($existing['id'], $updateData);

        return $this->response->setJSON(['status' => 'success', 'message' => 'Semua field AI berhasil dikosongkan.']);
    }

    /**
     * GET: Preview Modul Ajar (assembled view)
     */
    public function rpmPreview($id, $chapterIndex)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $teacher = $this->getTeacher();
        $device = $this->deviceModel->getDetail($id, $teacher['user_id']);
        if (!$device) {
            return redirect()->to('/guru/learning-devices')->with('error', 'Dokumen tidak ditemukan.');
        }

        $chapters = json_decode($device['chapters'] ?? '[]', true) ?: [];
        $chapterIndex = (int) $chapterIndex;
        $chapterName = $chapters[$chapterIndex] ?? 'Materi Pokok';

        $allTps = $this->deviceTpModel->getByDevice($id);
        $chapterTps = array_values(array_filter($allTps, function ($tp) use ($chapterName) {
            return ($tp['chapter'] ?? '') === $chapterName;
        }));

        if (empty($chapterTps)) {
            return redirect()->to('/guru/learning-devices/rpm/' . $id)->with('error', 'Tidak ada TP untuk bab ini.');
        }

        $modul = $this->modulModel->where('learning_device_id', $id)
            ->where('chapter_index', $chapterIndex)->first();
        if (!$modul) {
            return redirect()->to('/guru/learning-devices/rpm/' . $id . '/edit/' . $chapterIndex)
                ->with('error', 'Data modul belum ada, silakan isi field terlebih dahulu.');
        }

        $schoolSettingModel = new SchoolSettingModel();
        $settings = $schoolSettingModel->getSettings();

        $kktpList = [];
        foreach ($chapterTps as $tp) {
            $k = $this->kktpModel->where('tp_id', $tp['id'])->first();
            if ($k) $kktpList[] = $k;
        }

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

        $totalJp = 0;
        foreach ($chapterTps as $tp) $totalJp += (int) ($tp['allocated_hours'] ?? 0);
        $jumlahPertemuan = max(1, $this->hitungPertemuanDariPromes($id, $chapterTps));

        $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);
        }

        // Dynamically resolve cp_content if it's empty or space
        if (empty(trim($device['cp_content'] ?? ''))) {
            $device['cp_content'] = $this->resolveCpContentForChapter($device, $chapterIndex);
        }

        $device['teacher_name'] = $teacher['name'] ?? '';
        $device['teacher_nip'] = $teacher['nip'] ?? '';

        // Ambil DPL & KBC per-chapter
        $chapterDplMap = json_decode($device['chapter_dpl'] ?? '{}', true) ?: [];
        $chapterKbcMap = json_decode($device['chapter_kbc'] ?? '{}', true) ?: [];
        $dplChapterDisplay = $chapterDplMap[$chapterIndex] ?? [];
        $kbcChapterDisplay = $chapterKbcMap[$chapterIndex] ?? [];
        if (empty($dplChapterDisplay)) $dplChapterDisplay = json_decode($device['dpl'] ?? '[]', true);
        if (empty($kbcChapterDisplay)) $kbcChapterDisplay = json_decode($device['panca_cinta'] ?? '[]', true);

        $data = [
            'title'         => 'Preview Modul Ajar',
            'device'        => $device,
            'chapterIndex'  => $chapterIndex,
            'chapterName'   => $chapterName,
            'chapterTps'    => $chapterTps,
            'kktpList'      => $kktpList,
            'modul'         => $modul,
            'settings'      => $settings,
            'skenario'      => $skenario,
            'jumlahPertemuan' => $jumlahPertemuan,
            'totalJp'       => $totalJp,
            'cpElementsDisplay' => $cpElementsDisplay,
            'dplChapterDisplay' => $dplChapterDisplay,
            'kbcChapterDisplay' => $kbcChapterDisplay,
            'daftarPustaka' => $this->generateDaftarPustaka($device, $settings),
        ];

        return view('guru/learning_device/rpm_preview', $data);
    }

    /**
     * GET: Export Modul Ajar DOCX berdasarkan chapter (field-by-field)
     */
    public function rpmExportDoc($id, $chapterIndex)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $teacher = $this->getTeacher();
        $device = $this->deviceModel->getDetail($id, $teacher['user_id']);
        if (!$device) {
            return redirect()->to('/guru/learning-devices')->with('error', 'Dokumen tidak ditemukan.');
        }

        $chapters = json_decode($device['chapters'] ?? '[]', true) ?: [];
        $chapterIndex = (int) $chapterIndex;
        $chapterName = $chapters[$chapterIndex] ?? 'Materi Pokok';

        $allTps = $this->deviceTpModel->getByDevice($id);
        $chapterTps = array_values(array_filter($allTps, function ($tp) use ($chapterName) {
            return ($tp['chapter'] ?? '') === $chapterName;
        }));

        if (empty($chapterTps)) {
            return redirect()->to('/guru/learning-devices/rpm/' . $id)->with('error', 'Tidak ada TP untuk bab ini.');
        }

        $modul = $this->modulModel->where('learning_device_id', $id)
            ->where('chapter_index', $chapterIndex)->first();
        if (!$modul) {
            return redirect()->to('/guru/learning-devices/rpm/' . $id . '/edit/' . $chapterIndex)
                ->with('error', 'Data modul belum ada, silakan isi field terlebih dahulu.');
        }

        $device['teacher_name'] = $teacher['name'] ?? '';
        $device['teacher_nip'] = $teacher['nip'] ?? '';

        $schoolSettingModel = new SchoolSettingModel();
        $settings = $schoolSettingModel->getSettings();

        $totalJp = 0;
        foreach ($chapterTps as $tp) $totalJp += (int) ($tp['allocated_hours'] ?? 0);
        $jumlahPertemuan = max(1, $this->hitungPertemuanDariPromes($id, $chapterTps));

        $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);
        }

        // Dynamically resolve cp_content if it's empty or space
        if (empty(trim($device['cp_content'] ?? ''))) {
            $device['cp_content'] = $this->resolveCpContentForChapter($device, $chapterIndex);
        }

        // Ambil DPL & KBC per-chapter
        $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)) $dplChapterDisplay = $device['dpl'] ?? '-';
        if (empty($kbcChapterDisplay)) $kbcChapterDisplay = $device['panca_cinta'] ?? '-';

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

        $exportData = [
            'device'       => $device,
            'settings'     => $settings,
            'modul'        => $modul,
            'chapterName'  => $chapterName,
            'chapterTps'   => $chapterTps,
            'totalJp'      => $totalJp,
            'jumlahPertemuan' => $jumlahPertemuan,
            'cpElementsDisplay' => $cpElementsDisplay,
            'dplChapterDisplay' => $dplChapterDisplay,
            'kbcChapterDisplay' => $kbcChapterDisplay,
            'daftarPustaka' => $modul['daftar_pustaka'] ?? $this->generateDaftarPustaka($device, $settings),
            'skenario'     => $skenario,
        ];

        $exportService = new \App\Services\DocumentExportService();
        $fileContent = $exportService->exportModulBaru($exportData);

        return $this->response->setStatusCode(200)
            ->setContentType('application/vnd.openxmlformats-officedocument.wordprocessingml.document')
            ->setHeader('Content-Disposition', 'attachment; filename="Modul Ajar_' . $device['subject_name'] . '_Bab_' . ($chapterIndex + 1) . '_' . $device['grade_name'] . '.docx"')
            ->setBody($fileContent);
    }

    /**
     * Resolve the CP content based on elements and mapping
     */
    private function resolveCpContentForChapter(array $device, int $chapterIndex): string
    {
        $cpElements = json_decode($device['cp_elements'] ?? '[]', true);
        $chapterCpMap = json_decode($device['chapter_cp_map'] ?? '{}', true);
        $selectedCpElement = $chapterCpMap[$chapterIndex] ?? '';

        $resolvedCpContent = '';
        if (!empty($selectedCpElement)) {
            foreach ($cpElements as $el) {
                if (($el['name'] ?? '') === $selectedCpElement) {
                    $resolvedCpContent = $el['description'] ?? '';
                    break;
                }
            }
        }

        if (empty(trim($resolvedCpContent))) {
            if (!empty($cpElements) && is_array($cpElements)) {
                $parts = [];
                foreach ($cpElements as $el) {
                    if (!empty($el['name']) && !empty($el['description'])) {
                        $parts[] = "Elemen " . $el['name'] . ":\n" . $el['description'];
                    }
                }
                $resolvedCpContent = implode("\n\n", $parts);
            }
        }

        if (empty(trim($resolvedCpContent))) {
            $resolvedCpContent = $device['cp_content'] ?? '';
        }

        return $resolvedCpContent;
    }

    /**
     * GET: Preview all learning device components (RPE, CP, TP, ATP, PROTA, PROMES, KKTP, RPM)
     */
    public function previewAll($id)
    {
        if ($redirect = $this->checkLogin()) return $redirect;

        $teacher = $this->getTeacher();
        if (!$teacher) {
            return redirect()->to('/dashboard')->with('error', 'Data guru tidak ditemukan!');
        }

        $device = $this->deviceModel->getDetail($id, $teacher['user_id']);
        if (!$device) {
            return redirect()->to('/guru/learning-devices')->with('error', 'Dokumen tidak ditemukan.');
        }

        $device['teacher_name'] = $teacher['name'] ?? '';
        $device['teacher_nip'] = $teacher['nip'] ?? '';

        $schoolSettingModel = new \App\Models\SchoolSettingModel();
        $settings = $schoolSettingModel->getSettings();

        // 1. RPE Data
        $pekanEfektifModel = new \App\Models\LearningDevicePekanEfektifModel();
        $rpeRecord = $pekanEfektifModel->where('learning_device_id', $id)->first();
        if ($rpeRecord) {
            $rpeData = json_decode($rpeRecord['content_json'], true);
        } else {
            $rpeData = $this->calculateRpeFromKaldik($id);
        }

        // 2. CP Data
        $elements = json_decode($device['cp_elements'] ?? '[]', true);

        // 3. TP Data
        $tps = $this->deviceTpModel->getByDevice($id);

        // 4. ATP Data
        $chapters = json_decode($device['chapters'] ?? '[]', true) ?: [];
        $dplSelected = json_decode($device['dpl'] ?? '[]', true) ?: [];
        $pcSelected = json_decode($device['panca_cinta'] ?? '[]', true) ?: [];
        // Per-chapter DPL & KBC
        $chapterDplMap = json_decode($device['chapter_dpl'] ?? '{}', true) ?: [];
        $chapterKbcMap = json_decode($device['chapter_kbc'] ?? '{}', true) ?: [];
        $chapterCpMap  = json_decode($device['chapter_cp_map'] ?? '{}', true) ?: [];

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

        // 5. PROTA Data
        $prota = $this->protaModel->getDetailedProta($id);
        $protaMap = [];
        foreach ($prota as $p) {
            $protaMap[$p['tp_id']] = $p;
        }

        // 6. PROMES Data
        $promes = $this->promesModel->getPromesData($id);
        $promesMap = [];
        foreach ($promes as $pr) {
            $promesMap[$pr['tp_id']][$pr['month']][$pr['week_number']] = $pr['allocated_hours'];
        }

        // 7. KKTP Data
        $kktpsData = $this->kktpModel->getByDevice($id);
        $intervalsJson = $device['kktp_intervals'] ?? '';
        $intervals = json_decode($intervalsJson, true) ?: [
            'bimbingan' => 59,
            'cukup'     => 69,
            'baik'      => 84
        ];

        // 8. RPM (Modul Ajar) Data per Chapter
        $modulsData = [];
        foreach ($chapters as $chapterIndex => $chapterName) {
            $chapterTps = array_values(array_filter($tps, function ($tp) use ($chapterName) {
                return ($tp['chapter'] ?? '') === $chapterName;
            }));

            $modul = $this->modulModel->where('learning_device_id', $id)
                ->where('chapter_index', $chapterIndex)->first();

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

                $kktpList = [];
                foreach ($chapterTps as $tp) {
                    $k = $this->kktpModel->where('tp_id', $tp['id'])->first();
                    if ($k) {
                        $k['code'] = $tp['code'];
                        $kktpList[] = $k;
                    }
                }

                $totalJp = 0;
                foreach ($chapterTps as $tp) $totalJp += (int) ($tp['allocated_hours'] ?? 0);
                $jumlahPertemuan = max(1, $this->hitungPertemuanDariPromes($id, $chapterTps));

                $cpElementsDisplay = '';
                $chapterCpMap = json_decode($device['chapter_cp_map'] ?? '{}', true);
                $selectedCpElement = $chapterCpMap[$chapterIndex] ?? '';
                if (!empty($selectedCpElement)) {
                    $cpElementsDisplay = is_array($selectedCpElement) ? implode(', ', $selectedCpElement) : $selectedCpElement;
                } elseif (is_array($elements)) {
                    $names = array_column($elements, '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);
                }

                $modulsData[] = [
                    'chapterIndex'      => $chapterIndex,
                    'chapterName'       => $chapterName,
                    'chapterTps'        => $chapterTps,
                    'kktpList'          => $kktpList,
                    'modul'             => $modul,
                    'skenario'          => $skenario,
                    'jumlahPertemuan'   => $jumlahPertemuan,
                    'totalJp'           => $totalJp,
                    'cpElementsDisplay' => $cpElementsDisplay,
                    'dplChapterDisplay' => $dplChapterDisplay,
                    'kbcChapterDisplay' => $kbcChapterDisplay,
                    'daftarPustaka'     => $this->generateDaftarPustaka($device, $settings),
                ];
            }
        }

        // Get single document type if query param exists (e.g. ?type=rpe)
        $singleType = $this->request->getGet('type');

        $data = [
            'title'           => 'Preview Perangkat Pembelajaran - ' . $device['subject_name'],
            'device'          => $device,
            'settings'        => $settings,
            'teacher'         => $teacher,
            'rpeData'         => $rpeData,
            'elements'        => $elements,
            'tps'             => $tps,
            'chapters'        => $chapters,
            'dplSelected'     => $dplSelected,
            'pcSelected'      => $pcSelected,
            'chapterDplMap'   => $chapterDplMap,
            'chapterKbcMap'   => $chapterKbcMap,
            'chapterCpMap'    => $chapterCpMap,

            'tpByChapter'     => $tpByChapter,
            'prota'           => $prota,
            'protaMap'        => $protaMap,
            'promes'          => $promes,
            'promesMap'       => $promesMap,
            'kktpsData'       => $kktpsData,
            'intervals'       => $intervals,
            'modulsData'      => $modulsData,
            'singleType'      => $singleType,
            'schoolTypeLabel' => ($device['school_type'] === 'madrasah') ? 'Madrasah' : 'Sekolah',
        ];

        return view('guru/learning_device/preview_all', $data);
    }
}
