<?php

namespace App\Services;

class AtpRuleEngine
{
    protected string $subjectGroup;
    protected KkoService $kkoService;

    public function __construct(string $subjectGroup = 'Umum')
    {
        $this->subjectGroup = $subjectGroup;
        $this->kkoService = new KkoService($subjectGroup);
    }

    /**
     * Memetakan kata kerja awal ke level Taksonomi Bloom (C1 - C6)
     */
    protected function getBloomLevel(string $sentence): int
    {
        $words = explode(' ', strtolower(trim($sentence)));
        if (empty($words)) return 1;

        $firstWord = preg_replace('/[^a-z]/', '', $words[0]);

        // Cek kata pertama via KkoService
        $level = $this->kkoService->getBloomLevel($firstWord);
        if ($level !== null) return $level;

        // Cek 3 kata pertama jika kata pertama bukan KKO
        for ($i = 1; $i < min(count($words), 3); $i++) {
            $w = preg_replace('/[^a-z]/', '', $words[$i]);
            $level = $this->kkoService->getBloomLevel($w);
            if ($level !== null) return $level;
        }

        return 2; // default ke C2 (Memahami)
    }

    /**
     * Menjalankan validasi terhadap daftar TP
     */
    public function validate(array $tps, string $cpContent): array
    {
        $score = 100;
        $strengths = [];
        $improvements = [];

        if (empty($tps)) {
            return [
                'score'        => 0,
                'strengths'    => [],
                'improvements' => ['Belum ada Tujuan Pembelajaran yang dirumuskan.']
            ];
        }

        // Rule 1: Seluruh CP tercakup (Cek kata kunci penting CP di teks TP)
        $cpWords = ['menerapkan', 'memahami', 'berpikir', 'komputasional', 'data', 'sistem', 'komputer', 'jaringan', 'internet', 'dampak', 'sosial', 'pemrograman', 'kolaborasi', 'bahasa', 'inggris', 'teks', 'lisan', 'tulisan', 'membaca', 'menulis', 'bilangan', 'aljabar', 'geometri', 'statistika', 'peluang'];
        $matchedKeywords = [];
        $combinedTpText = '';
        foreach ($tps as $tp) {
            $combinedTpText .= ' ' . strtolower($tp['description']);
        }
        foreach ($cpWords as $kw) {
            if (str_contains(strtolower($cpContent), $kw) && str_contains($combinedTpText, $kw)) {
                $matchedKeywords[] = $kw;
            }
        }
        if (count($matchedKeywords) >= 4) {
            $strengths[] = 'Cakupan CP sangat baik, elemen-elemen kunci kompetensi telah terwakili dalam TP.';
        } else {
            $score -= 10;
            $improvements[] = 'Beberapa kompetensi atau kata kunci utama dalam CP belum terwakili secara mendalam pada TP.';
        }

        // Rule 2: Mencakup fase penuh (Minimal ada 4 TP)
        if (count($tps) >= 4) {
            $strengths[] = 'Jumlah Tujuan Pembelajaran mencukupi untuk menggambarkan kompetensi satu fase penuh.';
        } else {
            $score -= 15;
            $improvements[] = 'Jumlah TP terlalu sedikit (' . count($tps) . ' TP). Disarankan minimal memiliki 4 s.d 8 TP agar mencakup satu fase penuh secara komprehensif.';
        }

        // Rule 3: Urutan sederhana ke kompleks (Taksonomi Bloom)
        $bloomLevels = [];
        foreach ($tps as $tp) {
            $bloomLevels[] = $this->getBloomLevel($tp['description']);
        }

        $orderViolations = 0;
        for ($i = 0; $i < count($bloomLevels) - 1; $i++) {
            if ($bloomLevels[$i] - $bloomLevels[$i+1] > 2) {
                $orderViolations++;
            }
        }
        if ($orderViolations === 0) {
            $strengths[] = 'Urutan alur pengajaran logis, bergerak dari kompetensi dasar (konkret) ke tingkat lebih tinggi (abstrak).';
        } else {
            $score -= 15;
            $improvements[] = 'Urutan alur kurang optimal. Ada penurunan tingkat kognitif yang drastis di beberapa materi. Disarankan meletakkan TP dengan kata kerja operasional tingkat tinggi (seperti merancang, mencipta) di akhir alur.';
        }

        // Rule 4: Tidak ada alur bercabang
        $strengths[] = 'Alur bersifat linier dan teratur (tidak ada percabangan kompetensi).';

        // Rule 5: Tidak ada TP duplikat
        $descriptions = [];
        $hasDuplicate = false;
        foreach ($tps as $tp) {
            $descHash = md5(strtolower(trim($tp['description'])));
            if (in_array($descHash, $descriptions)) {
                $hasDuplicate = true;
                break;
            }
            $descriptions[] = $descHash;
        }
        if ($hasDuplicate) {
            $score -= 15;
            $improvements[] = 'Terdeteksi adanya Tujuan Pembelajaran dengan deskripsi yang sangat mirip atau duplikat. Silakan ubah atau gabungkan.';
        } else {
            $strengths[] = 'Tidak ditemukan Tujuan Pembelajaran yang duplikat.';
        }

        // Rule 6 & 7: Tidak terlalu rinci (JP < 4) / tidak terlalu umum (JP > 24)
        $tooDetailed = false;
        $tooGeneral = false;
        foreach ($tps as $tp) {
            if ($tp['allocated_hours'] < 4) {
                $tooDetailed = true;
            }
            if ($tp['allocated_hours'] > 24) {
                $tooGeneral = true;
            }
        }
        if ($tooDetailed) {
            $score -= 10;
            $improvements[] = 'Terdapat TP dengan alokasi JP terlalu sedikit (< 4 JP). Tujuan tersebut mungkin terlalu rinci dan bisa digabungkan ke TP lain.';
        }
        if ($tooGeneral) {
            $score -= 10;
            $improvements[] = 'Terdapat TP dengan alokasi JP sangat besar (> 24 JP). Tujuan tersebut terlalu umum dan sebaiknya dipecah menjadi beberapa TP yang lebih spesifik.';
        }
        if (!$tooDetailed && !$tooGeneral) {
            $strengths[] = 'Porsi alokasi waktu (JP) per TP seimbang dan realistis.';
        }

        // Rule 9: Dimensi karakter tidak dicampur ke ATP
        $hasCharacterWord = false;
        $characterWords = ['profil pelajar pancasila', 'pancasila', 'panca cinta', 'akhlak mulia', 'gotong royong', 'cinta allah', 'cinta rasul'];
        foreach ($tps as $tp) {
            $descLower = strtolower($tp['description']);
            foreach ($characterWords as $cw) {
                if (str_contains($descLower, $cw)) {
                    $hasCharacterWord = true;
                    break 2;
                }
            }
        }
        if ($hasCharacterWord) {
            $score -= 10;
            $improvements[] = 'Ditemukan penyebutan dimensi karakter (seperti Profil Pancasila / Panca Cinta) di dalam teks ATP. Berdasarkan panduan resmi, integrasi karakter dimasukkan pada Modul Ajar, bukan di dalam rumusan ATP.';
        } else {
            $strengths[] = 'Rumusan ATP murni berfokus pada capaian kompetensi akademik (dimensi karakter diintegrasikan nanti pada Modul Ajar).';
        }

        // Rule 10: Siap diturunkan menjadi Prota
        $totalHours = 0;
        foreach ($tps as $tp) {
            $totalHours += $tp['allocated_hours'];
        }
        if ($totalHours >= 36 && $totalHours <= 120) {
            $strengths[] = 'Total beban jam pelajaran (' . $totalHours . ' JP) memadai untuk dipecah menjadi Program Tahunan (Prota) dan Program Semester (Promes).';
        } else {
            $score -= 10;
            $improvements[] = 'Total alokasi waktu keseluruhan (' . $totalHours . ' JP) kurang realistis untuk durasi satu tahun ajaran (idealnya berkisar antara 36 s.d 108 JP tergantung mapel).';
        }

        // Pastikan skor tidak di bawah 10
        $score = max($score, 10);

        return [
            'score'        => $score,
            'strengths'    => $strengths,
            'improvements' => $improvements
        ];
    }
}
