<?php
// import_hierarki.php
// Logika Import Kegiatan: UPSERT (Berdasarkan Nama) dan Pembuatan Kode Otomatis

include_once 'header.php'; // Termasuk $conn, $is_admin, dan function getTahunAktifId()

// Cek apakah Composer autoload sudah ada (untuk PhpSpreadsheet)
if (!file_exists('vendor/autoload.php')) {
    die("Error: File 'vendor/autoload.php' tidak ditemukan. Pastikan Anda sudah menjalankan 'composer install'.");
}
require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\IOFactory;

if (!isset($_SESSION['user_id']) || !$_SESSION['is_admin']) {
    header("Location: dashboard.php");
    exit();
}

$message = "";
$success_count = 0;
$error_count = 0;

// =======================================================
// FUNGSI BANTUAN UNTUK OPERASI UPSERT (SELECT THEN INSERT)
// Menggunakan Prepared Statements untuk keamanan
// =======================================================
function upsert_and_get_id($conn, $table, $data, $nama_column_db, $tahun_aktif_id, $foreign_key_column = null, $foreign_key_id = null) {

    $name = trim($data['nama']);

    // 1. Cek apakah sudah ada (berdasarkan NAMA, TAHUN AKTIF, dan FK)
    $sql_check = "SELECT id FROM {$table} WHERE {$nama_column_db} = ? AND tahun_aktif_id = ?";
    $types = "si";
    $params = [$name, $tahun_aktif_id];

    if ($foreign_key_column && $foreign_key_id !== null) {
        $sql_check .= " AND {$foreign_key_column} = ?";
        $types .= "i";
        $params[] = $foreign_key_id;
    }
    $sql_check .= " LIMIT 1";

    $stmt_check = $conn->prepare($sql_check);
    if (!$stmt_check) return null;

    $stmt_check->bind_param($types, ...$params);
    $stmt_check->execute();
    $result = $stmt_check->get_result();

    if ($result && $result->num_rows > 0) {
        $stmt_check->close();
        return $result->fetch_assoc()['id']; // SELECT: Data sudah ada, kembalikan ID-nya
    }
    $stmt_check->close(); // Tutup statement check

    // 2. Jika tidak ada, lakukan INSERT
    $cols = [$nama_column_db, 'tahun_aktif_id'];
    $values_placeholder = '?, ?';
    $types_insert = "si";
    $params_insert = [$name, $tahun_aktif_id];

    if ($foreign_key_column && $foreign_key_id !== null) {
        $cols[] = $foreign_key_column;
        $values_placeholder .= ', ?';
        $types_insert .= "i";
        $params_insert[] = $foreign_key_id;
    }

    $sql_insert = "INSERT INTO {$table} (" . implode(', ', $cols) . ") VALUES ({$values_placeholder})";
    $stmt_insert = $conn->prepare($sql_insert);
    if (!$stmt_insert) return null;

    $stmt_insert->bind_param($types_insert, ...$params_insert);

    if ($stmt_insert->execute()) {
        $last_id = $conn->insert_id;
        $stmt_insert->close();
        return $last_id; // INSERT: Kembalikan ID baru
    } else {
        $stmt_insert->close();
        return null;
    }
}


// =======================================================
// LOGIKA IMPOR UTAMA
// =======================================================
if (isset($_POST['upload_import'])) {

    $TAHUN_AKTIF_ID = getTahunAktifId($conn);
    if (!$TAHUN_AKTIF_ID) {
        $message = "error|Tahun aktif tidak ditemukan. Harap aktifkan tahun di Manajemen Sistem.";
    } elseif (!empty($_FILES['csv_file']['name']) && $_FILES['csv_file']['error'] == 0) {

        $file_extension = pathinfo($_FILES['csv_file']['name'], PATHINFO_EXTENSION);
        $allowed_extensions = ['xlsx', 'xls', 'csv'];

        if (!in_array(strtolower($file_extension), $allowed_extensions)) {
            $message = "error|Ekstensi file tidak didukung. Harap gunakan XLSX, XLS, atau CSV.";
        } else {
            $file = $_FILES['csv_file']['tmp_name'];
            $conn->begin_transaction(); // Mulai transaksi untuk integritas data

            try {
                $spreadsheet = IOFactory::load($file);
                $worksheet = $spreadsheet->getActiveSheet();
                $rows = $worksheet->toArray();

                $is_header = true;
                $current_row_index = 0; // Untuk debugging baris

                foreach ($rows as $data) {
                    $current_row_index++;
                    if ($is_header) {
                        $is_header = false;
                        continue;
                    }

                    // Pastikan baris tidak kosong pada kolom Nama Program (data[1])
                    if (empty(trim($data[1] ?? ''))) {
                        $error_count++;
                        continue;
                    }

                    // --- Ambil Data dari Kolom (Trim data) ---
                    $nama_program = trim($data[1] ?? '');
                    $nama_kegiatan = trim($data[3] ?? '');
                    $nama_subkeg = trim($data[5] ?? '');
                    $nama_komponen = trim($data[7] ?? '');
                    $nama_subkom = trim($data[9] ?? '');
                    $nama_detail = trim($data[11] ?? '');

                    // Validasi Nama Wajib (Minimal Program, Kegiatan, Subkeg, Detail)
                    if (empty($nama_program) || empty($nama_kegiatan) || empty($nama_subkeg) || empty($nama_detail)) {
                           $error_count++;
                           continue;
                    }

                    // --- 1. Program ---
                    $program_id = upsert_and_get_id($conn, 'program', ['nama' => $nama_program], 'nama_program', $TAHUN_AKTIF_ID);
                    if (!$program_id) { $error_count++; continue; }

                    // Buat dan Update Kode Program (HANYA jika kode masih NULL)
                    $program_kode = $program_id;
                    $conn->query("UPDATE program SET kode = '{$program_kode}' WHERE id = {$program_id} AND kode IS NULL");


                    // --- 2. Kegiatan ---
                    $kegiatan_id = upsert_and_get_id($conn, 'kegiatan', ['nama' => $nama_kegiatan], 'nama_kegiatan', $TAHUN_AKTIF_ID, 'program_id', $program_id);
                    if (!$kegiatan_id) { $error_count++; continue; }

                    // Ambil kode program yang sudah ada
                    $program_kode_db = $conn->query("SELECT kode FROM program WHERE id = {$program_id}")->fetch_assoc()['kode'];

                    // Buat dan Update Kode Kegiatan: [Kode Program].[ID Kegiatan]
                    $kegiatan_kode = $conn->real_escape_string("{$program_kode_db}.{$kegiatan_id}");
                    $conn->query("UPDATE kegiatan SET kode = '{$kegiatan_kode}' WHERE id = {$kegiatan_id} AND kode IS NULL");


                    // --- 3. Subkegiatan ---
                    $subkeg_id = upsert_and_get_id($conn, 'subkegiatan', ['nama' => $nama_subkeg], 'nama_subkegiatan', $TAHUN_AKTIF_ID, 'kegiatan_id', $kegiatan_id);
                    if (!$subkeg_id) { $error_count++; continue; }

                    // Ambil kode kegiatan dari DB
                    $kegiatan_kode_db = $conn->query("SELECT kode FROM kegiatan WHERE id = {$kegiatan_id}")->fetch_assoc()['kode'];

                    // Buat dan Update Kode Subkegiatan: [Kode Kegiatan].[ID Subkegiatan]
                    $subkeg_kode = $conn->real_escape_string("{$kegiatan_kode_db}.{$subkeg_id}");
                    $conn->query("UPDATE subkegiatan SET kode = '{$subkeg_kode}' WHERE id = {$subkeg_id} AND kode IS NULL");


                    // --- 4. Komponen ---
                    $komponen_id = upsert_and_get_id($conn, 'komponen', ['nama' => $nama_komponen], 'nama_komponen', $TAHUN_AKTIF_ID, 'subkegiatan_id', $subkeg_id);
                    if (!$komponen_id) { $error_count++; continue; }

                    // Ambil kode subkegiatan dari DB
                    $subkeg_kode_db = $conn->query("SELECT kode FROM subkegiatan WHERE id = {$subkeg_id}")->fetch_assoc()['kode'];

                    // Buat dan Update Kode Komponen: [Kode Subkegiatan].K[ID Komponen]
                    $komponen_kode = $conn->real_escape_string("{$subkeg_kode_db}.K{$komponen_id}");
                    $conn->query("UPDATE komponen SET kode = '{$komponen_kode}' WHERE id = {$komponen_id} AND kode IS NULL");


                    // --- 5. Subkomponen ---
                    $subkom_id = upsert_and_get_id($conn, 'subkomponen', ['nama' => $nama_subkom], 'nama_subkomponen', $TAHUN_AKTIF_ID, 'komponen_id', $komponen_id);
                    if (!$subkom_id) { $error_count++; continue; }

                    // Ambil kode komponen dari DB
                    $komponen_kode_db = $conn->query("SELECT kode FROM komponen WHERE id = {$komponen_id}")->fetch_assoc()['kode'];

                    // Buat dan Update Kode Subkomponen: [Kode Komponen].SK[ID Subkomponen]
                    $subkom_kode = $conn->real_escape_string("{$komponen_kode_db}.SK{$subkom_id}");
                    $conn->query("UPDATE subkomponen SET kode = '{$subkom_kode}' WHERE id = {$subkom_id} AND kode IS NULL");


                    // --- 6. Detail Kegiatan (Hanya INSERT jika tidak ada) ---
                    // Menggunakan Prepared Statement untuk check
                    $sql_check_detail = "SELECT id FROM detail_kegiatan WHERE nama_detail = ? AND subkomponen_id = ? LIMIT 1";
                    $stmt_check_detail = $conn->prepare($sql_check_detail);
                    $stmt_check_detail->bind_param("si", $nama_detail, $subkom_id);
                    $stmt_check_detail->execute();
                    $result_detail = $stmt_check_detail->get_result();
                    $stmt_check_detail->close();

                    if ($result_detail && $result_detail->num_rows > 0) {
                        $success_count++;
                    } else {
                        // INSERT Detail Kegiatan (kode diisi otomatis setelah INSERT)
                        $sql_insert_detail = "INSERT INTO detail_kegiatan (nama_detail, subkomponen_id, tahun_aktif_id) VALUES (?, ?, ?)";
                        $stmt_insert_detail = $conn->prepare($sql_insert_detail);
                        $stmt_insert_detail->bind_param("sii", $nama_detail, $subkom_id, $TAHUN_AKTIF_ID);

                        if ($stmt_insert_detail->execute()) {
                            $detail_id = $conn->insert_id;
                            $stmt_insert_detail->close();
                            
                            // Ambil kode subkomponen dari DB
                            $subkom_kode_db = $conn->query("SELECT kode FROM subkomponen WHERE id = {$subkom_id}")->fetch_assoc()['kode'];

                            // Buat dan Update Kode Detail: [Kode Subkomponen].D[ID Detail]
                            $detail_kode = $conn->real_escape_string("{$subkom_kode_db}.D{$detail_id}");
                            $conn->query("UPDATE detail_kegiatan SET kode = '{$detail_kode}' WHERE id = {$detail_id}");
                            $success_count++;
                        } else {
                            $stmt_insert_detail->close();
                            $error_count++;
                        }
                    }
                }

                $conn->commit(); // Commit transaksi jika semua baris sukses
                $message = "success|Impor selesai! Berhasil: {$success_count} baris, Gagal: {$error_count} baris.";

            } catch (Exception $e) {
                $conn->rollback(); // Rollback jika ada error
                $message = "error|Gagal membaca file atau terjadi Error Transaksi: " . $e->getMessage();
            }
        }
    }
}

// Parsing pesan
if (!empty($message)) {
    list($msg_type, $msg_content) = explode('|', $message . '|');
} else {
    $msg_type = '';
    $msg_content = '';
}

?>

<div class="row">
    <div class="col-12">
        <h2><i class="bi bi-cloud-arrow-up"></i> Impor Kegiatan</h2>
        <p class="text-muted">Fitur ini akan mencari data berdasarkan <strong>Nama</strong>. Jika data (Program, Kegiatan, dsb.) belum ada, data tersebut akan ditambahkan, dan <strong>kolom Kode akan diisi otomatis</strong> berdasarkan ID baris.</p>
        <hr>

        <?php if ($message && $msg_content): ?>
            <div class="alert alert-<?php echo ($msg_type == 'success' ? 'success' : 'danger'); ?> alert-dismissible fade show" role="alert">
                <?php echo $msg_content; ?>
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
        <?php endif; ?>

        <div class="card p-4 mb-4 shadow-sm">
            <h5>Peringatan Penting ⚠️</h5>
            <ol>
                <li>Pastikan semua kolom `kode` di DB sudah disetel menjadi `NULL` pada baris lama.</li>
                <li>Baris-baris yang memiliki <strong>Nama</strong> yang sama persis dalam satu kegiatan akan dianggap sama dan ID-nya akan dipakai ulang.</li>
                <li>Kode yang dihasilkan mengikuti pola: <strong>ID Program</strong> -> <strong>P.ID Kegiatan</strong> -> <strong>P.K.ID Subkegiatan</strong>, dst.</li>
            </ol>
            <p class="text-info small"><i class="bi bi-info-circle-fill"></i> <strong>Template Kolom:</strong> Hanya perlu mengisi kolom <strong>Nama</strong> (kolom Index 1, 3, 5, 7, 9, 11). Kolom Kode (0, 2, 4, 6, 8, 10) di Excel akan <strong>diabaikan</strong>.</p>
            <a href="template.xlsx" class="btn btn-sm btn-success mt-3" download>
                <i class="bi bi-file-earmark-arrow-down-fill"></i> Download Template.xlsx
            </a>
        </div>

        <div class="card p-4 shadow-sm bg-light">
            <h5 class="mb-3">Unggah File Impor XLSX/XLS/CSV</h5>
            <form method="POST" action="import_hierarki.php" enctype="multipart/form-data">
                <div class="mb-3">
                    <label for="csvFile" class="form-label">Pilih File XLSX/XLS/CSV</label>
                    <input class="form-control" type="file" id="csvFile" name="csv_file" accept=".csv, .xlsx, .xls" required>
                </div>
                <button type="submit" name="upload_import" class="btn btn-primary"><i class="bi bi-cloud-upload"></i> Mulai Impor Data</button>
            </form>
        </div>
    </div>
</div>

<?php
include_once 'footer.php';
?>