import { type FormEvent, useEffect, useState } from 'react';
import { Head, useForm, usePage } from '@inertiajs/react';
import TataLetakPublik from '@/tata-letak/TataLetakPublik';
import { Ikon } from '@/komponen/Ikon';
import { PilihTanggal } from '@/komponen/PilihTanggal';
import { muatSwal } from '@/lib/dialog';
import { hariIniIso } from '@/lib/format';
import type { PendaftarPublik, RingkasanBerkas, RupaStatus } from '@/tipe/model';
import type { PropsBersama } from '@/tipe/inertia';

interface Props {
    pendaftar: PendaftarPublik | null;
    berkas: Record<string, RingkasanBerkas>;
    rupa: RupaStatus | null;
    maks_berkas_mb: number;
    /** Penanda sekali tampil: modal hasil hanya muncul sesudah pencarian. */
    tampilkan_hasil: boolean;
    judul: string;
    deskripsi: string;
}

const TAHAPAN_CEK: { nama: string; ringkas: string; judul: string }[] = [
    { nama: 'Cek status pendaftaran', ringkas: 'Cari', judul: 'Periksa status pendaftaranmu.' },
];

const LAHIR_MIN = '1950-01-01';
const LAHIR_MAKS = hariIniIso();

function esc(teks: string): string {
    return teks
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;');
}

function bangunHtmlHasil(
    pendaftar: PendaftarPublik,
    rupa: RupaStatus,
    berkas: Record<string, RingkasanBerkas>,
): string {
    const baris = (dt: string, dd: string) => `<div><dt>${esc(dt)}</dt><dd>${dd}</dd></div>`;

    const dibawaKeSekolah = pendaftar.cara_berkas === 'sekolah';

    let berkasHtml = '';
    for (const r of Object.values(berkas)) {
        const ikon = r.ada ? '✓' : (dibawaKeSekolah ? '•' : '✗');
        const kelas = r.ada ? 'tanda--ada' : (dibawaKeSekolah ? 'tanda--ada' : 'tanda--kosong');
        const ket = r.ada ? 'Sudah diunggah' : (dibawaKeSekolah ? 'Dibawa ke sekolah' : 'Belum diunggah');
        berkasHtml += `<li><span class="tanda ${kelas}" aria-hidden="true">${ikon}</span><span>${esc(r.label)}</span><span class="keterangan">${ket}</span></li>`;
    }

    let catatanHtml = '';
    if (pendaftar.catatan) {
        catatanHtml = `
            <hr class="pisah">
            <div class="spanduk spanduk--peringatan" role="status">
                <div>
                    <p class="spanduk__judul">Catatan panitia</p>
                    <p class="tanpa-jarak-bawah">${esc(pendaftar.catatan)}</p>
                </div>
            </div>`;
    }

    const berkasTeks = dibawaKeSekolah
        ? 'Berkas dibawa ke sekolah'
        : (pendaftar.berkas_lengkap ? 'Berkas lengkap' : 'Berkas belum lengkap');
    const pesanTampil = rupa.pesan
        ? `<p class="keterangan">${esc(rupa.pesan)}</p>`
        : '';

    // Draf: nomor sudah terbit, tetapi pendaftar belum menekan tombol
    // penyelesaian. Jangan tampilkan seolah pendaftarannya sudah sah.
    const drafHtml = pendaftar.belum_selesai
        ? `<div class="spanduk spanduk--peringatan" role="status">
                <div>
                    <p class="spanduk__judul">Pendaftaran belum diselesaikan</p>
                    <p class="tanpa-jarak-bawah">Nomor di atas baru terbit sebagai draf. Buka <a href="/daftar">formulir pendaftaran</a> untuk melanjutkan sampai langkah terakhir.</p>
                </div>
            </div>`
        : '';

    return `
        <div style="text-align:left">
            <div class="tiket">
                <small>Nomor pendaftaran</small>
                <b>${esc(pendaftar.nomor)}</b>
                <span>${esc(pendaftar.status)}</span>
            </div>
            ${drafHtml}
            <p><span class="lencana lencana--besar lencana--abu">${berkasTeks}</span></p>
            ${pesanTampil}
            <hr class="pisah">
            <dl class="rincian">
                ${baris('Pilihan jurusan', esc(pendaftar.nama_jurusan1))}
                ${baris('Sekolah asal', esc(pendaftar.sekolah_asal))}
                ${baris('NIK', `<span class="nik-samar">${esc(pendaftar.nik_samar)}</span>`)}
                ${baris('Waktu pendaftaran', esc(`${pendaftar.waktu_daftar} WIB`))}
            </dl>
            <hr class="pisah">
            <h3>Berkas persyaratan</h3>
            <ul class="daftar-berkas">${berkasHtml}</ul>
            ${catatanHtml}
        </div>`;
}

export default function CekStatus({
    pendaftar,
    berkas,
    rupa,
    maks_berkas_mb,
    tampilkan_hasil,
    judul,
}: Props) {
    const { errors } = usePage().props as unknown as PropsBersama;

    useEffect(() => {
        if (!tampilkan_hasil || !pendaftar || !rupa) {
            return;
        }

        void tampilkanHasil(pendaftar, rupa, berkas, maks_berkas_mb);
    }, [tampilkan_hasil, pendaftar, rupa, berkas, maks_berkas_mb]);

    return (
        <TataLetakPublik
            fokus
            tahapan={TAHAPAN_CEK}
            wadah="wadah--formulir"
            eyebrow="Cek status"
            lead="Masukkan nomor pendaftaran, NISN, atau NIK beserta tanggal lahir calon murid."
        >
            <Head title={judul} />

            <div className="tata">
                <div className="kartu kartu-form">
                    <FormulirCari errors={errors} />
                </div>

                <aside className="sisi">
                    <div className="kartu kartu-sisi langkah">
                        <h3>Cek status</h3>
                        <p>Periksa status pendaftaran murid baru dengan nomor pendaftaran, NISN, atau NIK.</p>
                        <ol className="daftar-langkah">
                            <li className="aktif" aria-current="step"><i>1</i>Masukkan data</li>
                            <li className="aktif"><i>2</i>Lihat hasil</li>
                        </ol>
                    </div>
                    <p className="aman"><Ikon nama="lock" ukuran={14} /> Data dilindungi sesuai UU 27/2022</p>
                </aside>
            </div>
        </TataLetakPublik>
    );
}

async function tampilkanHasil(
    pendaftar: PendaftarPublik,
    rupa: RupaStatus,
    berkas: Record<string, RingkasanBerkas>,
    _maksBerkasMb: number,
) {
    const Swal = await muatSwal();
    const html = bangunHtmlHasil(pendaftar, rupa, berkas);

    if (!Swal) {
        window.alert(`${pendaftar.nama}\nNomor: ${pendaftar.nomor}\nStatus: ${pendaftar.status}`);
        return;
    }

    void Swal.fire({
        title: pendaftar.nama,
        html,
        width: '24em',
        confirmButtonText: 'Tutup',
        confirmButtonColor: '#0b6b3a',
        heightAuto: false,
        customClass: { popup: 'modal-hasil-cek' },
    });
}

/* ---------- Formulir pencarian ---------- */

function FormulirCari({ errors }: { errors: Record<string, string> }) {
    const form = useForm({ kunci: 'nomor', nilai: '', tanggal_lahir: '' });
    const [kirimSedang, setKirimSedang] = useState(false);

    // Tautan dari QR bukti pendaftaran membawa ?nomor=, jadi kolom kunci
    // sudah terisi dan pemegang bukti cukup memilih tanggal lahir.
    useEffect(() => {
        const nomor = new URLSearchParams(window.location.search).get('nomor');
        if (nomor) {
            form.setData('kunci', 'nomor');
            form.setData('nilai', nomor);
        }
        // Hanya saat pertama dimuat; setelah itu isi form milik pengguna.
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    function saatKirim(e: FormEvent) {
        e.preventDefault();
        setKirimSedang(true);
        form.post('/cek-status', {
            preserveScroll: true,
            onFinish: () => setKirimSedang(false),
        });
    }

    return (
        <fieldset className="tahap">
            <legend className="sr">Cek status pendaftaran</legend>
            <div className="kepala-tahap">
                <span className="no-tahap"><Ikon nama="id" ukuran={22} /></span>
                <div>
                    <h2>Cek status pendaftaran</h2>
                    <small>Masukkan salah satu kunci beserta tanggal lahir calon murid</small>
                </div>
            </div>

            {errors.nilai && (
                <div className="spanduk spanduk--galat" role="alert">
                    <p className="tanpa-jarak-bawah">{errors.nilai}</p>
                </div>
            )}

            <form onSubmit={saatKirim} autoComplete="off">
                <div className="bidang tanpa-ikon">
                    <label className="label" htmlFor="kunci">Cari dengan <span className="wajib">*</span></label>
                    <select
                        id="kunci"
                        name="kunci"
                        value={form.data.kunci}
                        onChange={(e) => form.setData('kunci', e.target.value)}
                        required
                    >
                        <option value="nomor">Nomor pendaftaran</option>
                        <option value="nisn">NISN</option>
                        <option value="nik">NIK</option>
                    </select>
                </div>

                <div className="bidang">
                    <label className="label" htmlFor="nilai">Nomor pendaftaran / NISN / NIK <span className="wajib">*</span></label>
                    <div className="masukan">
                        <svg width="18" height="18"><use href="#i-id" /></svg>
                        <input
                            id="nilai"
                            name="nilai"
                            type="text"
                            maxLength={20}
                            autoComplete="off"
                            value={form.data.nilai}
                            onChange={(e) => form.setData('nilai', e.target.value)}
                            placeholder="Contoh: 001"
                            required
                        />
                    </div>
                    <div className="bantuan"><span>Masukkan nomor pendaftaran, NISN, atau NIK.</span></div>
                </div>

                <div className="bidang">
                    <label className="label" htmlFor="tanggal-lahir">Tanggal lahir calon murid <span className="wajib">*</span></label>
                    <PilihTanggal
                        nilai={form.data.tanggal_lahir}
                        onChange={(iso) => form.setData('tanggal_lahir', iso)}
                        min={LAHIR_MIN}
                        maks={LAHIR_MAKS}
                    />
                </div>

                {/* Tanpa kelas `dalam`: halaman ini tidak punya bilah aksi
                    melekat di ponsel, jadi tombolnya harus tetap tampil. */}
                <div className="aksi-baris">
                    <button
                        className="tombol utama"
                        type="submit"
                        disabled={kirimSedang}
                    >
                        <span>{kirimSedang ? 'Mencari…' : 'Cek pendaftar'}</span> <Ikon nama="arrow" />
                    </button>
                </div>
            </form>
        </fieldset>
    );
}
