// crud.js

// Fungsi-fungsi AJAX CRUD (Semua fungsi ini akan memanggil crud.php)

/**
 * Mengirim permintaan DELETE ke crud.php.
 * @param {string} table - Nama tabel database.
 * @param {string} idField - Nama kolom ID.
 * @param {*} idValue - Nilai ID record yang akan dihapus.
 * @returns {Promise<Object>} Promise yang resolve dengan objek respons dari server.
 */

function getPrintLayout(menuId) {
    return new Promise((resolve, reject) => {
        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: { action: 'get_print_layout', menuId: menuId },
            dataType: 'json',
            success: function (response) {
                // Jika json_cetak null atau kosong, kembalikan objek kosong
                resolve(response.data || {});
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (getPrintLayout):", error);
                reject(error);
            }
        });
    });
}

/**
 * Menyimpan layout cetak ke database.
 * @param {string} menuId - ID menu (contoh: trx_penjualan).
 * @param {Object} layoutData - Objek JavaScript yang berisi data layout.
 * @returns {Promise<Object>} Promise yang resolve dengan respons server.
 */
function savePrintLayout(menuId, layoutData) {
    return new Promise((resolve, reject) => {
        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: {
                action: 'save_print_layout',
                menuId: menuId,
                layoutJson: JSON.stringify(layoutData)
            },
            dataType: 'json',
            success: function (response) {
                resolve(response);
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (savePrintLayout):", error);
                reject(error);
            }
        });
    });
}

function hapus(table, idField, idValue) {
    
    return new Promise((resolve, reject) => {
        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: {
                action: 'hapus',
                table: table,
                idField: idField,
                idValue: idValue,
                xbrand: window.xbrand,
                xcab: window.xcab
            },
            dataType: 'json', // Tambahkan dataType agar jQuery parse JSON secara otomatis
            success: function (response) {
                resolve(response);
                
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (hapus):", status, error, xhr.responseText);
                try {
                    const errResponse = JSON.parse(xhr.responseText);
                    reject(new Error(`AJAX Error (hapus): ${status} - ${error}. Server: ${errResponse.error || xhr.responseText}`));
                } catch (e) {
                    reject(new Error(`AJAX Error (hapus): ${status} - ${error}. Response: ${xhr.responseText}`));
                }
            }
        });
    });
}

/**
 * Mengirim data JSON untuk penambahan record ke crud.php.
 * @param {string} table - Nama tabel database.
 * @param {Object} jsonData - Objek data yang akan ditambahkan.
 * @returns {Promise<Object>} Promise yang resolve dengan objek respons (biasanya berisi ID baru).
 */
function tambahjson(table, jsonData) {
    return new Promise((resolve, reject) => {
        const jsonDataString = JSON.stringify(jsonData);

        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: {
                action: 'tambahjson',
                table: table,
                jsonData: jsonDataString,
                xbrand: window.xbrand,
                xcab: window.xcab
            },
            dataType: 'json',
            success: function (response) {
                resolve(response);
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (tambahjson):", status, error, xhr.responseText);
                try {
                    const errResponse = JSON.parse(xhr.responseText);
                    reject(new Error(`AJAX Error (tambahjson): ${status} - ${error}. Server: ${errResponse.error || xhr.responseText}`));
                } catch (e) {
                    reject(new Error(`AJAX Error (tambahjson): ${status} - ${error}. Response: ${xhr.responseText}`));
                }
            }
        });
    });
}

/**
 * Mengirim data JSON untuk perubahan record ke crud.php.
 * @param {string} table - Nama tabel database.
 * @param {Object} jsonData - Objek data yang akan diubah.
 * @param {*} id - ID record yang akan diubah.
 * @param {string} ff - Field filter tambahan (opsional).
 * @returns {Promise<Object>} Promise yang resolve dengan objek respons.
 */
function rubahjson(table, jsonData, id, ff) {
    return new Promise((resolve, reject) => {
        let jsonDataString = JSON.stringify(jsonData);
        jsonDataString = jsonDataString.replace(/"top":/g, '"`top`":').replace(/"left":/g, '"`left`":');
        jsonDataString = jsonDataString.replace(/:null/g, ':""');

        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: {
                action: 'rubahjson',
                table: table,
                jsonData: jsonDataString,
                id: id,
                ff: ff,
                xbrand: window.xbrand,
                xcab: window.xcab
            },
            dataType: 'json',
            success: function (response) {
                resolve(response);
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (rubahjson):", status, error, xhr.responseText);
                try {
                    const errResponse = JSON.parse(xhr.responseText);
                    reject(new Error(`AJAX Error (rubahjson): ${status} - ${error}. Server: ${errResponse.error || xhr.responseText}`));
                } catch (e) {
                    reject(new Error(`AJAX Error (rubahjson): ${status} - ${error}. Response: ${xhr.responseText}`));
                }
            }
        });
    });
}

/**
 * Mengambil record berdasarkan range nilai field dari crud.php.
 * @param {string} table - Nama tabel database.
 * @param {string} field - Nama kolom untuk filter.
 * @param {*} value1 - Nilai awal range.
 * @param {*} value2 - Nilai akhir range.
 * @returns {Promise<Object[]|Object>} Promise yang resolve dengan array objek data atau objek error.
 */
function ambil(table, field, value1, value2) {
    
    return new Promise((resolve, reject) => {
        const finalValue2 = (value2 === undefined || value2 === null) ? value1 : value2;

        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: {
                action: 'ambil',
                table: table,
                field: field,
                value: [value1, finalValue2],
                xbrand: window.xbrand,
                xcab: window.xcab
            },
            dataType: 'json',
            success: function (response) {
                resolve(response);
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (ambil):", status, error, xhr.responseText);
                try {
                    const errResponse = JSON.parse(xhr.responseText);
                    reject(new Error(`AJAX Error (ambil): ${status} - ${error}. Server: ${errResponse.error || xhr.responseText}`));
                } catch (e) {
                    reject(new Error(`AJAX Error (ambil): ${status} - ${error}. Response: ${xhr.responseText}`));
                }
            }
        });
    });
}

/**
 * Mengambil record terakhir berdasarkan field dari crud.php.
 * @param {string} table - Nama tabel database.
 * @param {string} field - Nama kolom untuk pengurutan.
 * @param {*} [value1=''] - Opsional: Nilai filter tambahan (sesuai implementasi PHP).
 * @param {*} [value2=''] - Opsional: Nilai filter tambahan (sesuai implementasi PHP).
 * @returns {Promise<Object[]|Object>} Promise yang resolve dengan array objek data atau objek error.
 */
async function updateMassal(tableName, dataToUpdate, whereField, whereValue) {
    try {
        const response = await $.ajax({
            url: 'crud.php',
            type: 'POST',
            data: {
                action: 'update_massal',
                tabel: tableName,
                data: JSON.stringify(dataToUpdate),
                where_field: whereField,
                where_value: whereValue,
                xbrand: window.xbrand,
                xcab: window.xcab
            },
            dataType: 'json'
        });
        return response;
    } catch (error) {
        console.error('AJAX Error in updateMassal:', error);
        return { success: false, error: 'AJAX Error: ' + error.statusText };
    }
}

function ambilakhir(table, field, value1 = '', value2 = '') {
    return new Promise((resolve, reject) => {
        let postData = {
            action: 'ambilakhir',
            table: table,
            field: field,
            xbrand: window.xbrand,
            xcab: window.xcab
        };
        if (value1 !== undefined && value1 !== null && value1 !== '') {
            postData.value = [value1, value2];
        }

        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: postData,
            dataType: 'json',
            success: function (response) {
                resolve(response);
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (ambilakhir):", status, error, xhr.responseText);
                try {
                    const errResponse = JSON.parse(xhr.responseText);
                    reject(new Error(`AJAX Error (ambilakhir): ${status} - ${error}. Server: ${errResponse.error || xhr.responseText}`));
                } catch (e) {
                    reject(new Error(`AJAX Error (ambilakhir): ${status} - ${error}. Response: ${xhr.responseText}`));
                }
            }
        });
    });
}

/**
 * Mengambil record pertama berdasarkan field dari crud.php.
 * @param {string} table - Nama tabel database.
 * @param {string} field - Nama kolom untuk pengurutan.
 * @returns {Promise<Object[]|Object>} Promise yang resolve dengan array objek data atau objek error.
 */
function ambilawal(table, field) {
    return new Promise((resolve, reject) => {
        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: {
                action: 'ambilawal',
                table: table,
                field: field,
                xbrand: window.xbrand,
                xcab: window.xcab
            },
            dataType: 'json',
            success: function (response) {
                resolve(response);
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (ambilawal):", status, error, xhr.responseText);
                try {
                    const errResponse = JSON.parse(xhr.responseText);
                    reject(new Error(`AJAX Error (ambilawal): ${status} - ${error}. Server: ${errResponse.error || xhr.responseText}`));
                } catch (e) {
                    reject(new Error(`AJAX Error (ambilawal): ${status} - ${error}. Response: ${xhr.responseText}`));
                }
            }
        });
    });
}

/**
 * Mengambil record berikutnya berdasarkan field dari crud.php.
 * @param {string} table - Nama tabel database.
 * @param {string} field - Nama kolom untuk pengurutan.
 * @param {*} cari - Nilai dari field record saat ini.
 * @returns {Promise<Object[]|Object>} Promise yang resolve dengan array objek data atau objek error.
 */
function berikut(table, field, cari) {
    return new Promise((resolve, reject) => {
        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: {
                action: 'berikut',
                table: table,
                field: field,
                cari: cari,
                xbrand: window.xbrand,
                xcab: window.xcab
            },
            dataType: 'json',
            success: function (response) {
                resolve(response);
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (berikut):", status, error, xhr.responseText);
                try {
                    const errResponse = JSON.parse(xhr.responseText);
                    reject(new Error(`AJAX Error (berikut): ${status} - ${error}. Server: ${errResponse.error || xhr.responseText}`));
                } catch (e) {
                    reject(new Error(`AJAX Error (berikut): ${status} - ${error}. Response: ${xhr.responseText}`));
                }
            }
        });
    });
}

/**
 * Mengambil record sebelumnya berdasarkan field dari crud.php.
 * @param {string} table - Nama tabel database.
 * @param {string} field - Nama kolom untuk pengurutan.
 * @param {*} cari - Nilai dari field record saat ini.
 * @returns {Promise<Object[]|Object>} Promise yang resolve dengan array objek data atau objek error.
 */
function sebelum(table, field, cari) {
    return new Promise((resolve, reject) => {
        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: {
                action: 'sebelum',
                table: table,
                field: field,
                cari: cari,
                xbrand: window.xbrand,
                xcab: window.xcab
            },
            dataType: 'json',
            success: function (response) {
                resolve(response);
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (sebelum):", status, error, xhr.responseText);
                try {
                    const errResponse = JSON.parse(xhr.responseText);
                    reject(new Error(`AJAX Error (sebelum): ${status} - ${error}. Server: ${errResponse.error || xhr.responseText}`));
                } catch (e) {
                    reject(new Error(`AJAX Error (sebelum): ${status} - ${error}. Response: ${xhr.responseText}`));
                }
            }
        });
    });
}

/**
 * Mengirim query SELECT kustom ke crud.php.
 * @param {string} sql_query - Query SQL lengkap.
 * @returns {Promise<Object[]|Object>} Promise yang resolve dengan array objek hasil query atau objek error.
 */
function ambil_select(sql_query) {
    return new Promise((resolve, reject) => {
        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: {
                action: 'ambil_select',
                sql: sql_query
            },
            dataType: 'json',
            success: function (response) {
                resolve(response);
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (ambil_select):", status, error, xhr.responseText);
                try {
                    const errResponse = JSON.parse(xhr.responseText);
                    reject(new Error(`AJAX Error (ambil_select): ${status} - ${error}. Server: ${errResponse.error || xhr.responseText}`));
                } catch (e) { // Tambahkan kurung kurawal pembuka
                    reject(new Error(`AJAX Error (ambil_select): ${status} - ${error}. Response: ${xhr.responseText}`));
                } // Tambahkan kurung kurawal penutup
            } // Penutup error: function
        }); // Penutup $.ajax
    }); // Penutup new Promise
}

/**
 * Fungsi pencarian autocomplete untuk digunakan di form dan grid.
 * @param {string} query - Keyword pencarian.
 * @param {Function} callback - Callback untuk memproses hasil.
 * @param {string} table - Nama tabel untuk pencarian.
 * @param {string} field1 - Nama kolom pertama untuk pencarian/tampilan.
 * @param {string} field2 - Nama kolom kedua untuk pencarian/tampilan.
 */
function searchAutocomplete(query, callback, table, field1, field2) {

    $.ajax({
        type: 'POST',
        url: 'crud.php',
        data: {
            action: 'searchflexi',
            tabel: table,
            keyword: query,
            field1: field1,
            field2: field2,
            xbrand: window.xbrand,
            xcab: window.xcab
        },
        dataType: 'json',
        success: function (response) {
            const results = response;
            if (results && results.error) {
                console.error('Autocomplete API error:', results.error);
                callback(['Error API']);
                return;
            }
            if (Array.isArray(results)) {
                const formattedResults = results.map(item => {
                    if (!item || typeof item !== 'object' || !item[field1]) return 'Data tidak lengkap'; // Tambahkan pengecekan item
                    return `${item[field1]}${field2 && item[field2] ? ' _ ' + item[field2] : ''}`;
                });
                callback(formattedResults.length > 0 ? formattedResults : ['No Results']);
            } else {
                console.error('Autocomplete API response is not an array:', results);
                callback(['Invalid Response']);
            }
        },
        error: function (xhr, status, error) {
            console.error('Autocomplete AJAX error:', status, error, xhr.responseText);
            callback(['AJAX Error']);
        }
    });
}


// BARU: Fungsi untuk mendapatkan nomor seri berikutnya
/**
 * Mendapatkan nomor seri berikutnya dari server.
 * @param {string} tableName - Nama tabel.
 * @param {string} fieldName - Nama kolom field noseri.
 * @param {string} prefix - Prefix yang sudah di-generate (misal 'A00125').
 * @param {number} numericLength - Panjang bagian numerik (jumlah angka 9).
 * @returns {Promise<Object>} Promise yang resolve dengan objek respons dari server {success: boolean, new_serial_number?: string, error?: string}.
 */
function dapatkanNomorSeriBerikutnya(tableName, fieldName, prefix, numericLength) {
    return new Promise((resolve, reject) => {
        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: {
                action: 'get_next_serial_number',
                table_name: tableName,
                field_name: fieldName,
                prefix: prefix,
                numeric_length: numericLength,
                xbrand: window.xbrand, // Sertakan jika diperlukan oleh backend untuk konteks
                xcab: window.xcab     // Sertakan jika diperlukan oleh backend untuk konteks
            },
            dataType: 'json',
            success: function (response) {
                resolve(response);
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (dapatkanNomorSeriBerikutnya):", status, error, xhr.responseText);
                try {
                    const errResponse = JSON.parse(xhr.responseText);
                    reject(new Error(`AJAX Error (dapatkanNomorSeriBerikutnya): ${status} - ${error}. Server: ${errResponse.error || xhr.responseText}`));
                } catch (e) {
                    reject(new Error(`AJAX Error (dapatkanNomorSeriBerikutnya): ${status} - ${error}. Response: ${xhr.responseText}`));
                }
            }
        });
    });
}


function uploadFormImage(tableName, recordId, sequence, file) {
    return new Promise((resolve, reject) => {
        const formData = new FormData();
        formData.append('action', 'upload_form_image');
        formData.append('table_name', tableName);
        formData.append('record_id', recordId);
        formData.append('sequence', sequence);
        formData.append('file', file); // 'file' harus cocok dengan key di $_FILES['file'] PHP
        formData.append('xbrand', window.xbrand); // Sertakan jika diperlukan
        formData.append('xcab', window.xcab);     // Sertakan jika diperlukan

        $.ajax({
            type: "POST",
            url: BASE_URL + "crud.php",
            data: formData,
            processData: false, // Penting untuk FormData
            contentType: false, // Penting untuk FormData
            dataType: 'json',
            success: function (response) {
                resolve(response);
            },
            error: function (xhr, status, error) {
                console.error("AJAX Error (uploadFormImage):", status, error, xhr.responseText);
                try {
                    const errResponse = JSON.parse(xhr.responseText);
                    reject(new Error(`AJAX Error (uploadFormImage): ${status} - ${error}. Server: ${errResponse.message || errResponse.error || xhr.responseText}`));
                } catch (e) {
                    reject(new Error(`AJAX Error (uploadFormImage): ${status} - ${error}. Response: ${xhr.responseText}`));
                }
            }
        });
    });
}



// =====================================================================
// GLOBAL EXPORTS
// =====================================================================
window.hapus = hapus;
window.tambahjson = tambahjson;
window.rubahjson = rubahjson;
window.ambil = ambil;
window.ambilakhir = ambilakhir;
window.ambilawal = ambilawal;
window.berikut = berikut;
window.sebelum = sebelum;
window.ambil_select = ambil_select;
window.searchAutocomplete = searchAutocomplete;
window.dapatkanNomorSeriBerikutnya = dapatkanNomorSeriBerikutnya; // BARU
window.uploadFormImage = uploadFormImage; // BARU
window.getPrintLayout = getPrintLayout;
window.savePrintLayout = savePrintLayout;
window.updateMassal = updateMassal;