package database

import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.tinylog.Logger
import java.sql.Connection

@Suppress("unused", "SqlDialectInspection", "SqlSourceToSinkFlow")
abstract class dbFunctions<T>(val dbName: String, val connection: Connection) {
    var List : ArrayList<T> = ArrayList()

    /**
     * Clear all entries in the table
     * @return true if successful, false otherwise
     */
    open fun Clear() : Boolean{
        try {
            val statement = connection.createStatement()
            // use TRUNCATE to reset auto increment index
            statement?.executeUpdate("TRUNCATE TABLE $dbName")
            Logger.info("$dbName table cleared" as Any)
            List.clear()
            return true
        } catch (e: Exception) {
            Logger.error("Error clearing $dbName table: ${e.message}" as Any)
        }
        return false
    }

    /**
     * Delete entry by index
     * @param index The index of the entry to delete
     * @return true if successful, false otherwise
     */
    open fun DeleteByIndex(index: Int) : Boolean{
        try {
            val statement = connection.prepareStatement("DELETE FROM $dbName WHERE `index` = ?")
            statement?.setLong(1, index.toLong())
            val rowsAffected = statement?.executeUpdate()
            if (rowsAffected != null && rowsAffected > 0) {
                Logger.info("Deleted $rowsAffected row(s) from $dbName with index $index" as Any)
                return true
            } else {
                Logger.warn("No rows deleted from $dbName with index $index" as Any)
            }
        } catch (e: Exception) {
            Logger.error("Error deleting from $dbName with index $index: ${e.message}" as Any)
        }
        return false
    }

    /**
     * Create the table if it does not exist
     */
    abstract fun Create()

    protected fun Create(tableDefinition: String) {
        try {
            val statement = connection.createStatement()
            statement?.executeUpdate(tableDefinition)
            Logger.info("$dbName table ensured to exists" as Any)
        } catch (e: Exception) {
            Logger.error("Error creating $dbName table: ${e.message}" as Any)
        }
    }

    /**
     * Get all entries from the table and populate the List
     */
    abstract fun Get()

    /**
     * Add a new entry to the table
     * @param data The data to add
     * @return true if successful, false otherwise
     */
    abstract fun Add(data: T): Boolean

    /**
     * Add multiple entries to the table
     * @param data The list of data to add
     * @return true if successful, false otherwise
     */
    abstract fun AddAll(data: ArrayList<T>): Boolean

    /**
     * Update an existing entry by index
     * @param index The index of the entry to update
     * @param data The new data
     * @return true if successful, false otherwise
     */
    abstract fun UpdateByIndex(index: Int, data: T): Boolean
    abstract fun Resort(): Boolean

    /**
     * Import the table from XLSX format
     * @param workbook The XSSFWorkbook object to import from
     * @return true if successful, false otherwise
     */
    abstract fun Import_XLSX(workbook: XSSFWorkbook) : Boolean

    /**
     * Export the table to XLSX format
     * @return XSSFWorkbook object if successful, null otherwise
     */
    abstract fun Export_XLSX() : XSSFWorkbook?
}