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

const prisma = new PrismaClient();

type RichNode = {
  type: string;
  attrs?: Record<string, unknown>;
  content?: RichNode[];
  text?: string;
  marks?: { type: string; attrs?: Record<string, unknown> }[];
};

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

const content: RichNode = {
  type: "doc",
  content: [
    paragraph(text("XAMPP for Browsers adalah lingkungan LAMP yang dapat dijalankan langsung pada browser desktop. Berbeda dengan XAMPP for Windows, pilihan ini tidak meminta kita memasang server ke Windows. Artikel ini memandu proses mulai dari pencarian, memilih versi, menjalankan LAMP Sandbox, memakai phpMyAdmin, dan menggunakan terminal.")),
    heading("Apa perbedaan XAMPP for Browsers dan XAMPP for Windows?"),
    {
      type: "table",
      content: [
        { type: "tableRow", content: ["Pilihan", "Cara bekerja", "Cocok digunakan untuk"].map((value) => ({ type: "tableHeader", content: [paragraph(text(value))] })) },
        ...[
          ["XAMPP for Browsers", "LAMP berjalan sebagai emulator di browser. Tidak ada installer dan tersedia terminal serta phpMyAdmin di halaman yang sama.", "Praktik cepat, demonstrasi kelas, atau komputer yang tidak boleh dipasangi aplikasi."],
          ["XAMPP for Windows", "Apache, MariaDB, PHP, dan alat lain dipasang secara lokal lalu dikendalikan melalui XAMPP Control Panel.", "Proyek yang disimpan lebih lama, akses folder htdocs, dan pengembangan lokal sehari-hari."],
        ].map((row) => ({ type: "tableRow", content: row.map((value) => ({ type: "tableCell", content: [paragraph(text(value))] })) })),
      ],
    },
    { type: "blockquote", content: [paragraph(text("Untuk latihan singkat tanpa instalasi, pilih XAMPP for Browsers. Untuk mengerjakan proyek WEBKU yang tersimpan di C:\\xampp\\htdocs, tetap gunakan XAMPP for Windows."))] },
    heading("1. Mencari halaman resmi XAMPP melalui Google"),
    list([
      "Buka Google menggunakan browser Chrome atau browser berbasis Chromium lainnya.",
      "Ketik download XAMPP, lalu tekan Enter.",
      "Pilih hasil dari domain resmi apachefriends.org. Periksa alamat situs sebelum mengeklik agar tidak mengambil installer dari situs tidak resmi.",
      "Pada halaman Apache Friends, buka menu Download.",
    ], true),
    paragraph(text("Alamat resmi yang dapat diketik langsung adalah "), link("https://www.apachefriends.org/download.html", "https://www.apachefriends.org/download.html"), text(".")),
    heading("2. Menemukan pilihan XAMPP for Browsers"),
    image("/uploads/articles/panduan-xampp/02-situs-resmi-download-xampp.png", "Halaman resmi Apache Friends yang menampilkan XAMPP for Windows dan XAMPP for Browsers"),
    paragraph(text("Pada screenshot terlihat XAMPP for Windows di bagian atas dan XAMPP for Browsers tepat di bawahnya. XAMPP for Browsers menyediakan tombol Run in the browser, bukan tombol Download. Saat artikel ini dibuat, versi yang ditampilkan adalah 8.3.12 dengan PHP 8.3.12.")),
    list([
      "Klik Run in the browser jika ingin langsung berlatih secara daring tanpa memasang XAMPP.",
      "Klik Download (64 bit) pada bagian XAMPP for Windows jika ingin server dan proyek tersimpan di komputer.",
      "Versi browser diuji oleh penyedia pada Chrome desktop dan browser turunannya.",
      "Versi browser tetap memerlukan internet, sedangkan instalasi Windows dapat dipakai secara lokal setelah selesai diunduh dan dipasang.",
    ]),
    heading("3. Menjalankan LAMP Sandbox"),
    paragraph(text("Setelah tombol Run in the browser diklik, Apache Friends mengarahkan pengguna ke LAMP Sandbox milik Endor. Tunggu proses Starting Network dan Initializing Service hingga selesai. Jangan menutup tab selama proses inisialisasi.")),
    image("/uploads/articles/panduan-xampp/03-xampp-browser-lamp-sandbox.png", "Tampilan awal XAMPP for Browsers pada LAMP Sandbox"),
    paragraph(text("Panel kiri memuat layanan LAMP dan PHPMyAdmin. Panel kanan adalah browser internal yang menampilkan aplikasi web. Ikon terminal berada di bilah paling kiri. Tombol Sign In bersifat pilihan; masuk dengan akun yang didukung dapat berguna apabila platform menawarkan penyimpanan atau integrasi proyek.")),
    heading("4. Memahami komponen di dalam versi browser"),
    list([
      "Alpine Linux: sistem operasi Linux ringan yang menjadi lingkungan dasar emulator.",
      "Apache: web server yang menerima permintaan halaman web.",
      "MariaDB: server database relasional yang kompatibel dengan penggunaan MySQL pada pembelajaran dasar.",
      "PHP: bahasa pemrograman sisi server untuk menjalankan aplikasi PHP.",
      "phpMyAdmin: antarmuka visual untuk mengelola database melalui browser.",
      "Terminal: command line untuk menjalankan perintah Linux, PHP, dan MariaDB.",
    ]),
    heading("5. Menjalankan halaman PHP"),
    paragraph(text("Gunakan pengelola berkas di bilah kiri untuk membuat atau memasukkan proyek. Buat file index.php dengan contoh berikut, kemudian pilih layanan LAMP pada alamat browser internal.")),
    code("<?php\n$nama = 'Siswa RPL';\necho '<h1>Halo, ' . htmlspecialchars($nama) . '!</h1>';\necho '<p>PHP pada XAMPP for Browsers berhasil berjalan.</p>';", "php"),
    paragraph(text("Jika halaman tidak muncul, pastikan status LAMP sudah selesai melakukan inisialisasi. Muat ulang browser internal setelah menyimpan perubahan.")),
    heading("6. Membuka dan menggunakan phpMyAdmin"),
    paragraph(text("Klik quick link PHPMyAdmin pada panel kiri. Cara lainnya adalah mengetik /phpmyadmin/ pada alamat browser internal. phpMyAdmin sudah dipasang secara bawaan di lingkungan ini.")),
    image("/uploads/articles/panduan-xampp/04-phpmyadmin-home.png", "Tampilan utama phpMyAdmin untuk mengelola MariaDB"),
    list([
      "Klik Databases untuk membuat database baru.",
      "Pilih nama database pada panel kiri untuk melihat tabelnya.",
      "Klik Structure untuk membuat atau mengubah kolom tabel.",
      "Klik Browse untuk melihat isi tabel.",
      "Klik SQL untuk mengetik dan menjalankan perintah SQL.",
      "Gunakan Export untuk mengunduh cadangan database sebelum mengakhiri praktik.",
    ]),
    image("/uploads/articles/panduan-xampp/05-phpmyadmin-databases.png", "Menu Databases pada phpMyAdmin"),
    heading("Contoh latihan database", 3),
    paragraph(text("Buka tab SQL, tempelkan perintah berikut, lalu jalankan.")),
    code("CREATE DATABASE latihan_browser\n  CHARACTER SET utf8mb4\n  COLLATE utf8mb4_unicode_ci;\n\nUSE latihan_browser;\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);\n\nINSERT INTO siswa (nis, nama, kelas)\nVALUES ('1001', 'Mizan Adinata', 'XI-RPL 1');\n\nSELECT * FROM siswa;", "sql"),
    image("/uploads/articles/panduan-xampp/06-phpmyadmin-sql.png", "Tab SQL pada phpMyAdmin"),
    heading("7. Menggunakan Console atau Terminal"),
    paragraph(text("Klik ikon terminal bergambar >_ pada bilah kiri. Terminal versi browser memakai perintah Linux karena lingkungan dasarnya adalah Alpine Linux; jadi perintahnya tidak selalu sama dengan Command Prompt Windows.")),
    code("php --version\nmysql --version\nls -la\npwd", "bash"),
    paragraph(text("Untuk masuk ke MariaDB dari terminal, jalankan perintah berikut. Setelah prompt MariaDB tampil, kita dapat mengetik SQL dan mengakhirinya dengan tanda titik koma.")),
    code("mysql -u root\n\nSHOW DATABASES;\nUSE latihan_browser;\nSHOW TABLES;\nSELECT * FROM siswa;\nEXIT;", "sql"),
    list([
      "php --version memeriksa versi PHP.",
      "mysql --version memeriksa klien MariaDB/MySQL.",
      "pwd menampilkan folder aktif.",
      "ls -la menampilkan file dan folder.",
      "mysql -u root membuka console database pada konfigurasi latihan bawaan.",
      "Gunakan tombol panah atas untuk memanggil kembali perintah sebelumnya.",
    ]),
    heading("8. Menyimpan pekerjaan sebelum tab ditutup"),
    paragraph(text("Lingkungan browser dapat bersifat sementara. Karena itu, jangan mengandalkan tab browser sebagai satu-satunya tempat penyimpanan.")),
    list([
      "Ekspor database melalui phpMyAdmin dalam format SQL.",
      "Unduh atau salin file proyek ke komputer.",
      "Jika tersedia, gunakan fitur mount local folder agar proyek berada pada folder komputer.",
      "Simpan ulang berkas hasil praktik ke penyimpanan sekolah atau repositori yang diizinkan guru.",
    ]),
    heading("9. Jika memilih XAMPP for Windows"),
    paragraph(text("Untuk proyek WEBKU atau latihan jangka panjang, unduh XAMPP for Windows, pasang di C:\\xampp, lalu buka XAMPP Control Panel. Klik Start pada Apache dan MySQL/MariaDB.")),
    image("/uploads/articles/panduan-xampp/07-xampp-control-panel.png", "XAMPP Control Panel dengan Apache dan MySQL aktif"),
    paragraph(text("Jika kedua baris berwarna hijau, buka http://localhost untuk dashboard dan http://localhost/phpmyadmin untuk phpMyAdmin. File proyek disimpan pada C:\\xampp\\htdocs\\nama-proyek.")),
    image("/uploads/articles/panduan-xampp/08-xampp-dashboard-local.png", "Dashboard XAMPP lokal yang dibuka melalui localhost"),
    heading("10. Masalah yang sering muncul"),
    list([
      "XAMPP for Browsers berhenti di Initializing: periksa koneksi internet, gunakan Chrome desktop terbaru, nonaktifkan pemblokir yang menghalangi situs untuk pengujian, lalu muat ulang.",
      "PHPMyAdmin belum dapat diklik: tunggu hingga layanan LAMP dan PHPMyAdmin selesai dimulai.",
      "Data hilang setelah tab ditutup: pulihkan dari file SQL hasil Export dan unggah kembali file proyek.",
      "XAMPP Windows tidak dapat menjalankan Apache: periksa konflik port 80 atau 443 melalui Netstat dan log Apache.",
      "MySQL/MariaDB Windows tidak berjalan: periksa port 3306 dan jangan mematikan komputer ketika database sedang menulis data.",
    ]),
    heading("Rangkuman"),
    paragraph(text("Pilihan XAMPP for Browsers benar-benar tersedia pada halaman resmi Apache Friends. Pilihan tersebut membuka LAMP Sandbox di Endor sehingga Apache, MariaDB, PHP, phpMyAdmin, file proyek, dan terminal dapat digunakan dari satu tab Chrome. Gunakan versi browser untuk latihan cepat, tetapi gunakan XAMPP for Windows untuk proyek lokal yang harus tersimpan dan dipakai berulang kali.")),
    heading("Referensi resmi"),
    paragraph(link("Apache Friends — Download XAMPP", "https://www.apachefriends.org/download.html"), text(" dan "), link("Endor — LAMP Sandbox", "https://endor.dev/s/lamp"), text(".")),
  ],
};

async function main() {
  const teacher = await prisma.user.findFirst({ where: { role: "TEACHER", status: "ACTIVE" } });
  if (!teacher) throw new Error("Akun guru aktif belum tersedia.");

  const category = await prisma.category.upsert({
    where: { slug: "artikel" },
    create: { name: "Artikel", slug: "artikel", description: "Informasi, panduan, dan tutorial teknologi." },
    update: { name: "Artikel", description: "Informasi, panduan, dan tutorial teknologi." },
  });
  const subject = await prisma.subject.findFirst({ where: { OR: [{ code: "DB-XI" }, { name: "Basis Data" }] } });
  const slug = "xampp-for-browsers-phpmyadmin-console";
  const article = await prisma.article.upsert({
    where: { slug },
    create: {
      title: "XAMPP for Browsers: Menjalankan PHP, phpMyAdmin, dan Console Tanpa Instalasi",
      slug,
      cover: "/uploads/articles/panduan-xampp/02-situs-resmi-download-xampp.png",
      excerpt: "Panduan bergambar mencari XAMPP dari Google, memilih XAMPP for Browsers, menjalankan LAMP Sandbox, memakai phpMyAdmin, dan menggunakan terminal.",
      content: content as unknown as Prisma.InputJsonObject,
      status: ContentStatus.PUBLISHED,
      publishedAt: new Date(),
      authorId: teacher.id,
      categoryId: category.id,
      subjectId: subject?.id,
    },
    update: {
      title: "XAMPP for Browsers: Menjalankan PHP, phpMyAdmin, dan Console Tanpa Instalasi",
      cover: "/uploads/articles/panduan-xampp/02-situs-resmi-download-xampp.png",
      excerpt: "Panduan bergambar mencari XAMPP dari Google, memilih XAMPP for Browsers, menjalankan LAMP Sandbox, memakai phpMyAdmin, dan menggunakan terminal.",
      content: content as unknown as Prisma.InputJsonObject,
      status: ContentStatus.PUBLISHED,
      publishedAt: new Date(),
      authorId: teacher.id,
      categoryId: category.id,
      subjectId: subject?.id,
    },
  });

  console.log(`Artikel terbit: ${article.title}`);
  console.log(`/artikel/${article.slug}`);
}

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