import { ContentStatus, PrismaClient, Visibility, type Prisma } from "@prisma/client";

const prisma = new PrismaClient();

type Node = { type: string; attrs?: Record<string, unknown>; content?: Node[]; text?: string; marks?: { type: string; attrs?: Record<string, unknown> }[] };
const t = (value: string, marks?: Node["marks"]): Node => ({ type: "text", text: value, ...(marks ? { marks } : {}) });
const p = (...content: Node[]): Node => ({ type: "paragraph", content });
const h = (value: string, level = 2): Node => ({ type: "heading", attrs: { level }, content: [t(value)] });
const list = (items: string[], ordered = false): Node => ({ type: ordered ? "orderedList" : "bulletList", content: items.map((item) => ({ type: "listItem", content: [p(t(item))] })) });
const image = (src: string, alt: string): Node => ({ type: "image", attrs: { src, alt, title: alt } });
const code = (value: string): Node => ({ type: "codeBlock", attrs: { language: "sql" }, content: [t(value)] });
const link = (label: string, href: string): Node => t(label, [{ type: "link", attrs: { href, target: "_blank" } }]);

const content = {
  type: "doc",
  content: [
    p(t("phpMyAdmin adalah aplikasi web gratis yang ditulis dengan PHP untuk mengelola server database MySQL atau MariaDB melalui browser. Dengan antarmuka visualnya, pengguna dapat membuat database dan tabel, mengelola data, menjalankan SQL, mengatur akun, serta melakukan backup dan restore.")),
    h("Tujuan Pembelajaran"),
    list([
      "Menjelaskan pengertian, fungsi, manfaat, dan keterbatasan phpMyAdmin.",
      "Menjalankan phpMyAdmin melalui XAMPP dengan urutan yang benar.",
      "Mengenali panel navigasi, menu utama, dan informasi server.",
      "Membuat database, tabel, kolom, primary key, dan data secara visual.",
      "Menjalankan perintah SQL serta melakukan import dan export database.",
      "Menggunakan phpMyAdmin dengan aman dan menghindari penghapusan data tanpa sengaja.",
    ]),
    h("1. Apa Itu phpMyAdmin?"),
    p(t("phpMyAdmin bukan database dan bukan pengganti MySQL/MariaDB. phpMyAdmin adalah alat administrasi berbasis web yang mengirim perintah kepada server database. Karena itu, Apache dan MySQL harus aktif: Apache menjalankan aplikasi phpMyAdmin, sedangkan MySQL/MariaDB menyimpan dan memproses datanya.")),
    h("Fungsi Utama", 3),
    list([
      "Membuat, mengganti nama, menyalin, dan menghapus database atau tabel.",
      "Membuat serta mengubah kolom, tipe data, index, primary key, dan foreign key.",
      "Menambah, melihat, mengubah, mencari, dan menghapus isi tabel.",
      "Menjalankan satu atau banyak perintah SQL.",
      "Mengimpor file SQL/CSV dan mengekspor database sebagai backup.",
      "Mengatur pengguna database beserta hak aksesnya.",
      "Melihat status, variabel, charset, storage engine, trigger, view, dan routine.",
    ]),
    h("2. Cara Menjalankan phpMyAdmin dari XAMPP"),
    list([
      "Buka C:\\xampp\\xampp-control.exe atau cari XAMPP Control Panel pada Start Menu.",
      "Klik Start pada baris Apache. Tunggu sampai baris hijau dan port 80/443 tampil.",
      "Klik Start pada baris MySQL. Tunggu sampai baris hijau dan port 3306 tampil.",
      "Klik Admin pada baris MySQL; browser akan membuka phpMyAdmin.",
      "Alternatifnya, ketik http://localhost/phpmyadmin/ pada address bar browser.",
      "Setelah selesai, tutup halaman browser lalu klik Stop pada MySQL dan Apache.",
    ], true),
    { type: "blockquote", content: [p(t("Jika tombol pada Apache atau MySQL sudah bertuliskan Stop, modul tersebut sudah berjalan—jangan klik lagi kecuali memang ingin menghentikannya."))] },
    h("3. Tampilan Utama phpMyAdmin"),
    image("/uploads/materials/phpmyadmin-guide/phpmyadmin-home.png", "Screenshot tampilan utama phpMyAdmin pada XAMPP lokal"),
    p(t("Screenshot di atas berasal dari instalasi lokal Anda. Bagian kiri adalah panel navigasi database. Bagian atas berisi menu administrasi server. Bagian tengah menampilkan pengaturan umum serta informasi server database, web server, PHP, dan versi phpMyAdmin.")),
    h("Bagian-bagian Antarmuka", 3),
    list([
      "Logo/Home: kembali ke halaman awal phpMyAdmin.",
      "New: membuka formulir untuk membuat database baru.",
      "Panel kiri: memilih database dan membuka tabel menggunakan tanda plus.",
      "Databases: melihat daftar database dan membuat database.",
      "SQL: menulis serta menjalankan perintah SQL.",
      "Status: melihat aktivitas dan statistik server.",
      "User accounts: membuat akun database dan mengatur privilege.",
      "Export dan Import: mencadangkan serta memulihkan database.",
      "Settings: mengatur tampilan dan preferensi phpMyAdmin.",
      "Variables, Charsets, dan Engines: melihat konfigurasi teknis server.",
    ]),
    h("Peringatan pada Tampilan Lokal Anda", 3),
    p(t("Peringatan kuning menyebut ekstensi PHP mbstring belum ditemukan. phpMyAdmin masih dapat terbuka, tetapi mbstring sebaiknya diaktifkan agar pemrosesan teks multibyte berjalan benar. Buka C:\\xampp\\php\\php.ini, cari ;extension=mbstring, hapus tanda titik koma di depannya, simpan, lalu restart Apache.")),
    p(t("Peringatan merah tentang configuration storage berarti sejumlah fitur tambahan seperti bookmark, relasi, atau riwayat belum sepenuhnya dikonfigurasi. Operasi dasar database tetap dapat digunakan. Konfigurasi lanjutan dapat dilakukan kemudian melalui file config.inc.php dan tabel internal phpMyAdmin; jangan mengubahnya tanpa backup.")),
    h("4. Membuat Database Baru"),
    image("/uploads/materials/phpmyadmin-guide/phpmyadmin-databases.png", "Screenshot menu Databases dan formulir Create database"),
    list([
      "Klik Databases pada menu atas atau klik New di panel kiri.",
      "Pada kotak Database name, ketik latihan_phpmyadmin.",
      "Pilih collation utf8mb4_unicode_ci agar mendukung karakter Unicode dengan baik.",
      "Klik Create. Nama database baru akan tampil pada panel kiri.",
    ], true),
    { type: "blockquote", content: [p(t("Gunakan nama database tanpa spasi; pakai huruf kecil dan garis bawah. Jangan memilih Drop pada database yang masih dibutuhkan karena tindakan itu menghapus struktur dan seluruh datanya."))] },
    h("5. Membuat Tabel dan Menentukan Kolom"),
    list([
      "Klik database latihan_phpmyadmin pada panel kiri.",
      "Pada Create table, isi nama tabel siswa dan jumlah kolom 5, lalu klik Create.",
      "Buat id bertipe INT UNSIGNED, aktifkan A_I (AUTO_INCREMENT), lalu pilih PRIMARY.",
      "Buat nis VARCHAR(20), nama VARCHAR(100), kelas VARCHAR(20), dan created_at TIMESTAMP dengan default CURRENT_TIMESTAMP.",
      "Tetapkan nis sebagai UNIQUE agar satu NIS tidak tersimpan dua kali.",
      "Gunakan storage engine InnoDB, kemudian klik Save.",
    ], true),
    image("/uploads/materials/phpmyadmin-guide/database-structure.png", "Screenshot struktur database latihan_phpmyadmin dan tabel siswa"),
    p(t("Pada screenshot, database latihan_phpmyadmin sudah dipilih dan tabel siswa berhasil dibuat. Klik Browse untuk melihat datanya, Structure untuk mengatur kolom, Search untuk mencari, Insert untuk menambah data, Empty untuk mengosongkan isi, dan Drop untuk menghapus tabel. Gunakan Empty dan Drop dengan sangat hati-hati.")),
    h("Mengenal Tipe Data", 3),
    {
      type: "table",
      content: [
        { type: "tableRow", content: ["Tipe", "Kegunaan", "Contoh"].map((v) => ({ type: "tableHeader", content: [p(t(v))] })) },
        ...[
          ["INT", "Bilangan bulat dan ID numerik", "id, jumlah"],
          ["VARCHAR(n)", "Teks pendek dengan panjang maksimum", "nama, email"],
          ["TEXT", "Teks panjang", "deskripsi"],
          ["DATE", "Tanggal tanpa waktu", "tanggal_lahir"],
          ["DATETIME/TIMESTAMP", "Tanggal dan waktu", "created_at"],
          ["DECIMAL(p,s)", "Nilai desimal presisi", "harga"],
          ["BOOLEAN", "Nilai benar atau salah", "is_active"],
        ].map((row) => ({ type: "tableRow", content: row.map((v) => ({ type: "tableCell", content: [p(t(v))] })) })),
      ],
    },
    h("6. Mengelola Data dari Menu Tabel"),
    list([
      "Browse: melihat baris data dan membuka aksi Edit, Copy, atau Delete.",
      "Structure: mengubah kolom, index, primary key, dan relasi tabel.",
      "SQL: menjalankan query dalam konteks database atau tabel terpilih.",
      "Search: mencari data menggunakan kondisi tertentu.",
      "Insert: menambahkan satu atau beberapa baris data melalui formulir.",
      "Export/Import: memindahkan struktur dan data tabel.",
      "Operations: mengganti nama, menyalin, mengosongkan, atau menghapus tabel.",
    ]),
    p(t("Untuk menambahkan data secara visual, pilih tabel siswa → Insert → isi nis, nama, dan kelas → klik Go. Kolom id dan created_at dapat dibiarkan kosong karena nilainya dibuat otomatis.")),
    image("/uploads/materials/phpmyadmin-guide/table-browse.png", "Screenshot menu Browse dengan tiga data siswa"),
    p(t("Menu Browse pada screenshot menampilkan tiga baris data latihan. Tombol Edit mengubah satu baris, Copy menggandakan data sebagai dasar record baru, dan Delete menghapus baris tersebut. Filter rows dapat dipakai mencari data yang sedang terlihat.")),
    h("7. Menjalankan SQL"),
    image("/uploads/materials/phpmyadmin-guide/phpmyadmin-sql.png", "Screenshot editor SQL phpMyAdmin dan tombol Go"),
    p(t("Klik tab SQL, tulis query pada editor putih, lalu klik tombol Go di bagian bawah. Pastikan database yang benar sudah dipilih di panel kiri sebelum menjalankan query yang mengubah data.")),
    code("CREATE DATABASE IF NOT EXISTS latihan_phpmyadmin\n  CHARACTER SET utf8mb4\n  COLLATE utf8mb4_unicode_ci;\n\nUSE latihan_phpmyadmin;\n\nCREATE TABLE siswa (\n  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,\n  nis VARCHAR(20) NOT NULL UNIQUE,\n  nama VARCHAR(100) NOT NULL,\n  kelas VARCHAR(20) NOT NULL,\n  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n) ENGINE=InnoDB;\n\nINSERT INTO siswa (nis, nama, kelas) VALUES\n('1001', 'Andi Saputra', 'XI-RPL 1'),\n('1002', 'Siti Aminah', 'XI-RPL 1');\n\nSELECT id, nis, nama, kelas FROM siswa ORDER BY nama;"),
    h("CRUD Dasar dengan SQL", 3),
    code("-- Create: menambah data\nINSERT INTO siswa (nis, nama, kelas)\nVALUES ('1003', 'Rina Putri', 'XI-RPL 1');\n\n-- Read: membaca data\nSELECT * FROM siswa WHERE kelas = 'XI-RPL 1';\n\n-- Update: mengubah data tertentu\nUPDATE siswa SET nama = 'Rina Puspita' WHERE nis = '1003';\n\n-- Delete: menghapus data tertentu\nDELETE FROM siswa WHERE nis = '1003';"),
    { type: "blockquote", content: [p(t("Sebelum UPDATE atau DELETE, jalankan SELECT dengan kondisi WHERE yang sama. Hindari UPDATE atau DELETE tanpa WHERE karena dapat mengubah atau menghapus semua baris."))] },
    h("8. Export: Membuat Backup"),
    image("/uploads/materials/phpmyadmin-guide/database-export.png", "Screenshot halaman Export database dengan metode Quick dan format SQL"),
    list([
      "Pilih database yang akan dicadangkan pada panel kiri.",
      "Klik Export. Untuk pemula, pilih metode Quick dan format SQL.",
      "Klik Export/Go lalu simpan file .sql di lokasi backup yang aman.",
      "Untuk kebutuhan khusus, gunakan Custom untuk memilih tabel, kompresi, dan opsi struktur/data.",
    ], true),
    h("9. Import: Memulihkan Database"),
    image("/uploads/materials/phpmyadmin-guide/database-import.png", "Screenshot halaman Import database dan tombol Choose File"),
    list([
      "Buat atau pilih database tujuan terlebih dahulu.",
      "Klik Import, lalu Choose File dan pilih backup .sql atau format yang didukung.",
      "Periksa charset dan opsi import, kemudian klik Import/Go.",
      "Baca pesan hasil eksekusi dan periksa kembali tabel beserta datanya.",
    ], true),
    p(t("Untuk mengimpor ke database tertentu, pilih database tersebut sebelum membuka tab Import. File besar mungkin dibatasi oleh upload_max_filesize, post_max_size, memory_limit, atau waktu eksekusi PHP.")),
    h("10. User Accounts dan Hak Akses"),
    p(t("Jangan memakai root untuk aplikasi sehari-hari. Buat pengguna khusus dan berikan hak hanya pada database yang diperlukan. Prinsip ini disebut least privilege.")),
    code("CREATE USER 'siswa_app'@'localhost' IDENTIFIED BY 'Ganti-Dengan-Password-Kuat!';\nGRANT SELECT, INSERT, UPDATE, DELETE\nON latihan_phpmyadmin.* TO 'siswa_app'@'localhost';\nFLUSH PRIVILEGES;"),
    h("11. Keamanan dan Praktik Baik"),
    list([
      "Gunakan phpMyAdmin hanya pada localhost atau jaringan yang benar-benar dipercaya.",
      "Jangan mengekspos phpMyAdmin publik dengan akun root tanpa password.",
      "Gunakan authentication type cookie atau HTTP pada lingkungan multi-pengguna.",
      "Selalu backup sebelum Drop, Empty, perubahan struktur besar, atau import.",
      "Gunakan akun khusus dengan privilege minimum, bukan root.",
      "Perbarui phpMyAdmin ketika ada rilis keamanan dan gunakan HTTPS pada server publik.",
      "Jangan menyimpan password database secara terbuka di repository.",
    ]),
    h("12. Masalah Umum dan Solusi"),
    list([
      "localhost/phpmyadmin tidak terbuka: pastikan Apache dan MySQL berwarna hijau.",
      "Access denied: periksa username, password, host, serta hak akses akun database.",
      "404 Not Found: periksa konfigurasi alias phpMyAdmin dan lokasi folder instalasi XAMPP.",
      "MySQL gagal aktif: cek konflik port 3306 dan baca log MySQL dari Control Panel.",
      "Import terlalu besar: naikkan batas upload PHP secara wajar atau gunakan command line untuk dump besar.",
      "Karakter rusak: gunakan utf8mb4 secara konsisten pada database, tabel, koneksi, dan file.",
      "Configuration storage belum lengkap: fungsi dasar tetap berjalan; konfigurasikan fitur tambahan sesuai dokumentasi dan setelah backup.",
    ]),
    h("13. Latihan Mandiri"),
    list([
      "Jalankan Apache dan MySQL lalu buka phpMyAdmin.",
      "Buat database perpustakaan_rpl dengan charset utf8mb4.",
      "Buat tabel buku berisi id, kode_buku, judul, penulis, tahun_terbit, dan stok.",
      "Masukkan minimal lima buku melalui menu Insert.",
      "Gunakan SQL untuk mencari buku, memperbarui stok, dan menghapus satu data berdasarkan kode_buku.",
      "Export database menjadi file SQL, hapus database latihan, lalu pulihkan menggunakan Import.",
      "Catat setiap langkah dan screenshot hasil akhirnya.",
    ], true),
    h("Rangkuman"),
    p(t("phpMyAdmin memudahkan administrasi MySQL/MariaDB melalui browser, tetapi tetap bekerja dengan konsep database yang sama. Pengguna harus memahami database, tabel, kolom, tipe data, key, SQL, privilege, serta backup. Kemudahan tombol visual tidak menghilangkan risiko: selalu pastikan objek yang dipilih benar dan buat backup sebelum operasi destruktif.")),
    h("Referensi Resmi"),
    p(link("Dokumentasi pengantar phpMyAdmin", "https://docs.phpmyadmin.net/en/latest/intro.html"), t(" — fungsi dan kemampuan utama phpMyAdmin.")),
    p(link("Dokumentasi instalasi dan keamanan phpMyAdmin", "https://docs.phpmyadmin.net/en/latest/setup.html"), t(" — konfigurasi, autentikasi, dan rekomendasi keamanan.")),
    p(link("Dokumentasi import dan export phpMyAdmin", "https://docs.phpmyadmin.net/en/latest/import_export.html"), t(" — panduan backup serta pemulihan data.")),
  ],
} as unknown as Prisma.InputJsonObject;

async function main() {
  const [targetClass, subject, category, teacher] = await Promise.all([
    prisma.class.findFirst({ where: { name: "XI-RPL 1" }, orderBy: { createdAt: "desc" } }),
    prisma.subject.findFirst({ where: { OR: [{ code: "DB-XI" }, { name: "Basis Data" }] } }),
    prisma.category.findFirst({ where: { slug: "basis-data" } }),
    prisma.user.findFirst({ where: { role: "TEACHER", status: "ACTIVE" } }),
  ]);
  if (!targetClass || !subject || !category || !teacher) throw new Error("Data master kelas, mata pelajaran, kategori, atau guru belum tersedia.");

  const slug = "panduan-lengkap-phpmyadmin";
  const material = await prisma.material.upsert({
    where: { slug },
    create: {
      title: "Panduan Lengkap phpMyAdmin: Mengelola Database MySQL/MariaDB",
      slug,
      description: "Materi lengkap menjalankan dan menggunakan phpMyAdmin, mengenali tampilannya, membuat database dan tabel, CRUD, SQL, user privilege, import, export, keamanan, dan troubleshooting.",
      thumbnail: "/uploads/materials/phpmyadmin-guide/phpmyadmin-home.png",
      semester: 1,
      content,
      status: ContentStatus.PUBLISHED,
      visibility: Visibility.STUDENT_ONLY,
      publishedAt: new Date(),
      authorId: teacher.id,
      classId: targetClass.id,
      subjectId: subject.id,
      categoryId: category.id,
    },
    update: {
      title: "Panduan Lengkap phpMyAdmin: Mengelola Database MySQL/MariaDB",
      description: "Materi lengkap menjalankan dan menggunakan phpMyAdmin, mengenali tampilannya, membuat database dan tabel, CRUD, SQL, user privilege, import, export, keamanan, dan troubleshooting.",
      thumbnail: "/uploads/materials/phpmyadmin-guide/phpmyadmin-home.png",
      semester: 1,
      content,
      status: ContentStatus.PUBLISHED,
      visibility: Visibility.STUDENT_ONLY,
      publishedAt: new Date(),
      authorId: teacher.id,
      classId: targetClass.id,
      subjectId: subject.id,
      categoryId: category.id,
    },
  });

  const href = `/materi/${slug}`;
  await prisma.notification.deleteMany({ where: { type: "MATERIAL", href } });
  const students = await prisma.student.findMany({ where: { classId: targetClass.id, status: "ACTIVE", userId: { not: null } }, select: { userId: true } });
  const notifications = students.flatMap(({ userId }) => userId ? [{ userId, title: "Materi baru tersedia", message: material.title, type: "MATERIAL", href }] : []);
  if (notifications.length) await prisma.notification.createMany({ data: notifications });

  console.log(`Materi terbit: ${material.title}`);
  console.log(`URL: ${href}`);
  console.log(`Notifikasi siswa: ${notifications.length}`);
}

main().catch((error) => { console.error(error); process.exitCode = 1; }).finally(async () => prisma.$disconnect());
