/**
 * main.js — ACAAB Prestasi & Karya Mahasiswa
 * Vanilla JS: fetch data Directus CMS, render sections, handle interactions.
 */

// ─── Constants ────────────────────────────────────────────────────────────────

const API_BASE = 'https://api.ifuntanhub.dev';
const LANG_KEY = 'if_untan_lang';

const BIDANG_MAP = {
    1: 'Kecerdasan Buatan', 2: 'Cyber Security', 3: 'Data',
    4: 'Software Engineering', 5: 'Competitive Programming', 6: 'IoT',
    7: 'Smart City', 8: 'Web3', 9: 'Karya Tulis Ilmiah', 10: 'Robotik',
};

// ─── Utilities ────────────────────────────────────────────────────────────────

function escHtml(str) {
    if (str === null || str === undefined) return '';
    return String(str)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');
}

function getLang() {
    try {
        return localStorage.getItem(LANG_KEY) ||
            (navigator.language && navigator.language.startsWith('en') ? 'en' : 'id');
    } catch (_) { return 'id'; }
}

// Baca dari translations global yang didefinisikan localization.js
function t(key) {
    try {
        const lang = getLang();
        if (typeof translations !== 'undefined' && translations[lang] && translations[lang][key]) {
            return translations[lang][key];
        }
    } catch (_) {}
    return key;
}

// ─── Data Transformation ──────────────────────────────────────────────────────

function extractRank(title) {
    const m = (title || '').match(/(Juara\s+\d+|Juara\s+Harapan\s*\d*|Top\s+\d+|Finalis|Peringkat\s+\d+|Medali\s+\w+)/i);
    return m ? m[0] : 'Pemenang';
}

function extractLevel(title, category) {
    const text = ((title || '') + ' ' + (category || '')).toLowerCase();
    if (/internasional|international|global|world|asean|unesco/.test(text)) return 'Internasional';
    if (/regional|kalbar|kalimantan|provinsi|kota|kabupaten|lokal/.test(text)) return 'Regional';
    return 'Nasional';
}

function extractCompetition(title) {
    return (title || '')
        .replace(/^(Juara\s+\d+|Juara\s+Harapan\s*\d*|Top\s+\d+|Finalis|Peringkat\s+\d+|Medali\s+\w+)\s+(di\s+|pada\s+|dalam\s+)?/i, '')
        .trim();
}

function getImageUrl(item, seed) {
    if (item.galeri && Array.isArray(item.galeri) && item.galeri.length > 0) {
        const first = item.galeri[0];
        const imgId = typeof first === 'string' ? first : (first.directus_files_id || first.id);
        if (imgId) return `${API_BASE}/assets/${imgId}`;
    }
    if (item.foto) return `${API_BASE}/assets/${item.foto}`;
    return `https://picsum.photos/seed/${seed}/800/600`;
}

function transformAchievement(item) {
    const id = String(item.id);
    const title = item.nama_prestasi || 'Untitled Achievement';

    let category = 'Umum';
    if (item.bidang_id) {
        category = (typeof item.bidang_id === 'object' && item.bidang_id.nama_bidang)
            ? item.bidang_id.nama_bidang
            : (BIDANG_MAP[item.bidang_id] || 'Umum');
    }

    const rank        = extractRank(title);
    const level       = extractLevel(title, category);
    const competition = extractCompetition(title);
    const year        = parseInt(item.tahun) || new Date().getFullYear();
    const anggota     = Array.isArray(item.anggota) ? item.anggota : [];
    const team        = item.nama_tim || (anggota.length > 0 ? anggota[0].nama : 'Mahasiswa');
    const avatar      = (item.nama_tim || title || 'IF').substring(0, 2).toUpperCase();
    const description = item.deskripsi ||
        `${team} berhasil meraih prestasi luar biasa sebagai ${rank} dalam ajang ${competition} tahun ${year} pada bidang ${category.toLowerCase()}.`;

    return {
        id, title, category, competition, rank, year, level, description,
        team,
        nim:        item.nim || '',
        generation: item.angkatan ? `Angkatan ${item.angkatan}` : 'Informatika',
        image:      getImageUrl(item, `prestasi-${id}`),
        avatar,
        members:    anggota.map(m => ({ nama: m.nama || '', angkatan: m.angkatan ? parseInt(m.angkatan) : undefined })),
    };
}

function transformProject(item) {
    const id          = String(item.id);
    const title       = item.nama_proyek || 'Untitled Project';
    const anggota     = Array.isArray(item.anggota) ? item.anggota : [];
    const studentName = item.nama_mahasiswa || (anggota.length > 0 ? anggota[0].nama : 'Mahasiswa');
    const year        = parseInt(item.tahun) || new Date().getFullYear();
    const description = item.deskripsi || 'Tidak ada deskripsi.';

    let categories = [];
    if (item.bidang && Array.isArray(item.bidang)) {
        categories = item.bidang.map(b => {
            if (b.bidang_id && typeof b.bidang_id === 'object' && b.bidang_id.nama_bidang) return b.bidang_id.nama_bidang;
            if (typeof b.bidang_id === 'number') return BIDANG_MAP[b.bidang_id] || 'Umum';
            return 'Umum';
        }).filter(Boolean);
    }
    if (categories.length === 0) categories = ['Umum'];

    let link = item.url || null;
    if (link && !/^https?:\/\//i.test(link)) link = `https://${link}`;

    return {
        id, title, studentName, year, description, categories, link,
        nim:     item.nim || '',
        image:   getImageUrl(item, `project-${id}`),
        catatan: item.catatan || '',
        members: anggota.map(m => ({ nama: m.nama || '', nim: m.nim || '' })),
    };
}

// ─── API Fetch ────────────────────────────────────────────────────────────────

async function fetchAchievements() {
    const res = await fetch(`${API_BASE}/items/prestasi?fields=*.*`);
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const { data } = await res.json();
    return (data || [])
        .filter(item => item.status === 'published')
        .map(transformAchievement);
}

async function fetchProjects() {
    const res = await fetch(`${API_BASE}/items/portfolio?fields=*,bidang.bidang_id.nama_bidang,galeri.*`);
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const { data } = await res.json();
    return (data || [])
        .filter(item => item.status === 'published')
        .map(transformProject);
}

// ─── App State ────────────────────────────────────────────────────────────────

let achievements = [];
let projects     = [];
let achVisible   = 3;
let projVisible  = 6;

let achFilter  = { search: '', level: '', cat: '', year: '' };
let projFilter = { search: '', cat: '', year: '' };

// ─── Init ─────────────────────────────────────────────────────────────────────

document.addEventListener('DOMContentLoaded', async () => {
    initWaButton();

    // Loading placeholders
    showSkeleton('acaab-ach-grid', 3);
    showSkeleton('acaab-proj-track', 4);

    const [achResult, projResult] = await Promise.allSettled([
        fetchAchievements(),
        fetchProjects(),
    ]);

    if (achResult.status === 'fulfilled') {
        achievements = achResult.value.sort((a, b) => b.year - a.year);
    } else {
        console.error('[ACAAB] achievements error:', achResult.reason);
        showError('acaab-ach-grid', t('grp_acaab_ach_error'));
    }

    if (projResult.status === 'fulfilled') {
        projects = projResult.value;
    } else {
        console.error('[ACAAB] projects error:', projResult.reason);
        showError('acaab-proj-track', t('grp_acaab_proj_error'));
    }

    initStats();
    initAchievements();
    initProjects();
    updateDataNote();
});

// Re-render saat bahasa berubah dari kit navbar
document.addEventListener('languageChanged', () => {
    updateStats();
    renderAchievements();
    buildAchFilterOptions();
    renderProjects();
    buildProjFilterOptions();
    updateWaButton();
    updateDataNote();
    updateSearchPlaceholders();
});

// ─── Skeleton / Error ─────────────────────────────────────────────────────────

function showSkeleton(containerId, count) {
    const el = document.getElementById(containerId);
    if (!el) return;
    el.innerHTML = Array(count).fill(0).map(() =>
        `<div class="acaab-skeleton" style="height:220px;border-radius:0.75rem;"></div>`
    ).join('');
}

function showError(containerId, msg) {
    const el = document.getElementById(containerId);
    if (el) el.innerHTML = `<p style="color:#ef4444;padding:1rem 0;grid-column:1/-1;">${escHtml(msg)}</p>`;
}

// ─── Stats ────────────────────────────────────────────────────────────────────

function initStats() {
    updateStats();

    const statsEl = document.getElementById('acaab-stats');
    if (!statsEl) return;

    const intl     = achievements.filter(a => a.level === 'Internasional').length;
    const national = achievements.filter(a => a.level === 'Nasional').length;
    const regional = achievements.filter(a => a.level === 'Regional').length;

    const observer = new IntersectionObserver(entries => {
        entries.forEach(entry => {
            if (!entry.isIntersecting) return;
            animateCount('stat-total-ach',  achievements.length, 1600);
            animateCount('stat-total-proj', projects.length,     1600);
            animateCount('stat-intl',       intl,     1200);
            animateCount('stat-national',   national, 1350);
            animateCount('stat-regional',   regional, 1500);
            observer.disconnect();
        });
    }, { threshold: 0.4 });

    observer.observe(statsEl);
}

function updateStats() {
    const set = (id, val) => { const el = document.getElementById(id); if (el) el.textContent = val; };
    set('stat-total-ach',  achievements.length);
    set('stat-total-proj', projects.length);
    set('stat-intl',       achievements.filter(a => a.level === 'Internasional').length);
    set('stat-national',   achievements.filter(a => a.level === 'Nasional').length);
    set('stat-regional',   achievements.filter(a => a.level === 'Regional').length);
}

function animateCount(elId, target, duration) {
    const el = document.getElementById(elId);
    if (!el) return;
    const start = performance.now();
    (function step(now) {
        const p      = Math.min((now - start) / duration, 1);
        const eased  = 1 - Math.pow(1 - p, 4); // easeOutQuart
        el.textContent = Math.round(target * eased).toLocaleString();
        if (p < 1) requestAnimationFrame(step);
    })(start);
}

function updateDataNote() {
    const el = document.getElementById('acaab-data-note');
    if (!el) return;
    const lang   = getLang();
    const locale = lang === 'en' ? 'en-US' : 'id-ID';
    const date   = new Date().toLocaleDateString(locale, { day: 'numeric', month: 'long', year: 'numeric' });
    el.textContent = `${t('grp_acaab_stats_data_note')} ${date}`;
}

// ─── Achievements ─────────────────────────────────────────────────────────────

const ACH_INIT = 3;
const ACH_MORE = 3;

const LEVEL_CLASS = {
    Internasional: 'acaab-badge-intl',
    Nasional:      'acaab-badge-nasional',
    Regional:      'acaab-badge-regional',
};

function initAchievements() {
    buildAchFilterOptions();
    renderAchievements();
    bindAchEvents();
}

function buildAchFilterOptions() {
    const levelSel = document.getElementById('acaab-ach-level');
    const catSel   = document.getElementById('acaab-ach-cat');
    const yearSel  = document.getElementById('acaab-ach-year');
    if (!levelSel || !catSel || !yearSel) return;

    const levels = ['Internasional', 'Nasional', 'Regional'];
    const cats   = [...new Set(achievements.map(a => a.category))].sort();
    const years  = [...new Set(achievements.map(a => String(a.year)))].filter(Boolean).sort((a, b) => b - a);

    levelSel.innerHTML = `<option value="">${escHtml(t('grp_acaab_ach_filter_level'))}</option>` +
        levels.map(l => `<option value="${escHtml(l)}"${achFilter.level === l ? ' selected' : ''}>${escHtml(l)}</option>`).join('');
    catSel.innerHTML = `<option value="">${escHtml(t('grp_acaab_ach_filter_cat'))}</option>` +
        cats.map(c => `<option value="${escHtml(c)}"${achFilter.cat === c ? ' selected' : ''}>${escHtml(c)}</option>`).join('');
    yearSel.innerHTML = `<option value="">${escHtml(t('grp_acaab_ach_filter_year'))}</option>` +
        years.map(y => `<option value="${escHtml(y)}"${achFilter.year === y ? ' selected' : ''}>${escHtml(y)}</option>`).join('');
}

function filterAchievements() {
    const q = achFilter.search.toLowerCase();
    return achievements.filter(a => {
        const matchSearch = !q || [a.title, a.team, a.category, a.competition]
            .some(s => (s || '').toLowerCase().includes(q));
        const matchLevel = !achFilter.level || a.level === achFilter.level;
        const matchCat   = !achFilter.cat   || a.category === achFilter.cat;
        const matchYear  = !achFilter.year  || String(a.year) === achFilter.year;
        return matchSearch && matchLevel && matchCat && matchYear;
    });
}

function renderAchievements() {
    const grid    = document.getElementById('acaab-ach-grid');
    const countEl = document.getElementById('acaab-ach-count');
    const moreBtn = document.getElementById('acaab-ach-more');
    const lessBtn = document.getElementById('acaab-ach-less');
    const resetBtn= document.getElementById('acaab-ach-reset');
    if (!grid) return;

    const filtered = filterAchievements();
    const visible  = filtered.slice(0, achVisible);
    const hasFilter = achFilter.search || achFilter.level || achFilter.cat || achFilter.year;

    if (countEl) countEl.textContent =
        `${t('grp_acaab_ach_showing')} ${filtered.length} ${t('grp_acaab_ach_results')}`;
    if (resetBtn) resetBtn.style.display = hasFilter ? 'flex' : 'none';

    if (filtered.length === 0) {
        grid.innerHTML = `<p style="color:#64748b;padding:0.5rem 0;grid-column:1/-1;">${escHtml(t('grp_acaab_ach_empty'))}</p>`;
        if (moreBtn) moreBtn.style.display = 'none';
        if (lessBtn) lessBtn.style.display = 'none';
        return;
    }

    grid.innerHTML = visible.map((a, i) => achCardHtml(a, i)).join('');

    if (moreBtn) moreBtn.style.display = achVisible < filtered.length ? 'inline-block' : 'none';
    if (lessBtn) lessBtn.style.display = achVisible > ACH_INIT        ? 'inline-block' : 'none';

    grid.querySelectorAll('.acaab-ach-card').forEach(card => {
        card.addEventListener('click', (e) => {
            // Biarkan tombol yang merupakan link tetap berfungsi
            if (e.target.closest('a')) return;
            const ach = achievements.find(a => a.id === card.dataset.id);
            if (ach) openAchModal(ach);
        });
    });
}

function achCardHtml(a, idx) {
    return `
    <article class="acaab-ach-card acaab-fade-in" data-id="${escHtml(a.id)}" style="animation-delay:${idx * 0.05}s;cursor:pointer;">
        <div class="acaab-ach-top-bar"></div>
        <!-- Image h-56 (224px) -->
        <div style="position:relative;height:224px;overflow:hidden;background:#f1f5f9;">
            <img src="${escHtml(a.image)}" alt="${escHtml(a.title)}" loading="lazy" class="acaab-card-img"
                style="width:100%;height:100%;object-fit:cover;"
                onerror="this.src='https://placehold.co/800x600/003150/FDB813?text=Informatika+UNTAN'">
            <!-- Rank badge top-left: white pill dengan trophy icon -->
            <div style="position:absolute;top:0.75rem;left:0.75rem;background:rgba(255,255,255,0.95);backdrop-filter:blur(4px);color:#003150;font-weight:700;padding:0.25rem 0.625rem;border-radius:9999px;box-shadow:0 1px 3px rgba(0,0,0,0.15);display:flex;align-items:center;gap:0.375rem;font-size:0.72rem;z-index:2;">
                <i class="fas fa-trophy" style="color:#feb401;font-size:0.65rem;"></i>
                ${escHtml(a.rank)}
            </div>
        </div>
        <!-- Content p-6 -->
        <div style="padding:1.5rem;display:flex;flex-direction:column;flex-grow:1;">
            <!-- Category + Year row -->
            <div style="display:flex;align-items:center;gap:0.75rem;margin-bottom:0.75rem;">
                <span style="color:#1e40af;font-size:0.72rem;font-weight:700;text-transform:uppercase;letter-spacing:0.05em;">${escHtml(a.category)}</span>
                <span style="color:#94a3b8;font-size:0.72rem;font-weight:500;display:flex;align-items:center;gap:0.25rem;border-left:1px solid #e2e8f0;padding-left:0.625rem;">
                    <i class="fas fa-calendar-alt" style="font-size:0.6rem;"></i> ${escHtml(String(a.year))}
                </span>
            </div>
            <!-- Title -->
            <h3 class="acaab-card-title acaab-line-clamp-2" style="font-size:1.125rem;font-weight:700;color:#003150;margin:0 0 0.75rem;line-height:1.35;font-family:'Roboto Condensed',sans-serif;">${escHtml(a.title)}</h3>
            <!-- Description 3 lines -->
            <p class="acaab-line-clamp-3" style="color:#475569;font-size:0.875rem;line-height:1.6;margin:0 0 1.5rem;flex-grow:1;">${escHtml(a.description)}</p>
            <!-- Bottom -->
            <div style="border-top:1px solid #f1f5f9;padding-top:1rem;margin-top:auto;">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;">
                    <!-- Avatar + team + generation -->
                    <div style="display:flex;align-items:center;gap:0.625rem;">
                        <div style="width:2rem;height:2rem;border-radius:0.375rem;background:rgba(0,49,80,0.05);border:1px solid rgba(0,49,80,0.1);display:flex;align-items:center;justify-content:center;color:#003150;font-weight:700;font-size:0.65rem;flex-shrink:0;">${escHtml(a.avatar)}</div>
                        <div>
                            <span style="font-weight:700;color:#1e293b;display:block;font-size:0.8125rem;line-height:1.2;">${escHtml(a.team)}</span>
                            <span style="color:#64748b;display:block;font-size:0.72rem;margin-top:0.1rem;">${escHtml(a.generation)}</span>
                        </div>
                    </div>
                    <!-- Level badge -->
                    <span style="background:#f1f5f9;color:#475569;font-size:0.575rem;padding:0.2rem 0.5rem;border-radius:0.25rem;font-weight:700;text-transform:uppercase;letter-spacing:0.05em;white-space:nowrap;">${escHtml(a.level)}</span>
                </div>
                <!-- Full-width CTA button -->
                <button class="acaab-ach-readmore acaab-ach-read-btn" data-id="${escHtml(a.id)}"
                    style="width:100%;padding:0.625rem;border-radius:0.375rem;background:rgba(0,49,80,0.05);color:#003150;font-weight:700;font-size:0.875rem;border:none;cursor:pointer;transition:background 0.2s,color 0.2s;min-height:44px;">
                    ${escHtml(t('grp_acaab_modal_read_more'))}
                </button>
            </div>
        </div>
    </article>`;
}

function bindAchEvents() {
    const search  = document.getElementById('acaab-ach-search');
    const level   = document.getElementById('acaab-ach-level');
    const cat     = document.getElementById('acaab-ach-cat');
    const year    = document.getElementById('acaab-ach-year');
    const reset   = document.getElementById('acaab-ach-reset');
    const moreBtn = document.getElementById('acaab-ach-more');
    const lessBtn = document.getElementById('acaab-ach-less');

    const onChange = () => {
        achFilter.search = search ? search.value.trim() : '';
        achFilter.level  = level  ? level.value  : '';
        achFilter.cat    = cat    ? cat.value    : '';
        achFilter.year   = year   ? year.value   : '';
        achVisible = ACH_INIT;
        renderAchievements();
    };

    if (search) search.addEventListener('input',  onChange);
    if (level)  level.addEventListener('change',  onChange);
    if (cat)    cat.addEventListener('change',    onChange);
    if (year)   year.addEventListener('change',   onChange);

    if (reset) reset.addEventListener('click', () => {
        achFilter = { search: '', level: '', cat: '', year: '' };
        if (search) search.value = '';
        if (level)  level.value  = '';
        if (cat)    cat.value    = '';
        if (year)   year.value   = '';
        achVisible = ACH_INIT;
        renderAchievements();
    });

    if (moreBtn) moreBtn.addEventListener('click', () => { achVisible += ACH_MORE; renderAchievements(); });
    if (lessBtn) lessBtn.addEventListener('click', () => {
        achVisible = ACH_INIT;
        document.getElementById('acaab-ach-section')?.scrollIntoView({ behavior: 'smooth', block: 'start' });
        renderAchievements();
    });
}

// ─── Achievement Modal ────────────────────────────────────────────────────────

function infoRow(icon, label, value) {
    if (!value) return '';
    return `<div style="display:flex;gap:0.625rem;align-items:flex-start;">
        <span style="color:#feb401;margin-top:0.125rem;flex-shrink:0;"><i class="fas fa-${icon}" style="font-size:0.75rem;"></i></span>
        <div>
            <p style="font-size:0.6rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;color:#94a3b8;margin:0 0 0.125rem;line-height:1;">${escHtml(label)}</p>
            <p style="font-size:0.875rem;font-weight:600;color:#1e293b;margin:0;line-height:1.3;">${escHtml(value)}</p>
        </div>
    </div>`;
}

function memberItem(nama, sub) {
    const initial = (nama || '?').charAt(0).toUpperCase();
    return `<li style="display:flex;align-items:center;gap:0.5rem;background:#f8fafc;padding:0.5rem 0.75rem;border-radius:0.375rem;">
        <span style="width:1.5rem;height:1.5rem;border-radius:50%;background:rgba(254,180,1,0.2);color:#b45309;display:flex;align-items:center;justify-content:center;font-size:0.72rem;font-weight:700;flex-shrink:0;">${initial}</span>
        <div style="display:flex;flex-direction:column;">
            <span style="font-size:0.875rem;font-weight:600;color:#334155;line-height:1.2;">${escHtml(nama)}</span>
            ${sub ? `<span style="font-size:0.65rem;color:#94a3b8;margin-top:0.125rem;">${escHtml(sub)}</span>` : ''}
        </div>
    </li>`;
}

function openAchModal(a) {
    const membersHtml = a.members && a.members.length > 0 ? `
        <div style="border-top:1px solid #f1f5f9;padding-top:1rem;margin-bottom:1rem;">
            <p style="font-size:0.6rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;color:#94a3b8;margin:0 0 0.5rem;">Anggota Tim</p>
            <ul style="list-style:none;margin:0;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:0.5rem;">
                ${a.members.map(m => memberItem(m.nama, m.angkatan ? `Angkatan ${m.angkatan}` : '')).join('')}
            </ul>
        </div>` : '';

    renderModal(`
        <!-- Image header -->
        <div style="position:relative;border-radius:0.75rem 0.75rem 0 0;background:#0f172a;flex-shrink:0;">
            <img src="${escHtml(a.image)}" alt="${escHtml(a.title)}" style="width:100%;max-height:450px;object-fit:contain;display:block;"
                onerror="this.src='https://placehold.co/800x600/0f172a/FDB813?text=Informatika+UNTAN'">
            <div style="position:absolute;inset:0;background:linear-gradient(to top,rgba(0,0,0,0.8) 0%,rgba(0,0,0,0.1) 40%,transparent 100%);pointer-events:none;"></div>
            <!-- Close button: white rounded-full -->
            <button id="acaab-modal-close" aria-label="Tutup"
                style="position:absolute;top:0.75rem;right:0.75rem;width:2.25rem;height:2.25rem;background:rgba(255,255,255,0.9);backdrop-filter:blur(4px);border:none;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">
                <i class="fas fa-times" style="color:#334155;font-size:0.875rem;"></i>
            </button>
            <!-- Two badges bottom-left -->
            <div style="position:absolute;bottom:1rem;left:1rem;display:flex;gap:0.5rem;flex-wrap:wrap;">
                <span style="background:#feb401;color:#0f172a;font-size:0.72rem;font-weight:700;padding:0.3rem 0.75rem;border-radius:0.25rem;display:flex;align-items:center;gap:0.375rem;">
                    <i class="fas fa-trophy" style="font-size:0.65rem;"></i>${escHtml(a.rank)}
                </span>
                <span style="background:rgba(255,255,255,0.2);backdrop-filter:blur(4px);color:white;font-size:0.72rem;font-weight:700;padding:0.3rem 0.75rem;border-radius:0.25rem;text-transform:uppercase;letter-spacing:0.05em;">
                    ${escHtml(a.level)}
                </span>
            </div>
        </div>
        <!-- Content -->
        <div style="padding:1.5rem;">
            <span style="color:#1e40af;font-size:0.72rem;font-weight:700;text-transform:uppercase;letter-spacing:0.05em;">${escHtml(a.category)}</span>
            <h2 style="font-size:1.125rem;font-weight:700;color:#003150;line-height:1.3;margin:0.25rem 0 1.25rem;font-family:'Roboto Condensed',sans-serif;">${escHtml(a.title)}</h2>
            <!-- Info grid: slate-50 bg -->
            <div style="display:grid;grid-template-columns:1fr 1fr;gap:1rem;padding:1rem;background:#f8fafc;border-radius:0.5rem;margin-bottom:1.25rem;">
                ${infoRow('users', t('grp_acaab_modal_team'), a.team)}
                ${a.nim ? infoRow('id-card', 'NIM', a.nim) : ''}
                ${infoRow('user-graduate', t('grp_acaab_modal_generation'), a.generation)}
                ${infoRow('calendar-alt', 'Tahun', String(a.year))}
                ${infoRow('award', 'Kompetisi', a.competition)}
                ${infoRow('tag', 'Bidang', a.category)}
            </div>
            ${membersHtml}
            <!-- Description -->
            <div style="border-top:1px solid #f1f5f9;padding-top:1rem;">
                <p style="font-size:0.6rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;color:#94a3b8;margin:0 0 0.5rem;">Deskripsi</p>
                <p style="color:#475569;font-size:0.875rem;line-height:1.65;margin:0;">${escHtml(a.description)}</p>
            </div>
            <!-- Close button full-width -->
            <button id="acaab-modal-close-btn" style="margin-top:1.5rem;width:100%;padding:0.75rem;background:#003150;color:white;font-weight:700;border:none;border-radius:0.5rem;cursor:pointer;font-size:0.875rem;">
                Tutup
            </button>
        </div>
    `, true);
}

// ─── Projects ─────────────────────────────────────────────────────────────────

const PROJ_INIT = 6;
const PROJ_MORE = 3;

function initProjects() {
    buildProjFilterOptions();
    renderProjects();
    bindProjEvents();
}

function buildProjFilterOptions() {
    const catSel  = document.getElementById('acaab-proj-cat');
    const yearSel = document.getElementById('acaab-proj-year');
    if (!catSel || !yearSel) return;

    const cats  = [...new Set(projects.flatMap(p => p.categories))].sort();
    const years = [...new Set(projects.map(p => String(p.year)))].filter(Boolean).sort((a, b) => b - a);

    catSel.innerHTML  = `<option value="">${escHtml(t('grp_acaab_proj_filter_cat'))}</option>` +
        cats.map(c => `<option value="${escHtml(c)}"${projFilter.cat === c ? ' selected' : ''}>${escHtml(c)}</option>`).join('');
    yearSel.innerHTML = `<option value="">${escHtml(t('grp_acaab_proj_filter_year'))}</option>` +
        years.map(y => `<option value="${escHtml(y)}"${projFilter.year === y ? ' selected' : ''}>${escHtml(y)}</option>`).join('');
}

function filterProjects() {
    const q = projFilter.search.toLowerCase();
    const result = projects.filter(p => {
        const matchSearch = !q || [p.title, p.studentName, p.description, ...p.categories]
            .some(s => (s || '').toLowerCase().includes(q));
        const matchCat  = !projFilter.cat  || p.categories.includes(projFilter.cat);
        const matchYear = !projFilter.year || String(p.year) === projFilter.year;
        return matchSearch && matchCat && matchYear;
    });
    
    // Sort descending by year
    result.sort((a, b) => (b.year || 0) - (a.year || 0));
    
    return result;
}

function renderProjects() {
    const track    = document.getElementById('acaab-proj-track');
    const moreBtn  = document.getElementById('acaab-proj-more');
    const resetBtn = document.getElementById('acaab-proj-reset');
    if (!track) return;

    const filtered  = filterProjects();
    const visible   = filtered.slice(0, projVisible);
    const hasFilter = projFilter.search || projFilter.cat || projFilter.year;

    if (resetBtn) resetBtn.style.display = hasFilter ? 'flex' : 'none';

    if (filtered.length === 0) {
        track.innerHTML = `<p style="color:#64748b;padding:0.5rem 0;">${escHtml(t('grp_acaab_proj_empty'))}</p>`;
        if (moreBtn) moreBtn.style.display = 'none';
        return;
    }

    track.innerHTML = visible.map((p, i) => projCardHtml(p, i)).join('');
    if (moreBtn) moreBtn.style.display = projVisible < filtered.length ? 'inline-block' : 'none';

    // Responsif: Sembunyikan scroll button & center jika cuma 1 data
    const prevBtn = document.getElementById('acaab-proj-prev');
    const nextBtn = document.getElementById('acaab-proj-next');
    if (prevBtn) prevBtn.style.display = filtered.length <= 1 ? 'none' : 'flex';
    if (nextBtn) nextBtn.style.display = filtered.length <= 1 ? 'none' : 'flex';
    track.style.justifyContent = filtered.length === 1 ? 'center' : 'flex-start';

    track.querySelectorAll('.acaab-proj-card-wrap').forEach(card => {
        card.addEventListener('click', (e) => {
            if (e.target.closest('a') && e.target.closest('a').href) return;
            const proj = projects.find(p => p.id === card.dataset.id);
            if (proj) openProjModal(proj);
        });
    });
}

function projCardHtml(p, idx) {
    const catBadges = p.categories.map(c => `
        <span style="display:inline-flex;align-items:center;gap:0.2rem;font-size:0.6rem;font-weight:700;color:#feb401;text-transform:uppercase;letter-spacing:0.05em;background:rgba(0,0,0,0.3);padding:0.2rem 0.45rem;border-radius:0.2rem;backdrop-filter:blur(4px);">
            <i class="fas fa-tag" style="font-size:0.5rem;"></i>${escHtml(c)}
        </span>`).join('');

    return `
    <div class="acaab-proj-card acaab-proj-card-wrap acaab-fade-in" data-id="${escHtml(p.id)}" style="animation-delay:${idx * 0.05}s;cursor:pointer;">
        <div class="acaab-proj-left-bar"></div>
        <!-- Image h-52 (208px) dengan title overlay -->
        <div style="height:208px;overflow:hidden;position:relative;">
            <img src="${escHtml(p.image)}" alt="${escHtml(p.title)}" loading="lazy" class="acaab-card-img"
                style="width:100%;height:100%;object-fit:cover;"
                onerror="this.src='https://placehold.co/800x600/003150/FDB813?text=Informatika+UNTAN'">
            <!-- Gradient overlay: title + categories di dalam gambar -->
            <div style="position:absolute;inset:0;background:linear-gradient(to top,rgba(0,49,80,0.85),transparent);padding:1.25rem;display:flex;flex-direction:column;justify-content:flex-end;pointer-events:none;">
                <h4 style="font-size:1rem;font-weight:700;color:white;line-height:1.25;margin:0 0 0.375rem;font-family:'Roboto Condensed',sans-serif;">${escHtml(p.title)}</h4>
                <div style="display:flex;flex-wrap:wrap;gap:0.3rem;">${catBadges}</div>
            </div>
        </div>
        <!-- Body p-5 -->
        <div style="padding:1.25rem;display:flex;flex-direction:column;flex-grow:1;">
            <!-- Meta: student + year -->
            <div style="display:flex;flex-wrap:wrap;align-items:center;gap:0.625rem;margin-bottom:0.75rem;font-size:0.72rem;color:#64748b;font-weight:500;">
                ${p.studentName ? `<span style="display:flex;align-items:center;gap:0.25rem;"><i class="fas fa-user" style="color:#94a3b8;font-size:0.6rem;"></i>${escHtml(p.studentName)}</span>` : ''}
                ${p.year ? `<span style="display:flex;align-items:center;gap:0.25rem;"><i class="fas fa-calendar-alt" style="color:#94a3b8;font-size:0.6rem;"></i>${escHtml(String(p.year))}</span>` : ''}
            </div>
            <!-- Description 3 lines -->
            <p class="acaab-line-clamp-3" style="color:#475569;font-size:0.875rem;line-height:1.6;margin:0 0 1.25rem;flex-grow:1;">${escHtml(p.description)}</p>
            <!-- Actions -->
            <div style="display:flex;align-items:center;gap:0.625rem;margin-top:auto;">
                <button class="acaab-proj-readmore" data-id="${escHtml(p.id)}"
                    style="color:#003150;font-weight:700;font-size:0.875rem;background:none;border:none;cursor:pointer;display:flex;align-items:center;gap:0.375rem;min-height:44px;">
                    ${escHtml(t('grp_acaab_modal_read_more'))} <i class="fas fa-arrow-right" style="font-size:0.7rem;"></i>
                </button>
                ${p.link ? `
                <a href="${escHtml(p.link)}" target="_blank" rel="noopener noreferrer"
                    style="margin-left:auto;display:flex;align-items:center;gap:0.375rem;font-size:0.72rem;font-weight:700;color:#64748b;border:1px solid #e2e8f0;border-radius:0.375rem;padding:0.375rem 0.625rem;text-decoration:none;min-height:44px;transition:color 0.2s,border-color 0.2s;">
                    <i class="fas fa-external-link-alt" style="font-size:0.65rem;"></i>${escHtml(t('grp_acaab_modal_visit'))}
                </a>` : ''}
            </div>
        </div>
    </div>`;
}

function bindProjEvents() {
    const search  = document.getElementById('acaab-proj-search');
    const cat     = document.getElementById('acaab-proj-cat');
    const year    = document.getElementById('acaab-proj-year');
    const reset   = document.getElementById('acaab-proj-reset');
    const moreBtn = document.getElementById('acaab-proj-more');
    const prevBtn = document.getElementById('acaab-proj-prev');
    const nextBtn = document.getElementById('acaab-proj-next');

    const onChange = () => {
        projFilter.search = search ? search.value.trim() : '';
        projFilter.cat    = cat    ? cat.value    : '';
        projFilter.year   = year   ? year.value   : '';
        projVisible = PROJ_INIT;
        renderProjects();
    };

    if (search) search.addEventListener('input',  onChange);
    if (cat)    cat.addEventListener('change',    onChange);
    if (year)   year.addEventListener('change',   onChange);

    if (reset) reset.addEventListener('click', () => {
        projFilter = { search: '', cat: '', year: '' };
        if (search) search.value = '';
        if (cat)    cat.value    = '';
        if (year)   year.value   = '';
        projVisible = PROJ_INIT;
        renderProjects();
    });

    if (moreBtn) moreBtn.addEventListener('click', () => { projVisible += PROJ_MORE; renderProjects(); });

    const track = document.getElementById('acaab-proj-track');
    if (prevBtn && track) prevBtn.addEventListener('click', () => {
        const cardW = (track.firstElementChild ? track.firstElementChild.offsetWidth : 300) + 20;
        track.scrollBy({ left: -cardW, behavior: 'smooth' });
    });
    if (nextBtn && track) nextBtn.addEventListener('click', () => {
        const cardW = (track.firstElementChild ? track.firstElementChild.offsetWidth : 300) + 20;
        track.scrollBy({ left: cardW, behavior: 'smooth' });
    });
}

// ─── Project Modal ────────────────────────────────────────────────────────────

function openProjModal(p) {
    const membersHtml = p.members && p.members.length > 0 ? `
        <div style="border-top:1px solid #f1f5f9;padding-top:1rem;margin-bottom:1rem;">
            <p style="font-size:0.6rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;color:#94a3b8;margin:0 0 0.5rem;">Anggota Tim</p>
            <ul style="list-style:none;margin:0;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:0.5rem;">
                ${p.members.map(m => memberItem(m.nama, m.nim || '')).join('')}
            </ul>
        </div>` : '';

    const catBadgesImg = p.categories.map(c => `
        <span style="background:#feb401;color:#0f172a;font-size:0.72rem;font-weight:700;padding:0.3rem 0.75rem;border-radius:0.25rem;display:inline-flex;align-items:center;gap:0.375rem;text-transform:uppercase;letter-spacing:0.05em;">
            <i class="fas fa-tag" style="font-size:0.6rem;"></i>${escHtml(c)}
        </span>`).join('');

    const linkSection = p.link
        ? `<a href="${escHtml(p.link)}" target="_blank" rel="noopener noreferrer"
                style="display:flex;align-items:center;justify-content:center;gap:0.5rem;width:100%;padding:0.75rem;background:#003150;color:white;font-weight:700;border-radius:0.5rem;font-size:0.875rem;text-decoration:none;margin-bottom:0.625rem;">
                <i class="fas fa-external-link-alt" style="font-size:0.8rem;"></i>${escHtml(t('grp_acaab_modal_visit'))}
           </a>`
        : `<div style="display:flex;align-items:center;justify-content:center;gap:0.5rem;width:100%;padding:0.75rem;background:#f1f5f9;color:#94a3b8;font-weight:700;border-radius:0.5rem;font-size:0.875rem;margin-bottom:0.625rem;cursor:not-allowed;">
                <i class="fas fa-file-alt" style="font-size:0.8rem;"></i>${escHtml(t('grp_acaab_modal_no_link'))}
           </div>`;

    renderModal(`
        <!-- Image header -->
        <div style="position:relative;border-radius:0.75rem 0.75rem 0 0;background:#0f172a;flex-shrink:0;">
            <img src="${escHtml(p.image)}" alt="${escHtml(p.title)}" style="width:100%;max-height:450px;object-fit:contain;display:block;"
                onerror="this.src='https://placehold.co/800x600/0f172a/FDB813?text=Informatika+UNTAN'">
            <div style="position:absolute;inset:0;background:linear-gradient(to top,rgba(0,0,0,0.8) 0%,rgba(0,0,0,0.1) 40%,transparent 100%);pointer-events:none;"></div>
            <!-- Close button -->
            <button id="acaab-modal-close" aria-label="Tutup"
                style="position:absolute;top:0.75rem;right:0.75rem;width:2.25rem;height:2.25rem;background:rgba(255,255,255,0.9);backdrop-filter:blur(4px);border:none;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,0.2);">
                <i class="fas fa-times" style="color:#334155;font-size:0.875rem;"></i>
            </button>
            <!-- Category badges bottom-left -->
            <div style="position:absolute;bottom:1rem;left:1rem;display:flex;flex-wrap:wrap;gap:0.375rem;">${catBadgesImg}</div>
        </div>
        <!-- Content -->
        <div style="padding:1.5rem;">
            <h2 style="font-size:1.125rem;font-weight:700;color:#003150;line-height:1.3;margin:0 0 1.25rem;font-family:'Roboto Condensed',sans-serif;">${escHtml(p.title)}</h2>
            <!-- Info grid -->
            <div style="display:grid;grid-template-columns:1fr 1fr;gap:1rem;padding:1rem;background:#f8fafc;border-radius:0.5rem;margin-bottom:1.25rem;">
                ${p.studentName ? infoRow('users', t('grp_acaab_modal_team'), p.studentName) : ''}
                ${p.nim ? infoRow('id-card', 'NIM', p.nim) : ''}
                ${infoRow('calendar-alt', 'Tahun', String(p.year))}
                ${infoRow('tag', 'Bidang', p.categories.join(', '))}
            </div>
            ${membersHtml}
            <!-- Description -->
            <div style="border-top:1px solid #f1f5f9;padding-top:1rem;margin-bottom:1.25rem;">
                <p style="font-size:0.6rem;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;color:#94a3b8;margin:0 0 0.5rem;">Deskripsi</p>
                <p style="color:#475569;font-size:0.875rem;line-height:1.65;margin:0;">${escHtml(p.description)}</p>
                ${p.catatan ? `
                <div style="margin-top:1rem;padding:0.75rem;background:rgba(239,246,255,0.5);border:1px solid #bfdbfe;border-radius:0.5rem;">
                    <p style="font-size:0.6rem;font-weight:700;text-transform:uppercase;color:#93c5fd;margin:0 0 0.25rem;">Catatan Tambahan</p>
                    <p style="font-size:0.875rem;color:#475569;font-style:italic;margin:0;">${escHtml(p.catatan)}</p>
                </div>` : ''}
            </div>
            <!-- Link + close buttons -->
            ${linkSection}
            <button id="acaab-modal-close-btn" style="width:100%;padding:0.625rem;border:2px solid #e2e8f0;color:#475569;font-weight:700;background:white;border-radius:0.5rem;cursor:pointer;font-size:0.875rem;transition:border-color 0.2s,background 0.2s;">
                Tutup
            </button>
        </div>
    `, true);
}

// ─── Modal shared ─────────────────────────────────────────────────────────────

function renderModal(innerHtml, hasCloseBtn = false) {
    const container = document.getElementById('acaab-modal');
    if (!container) return;

    container.innerHTML = `
        <div class="acaab-modal-backdrop" id="acaab-modal-bd">
            <div style="background:white;border-radius:0.75rem;max-width:672px;width:100%;max-height:90vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,0.35);">
                ${innerHtml}
            </div>
        </div>`;

    document.body.classList.add('acaab-modal-open');

    document.getElementById('acaab-modal-close')?.addEventListener('click', closeModal);
    if (hasCloseBtn) {
        document.getElementById('acaab-modal-close-btn')?.addEventListener('click', closeModal);
    }
    document.getElementById('acaab-modal-bd').addEventListener('click', e => {
        if (e.target === e.currentTarget) closeModal();
    });
    document.addEventListener('keydown', onEsc);
}

function closeModal() {
    const c = document.getElementById('acaab-modal');
    if (c) c.innerHTML = '';
    document.body.classList.remove('acaab-modal-open');
    document.removeEventListener('keydown', onEsc);
}

function onEsc(e) { if (e.key === 'Escape') closeModal(); }

// ─── CTA / WhatsApp ───────────────────────────────────────────────────────────

const WA_NUMBER = '6285177655161';

function initWaButton() { updateWaButton(); }

function updateWaButton() {
    const btn = document.getElementById('acaab-cta-wa');
    if (!btn) return;
    const msg = getLang() === 'en'
        ? 'Hello! I would like to know more about Informatika UNTAN student achievements and projects.'
        : 'Halo! Saya ingin mengetahui lebih lanjut tentang prestasi dan karya mahasiswa Informatika UNTAN.';
    btn.href = `https://wa.me/${WA_NUMBER}?text=${encodeURIComponent(msg)}`;
}

// ─── Placeholder sync ─────────────────────────────────────────────────────────

function updateSearchPlaceholders() {
    const s1 = document.getElementById('acaab-ach-search');
    const s2 = document.getElementById('acaab-proj-search');
    if (s1) s1.placeholder = t('grp_acaab_ach_search');
    if (s2) s2.placeholder = t('grp_acaab_proj_search');
}
