package mx.gob.jumapacelaya.services;

import mx.gob.jumapacelaya.models.*;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OraclePreparedStatement;
import oracle.sql.CLOB;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.security.interfaces.RSAKey;
import java.sql.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@Service
public class DatabaseService {


    @Value("${db.url}")
    private String dbUrl;
    @Value("${db.user}")
    private String dbUser;
    @Value("${db.pass}")
    private String dbPass;

    private Connection getMysqlConnection() throws SQLException {
        return DriverManager.getConnection(dbUrl, dbUser, dbPass);
    }

    /*private Connection getOracleConnection() throws SQLException {
        String url = "jdbc:oracle:thin:@//svradminfinan:1521/admfinpdb.JUMAPACELAYA.GOB.MX";
        String user = "Finanzas";
        String pass = "finanzas";

        return DriverManager.getConnection(url, user, pass);

    }*/

    // Método para obtener los tipos de mantenimientos
    public List<TiposMantenimiento> getTiposDeMantenimientos() {
        List<TiposMantenimiento> tiposDeMantenimientos = new ArrayList<>();
        String query = "SELECT tipomantid, nombre FROM TIPOMANT";

        try (Connection connection = getMysqlConnection();
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(query)) {

            while (resultSet.next()) {
                TiposMantenimiento tipo = new TiposMantenimiento(
                        resultSet.getString("tipomantid"),
                        resultSet.getString("nombre")
                );
                tiposDeMantenimientos.add(tipo);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return tiposDeMantenimientos;
    }

    // Método para obtener las nomenclaturas
    public String getNomenclatura(String tipoMantenimiento) {
        String nomenclatura = "";
        String query = "SELECT nomenclatura FROM TIPOMANT where TIPOMANTID = ?";

        try (Connection connection = getMysqlConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(query)) {
            preparedStatement.setString(1, tipoMantenimiento);

            try (ResultSet resultSet = preparedStatement.executeQuery()) {
                if (resultSet.next()) {
                    nomenclatura = resultSet.getString("nomenclatura");
                }
            }

        } catch (SQLException e) {
            e.printStackTrace();
            System.err.println("Error al obtener nomenclatura: " + e.getMessage());
        }
        return nomenclatura;
    }


    /* -------------- Metodo para obtener a los usuarios ---------------- */
    public List<Usuario> getUsuarios() {
        List<Usuario> usuarios = new ArrayList<>();
        String query = "SELECT u.* \n" +
                "FROM USUARIOS u";

        try (Connection connection = getMysqlConnection();
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(query)) {

            while (resultSet.next()) {
                Usuario usuario = new Usuario(
                        resultSet.getString("empleadoid"),
                        resultSet.getString("nombre"),
                        resultSet.getString("email")
                );
                usuarios.add(usuario);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return usuarios;
    }


    /* -------------- Metodo para obtener los departamentos ---------------- */
    public List<DepartamentosModel> getDepartamentos() {
        List<DepartamentosModel> departamentos = new ArrayList<>();
        String query = "select DEPARTAMENTOID, DESCRIPCION from DEPARTAMENTOS";

        try (Connection connection = getMysqlConnection();
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(query)) {

            while (resultSet.next()) {
                DepartamentosModel departamentosModel = new DepartamentosModel(
                        resultSet.getString("departamentoid"),
                        resultSet.getString("descripcion")
                );
                departamentos.add(departamentosModel);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return departamentos;
    }


    /* -------------- Metodo para obtener los tipos de hardware ---------------- */
    public List<TiposHardware> getTiposHardware() {
        List<TiposHardware> tiposHardware = new ArrayList<>();
        String query = "select TIPOHARDWAREID, DESCRIPCION from TIPOSHARDWARE";

        try (Connection connection = getMysqlConnection();
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(query)) {

            while (resultSet.next()) {
                TiposHardware tiposHardwareModel = new TiposHardware(
                        resultSet.getString("tipohardwareid"),
                        resultSet.getString("descripcion")
                );
                tiposHardware.add(tiposHardwareModel);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return tiposHardware;
    }



    /* ----------------Obtener el Plan Anual de Mantenimiento ---------------- */
    public List<PlanAnual> getPlanAnual() {
        List<PlanAnual> planAnualList = new ArrayList<>();
        String query = "SELECT p.plananualid, p.nomEquipo, p.area, \r\n" + //
                        "       p.monitor, p.teclado, p.mouse, p.regulador, \r\n" + //
                        "       p.cpu, p.impresora, p.miniPrint, p.laptop, p.escaner, \r\n" + //
                        "       p.fechaprog, m.fecha AS fechaMantenimiento, \r\n" + //
                        "       p.tecnicosmt, p.estado\r\n" + //
                        "FROM PLANANUAL p\r\n" + //
                        "LEFT JOIN MANTENIMIENTOS m ON p.plananualid = m.plananualid\r\n" + //
                        "ORDER BY p.plananualid ASC";

        try (Connection connection = getMysqlConnection();
            Statement statement = connection.createStatement();
            ResultSet resultSet = statement.executeQuery(query)) {

            while (resultSet.next()) {
                PlanAnual planAnual = new PlanAnual(
                        resultSet.getInt("plananualid"),
                        resultSet.getString("nomEquipo"),
                        resultSet.getString("area"),
                        resultSet.getBoolean("monitor"),
                        resultSet.getBoolean("teclado"),
                        resultSet.getBoolean("mouse"),
                        resultSet.getBoolean("regulador"),
                        resultSet.getBoolean("cpu"),
                        resultSet.getBoolean("impresora"),
                        resultSet.getBoolean("miniPrint"),
                        resultSet.getBoolean("laptop"),
                        resultSet.getBoolean("escaner"),
                        resultSet.getDate("fechaprog").toLocalDate(), // Cambiado a LocalDate
                        resultSet.getDate("fechaMantenimiento") != null ? resultSet.getDate("fechaMantenimiento").toLocalDate() : null, // Cambiado a LocalDate
                        resultSet.getString("tecnicosmt"),
                        resultSet.getString("estado")
                );
                planAnualList.add(planAnual);
            }
            System.out.println("Registros obtenidos: " + planAnualList.size());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return planAnualList;
    }



     /* ----------------Obtener detalles del mantenimiento ---------------- */
    public DetalleMantenimientoModel getDetalleMantenimientoPorPlanAnualId(int planAnualId) {
        String query = "SELECT\r\n" + //
                        "\tm.MANTENIMIENTOID ID, p.PLANANUALID, t.NOMBRE TIPO,\r\n" + //
                        "\td.DESCRIPCION DEPARTAMENTO, u.NOMBRE USUARIO, pa.FECHAPROG,\r\n" + //
                        "\tm.FECHA FECHAREALIZADO, NOMBREEQUIPO, FORMAMANT, FIRMAUSUARIO, FIRMASMT, FIRMAGCIA   \r\n" + //
                        "FROM MANTENIMIENTOS m\r\n" + //
                        "INNER JOIN TIPOMANT t ON m.TIPOMANTID = t.TIPOMANTID\r\n" + //
                        "INNER JOIN DEPARTAMENTOS d ON m.DEPARTAMENTOID = d.DEPARTAMENTOID\r\n" + //
                        "INNER JOIN USUARIOS u ON u.EMPLEADOID  = m.EMPLEADOID\r\n" + //
                        "INNER JOIN PLANANUAL p ON m.PLANANUALID = p.PLANANUALID\r\n" + //
                        "INNER JOIN PLANANUAL pa ON m.PLANANUALID = pa.PLANANUALID \r\n" + //
                        "WHERE p.PLANANUALID = ?";

        try (Connection connection = getMysqlConnection();
            PreparedStatement statement = connection.prepareStatement(query)) {
                
            statement.setInt(1, planAnualId);

            try (ResultSet rs = statement.executeQuery()) {
                if (rs.next()) {
                    return new DetalleMantenimientoModel(
                        rs.getInt("ID"),
                        rs.getInt("PLANANUALID"),
                        rs.getString("TIPO"),
                        rs.getString("DEPARTAMENTO"),
                        rs.getString("USUARIO"),
                        rs.getDate("FECHAPROG").toLocalDate(),
                        rs.getDate("FECHAREALIZADO").toLocalDate(),
                        rs.getString("NOMBREEQUIPO"),
                        rs.getString("FORMAMANT"),
                        rs.getString("FIRMAUSUARIO"),
                        rs.getString("FIRMASMT"),
                        rs.getString("FIRMAGCIA")
                    );
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return null;
    }


     /* ----------------Obtener detalles del hardaware por ID ---------------- */
    public List<HardwareDetalle> getHardwaredetallePorMantId(int mantenimientoId) {
        List<HardwareDetalle> detalles = new ArrayList<>();
        String query = "SELECT  h.MANTENIMIENTOID, h.HARDWAREDETID, t.DESCRIPCION, h.MODELO, h.NUMSERIE, h.PLACA\r\n" + //
                        "FROM HARDWAREDET h\r\n" + //
                        "INNER JOIN TIPOSHARDWARE t ON h.TIPOHARDWAREID = t.TIPOHARDWAREID \r\n" + //
                        "WHERE h.MANTENIMIENTOID = ?";
        
        try (Connection conn = getMysqlConnection();
            PreparedStatement stmt = conn.prepareStatement(query)) {
            
            stmt.setInt(1, mantenimientoId);
            ResultSet rs = stmt.executeQuery();

            while (rs.next()) {
                HardwareDetalle detalle = new HardwareDetalle(
                    rs.getInt("MANTENIMIENTOID"),
                    rs.getInt("HARDWAREDETID"),
                    rs.getString("DESCRIPCION"),
                    rs.getString("MODELO"),
                    rs.getString("NUMSERIE"),
                    rs.getString("PLACA")
                );
                detalles.add(detalle);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
        return detalles;
    }


     /* ---------------- Obtener las actualizaciones de seguridad ---------------- */
    public List<ActualizacioneSeguridadModel> getActualizacionesSeg(int mantenimientoId) {
        List<ActualizacioneSeguridadModel> actualizaciones = new ArrayList<>();
        String query = "SELECT *\r\n" + //
                        "FROM ACTUALIZACIONESSEG a\r\n" + //
                        "WHERE a.MANTENIMIENTOID = ?";
        
        try (Connection conn = getMysqlConnection();
            PreparedStatement stmt = conn.prepareStatement(query)) {

                stmt.setInt(1, mantenimientoId);
                ResultSet rs = stmt.executeQuery();

                while (rs.next()) {
                    ActualizacioneSeguridadModel actualizacion = new ActualizacioneSeguridadModel(
                        rs.getInt("ACTUALIZACIONSEGID"),
                        rs.getString("DESCRIPCION"),
                        rs.getString("OTRASACTUALIZACIONES"),
                        rs.getInt("MANTENIMIENTOID")
                    );
                    actualizaciones.add(actualizacion);
                }

            } catch (SQLException e) {
                e.printStackTrace();
            }
            return actualizaciones;
    }


    /*-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<()*/
    /*-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<()*/
    /*-=iii=<() *-=iii=<() *-=iii=<() *-=iii=<()*/
    /*-=iii=<() *-=iii=<() *-=iii=<()*/
    /*-=iii=<() *-=iii=<()*/
    /* ( ͡° ͜ʖ ͡°) Metodos para insetar en la BD ( ͡° ͜ʖ ͡°) ( ͡° ͜ʖ ͡°) Metodos para insetar en la BD ( ͡° ͜ʖ ͡°) ( ͡° ͜ʖ ͡°) Metodos para insetar en la BD ( ͡° ͜ʖ ͡°) */
    // INSERTAR EN TABLA: MANTENIMINETOS
    public int insertarMantenimiento(LocalDate fecha, String tipoMantId, String departamentoId, String empleadoId,
                                    String formaMant, String equipoId, String userSignatureBase64,
                                    String smtSignatureBase64, String planAnualId) {

        String query = "INSERT INTO MANTENIMIENTOS (fecha, tipoMantId, departamentoId, empleadoId, formaMant, nombreequipo," +
                " firmaUsuario, firmaSmt, planAnualId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING MANTENIMIENTOID INTO ?";

        String updateStatusQuery = "UPDATE PLANANUAL SET estado = 'REALIZADO' WHERE planAnualId = ?";

        int nuevoId = -1;
        Connection connection = null;

        try {
            connection = getMysqlConnection();

            if (connection == null) {
                throw new SQLException("No se pudo establecer la conexion con la base de datos.");
            }


            connection.setAutoCommit(false);

            // Paso 1: primero inserta el mantenimiento
            try (OraclePreparedStatement preparedStatement = (OraclePreparedStatement) connection.prepareStatement(query)) {

                preparedStatement.setDate(1, Date.valueOf(fecha));
                preparedStatement.setLong(2, Long.parseLong(tipoMantId));
                preparedStatement.setString(3, departamentoId);
                preparedStatement.setLong(4, Long.parseLong(empleadoId));
                preparedStatement.setString(5, formaMant);
                preparedStatement.setString(6, equipoId);

                if (userSignatureBase64 != null) {
                    preparedStatement.setString(7, userSignatureBase64);
                } else {
                    preparedStatement.setNull(7, Types.VARCHAR);
                }

                if (smtSignatureBase64 != null) {
                    preparedStatement.setString(8, smtSignatureBase64);
                } else {
                    preparedStatement.setNull(8, Types.VARCHAR);
                }

                preparedStatement.setLong(9, Long.parseLong(planAnualId));

                preparedStatement.registerReturnParameter(10, Types.NUMERIC);

                preparedStatement.executeUpdate();

                ResultSet rs = preparedStatement.getReturnResultSet();
                if (rs != null && rs.next()) {
                    nuevoId = rs.getInt(1);
                }
            }

            // Paso 2: Si se inserto el mantenimiento, se actualiza el estado en MTTOPROGRAMADOS
            if (nuevoId != -1) {
                try (PreparedStatement updateStatement = connection.prepareStatement(updateStatusQuery)) {
                    updateStatement.setString(1, planAnualId);
                    updateStatement.executeUpdate();
                }
            }

            // Confirmar la transaccion si ambos pasos son exitosos
            connection.commit();

        } catch (SQLException e) {
            System.err.println("Error al insertar mantenimiento: " + e.getMessage());
            e.printStackTrace();
            // En caso de error, se hace rollback
            if (connection != null) {
                try {
                    connection.rollback();
                } catch (SQLException rollbackEx) {
                    System.err.println("Error al hacer rollback: " + rollbackEx.getMessage());
                }
            }
        } finally {
            // Cerrar la conexion
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException closeEx) {
                    System.err.println("Error al cerrar la conexion: " + closeEx.getMessage());
                }
            }
        }

        return nuevoId;
    }
    /*( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■)( •_•)>⌐■-■ (⌐■_■) */
    /* ˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀˁ˚ᴥ˚ˀ */

    // INSERTAR EN LA TABLA: HARDWAREDET
    public boolean insertarHardware(String tipoHardwareId, String numSerie, String modelo, String placa, int mantenimientoId) {
        String query = "INSERT INTO HARDWAREDET (tipoHardwareId, numSerie, modelo, placa, mantenimientoId) VALUES (?, ?, ?, ?, ?)";
        boolean isInserted = false;

        try (Connection connection = getMysqlConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(query)) {

            preparedStatement.setInt(1, Integer.parseInt(tipoHardwareId));
            preparedStatement.setString(2, numSerie);
            preparedStatement.setString(3, modelo);
            preparedStatement.setString(4, placa);
            preparedStatement.setInt(5, mantenimientoId);

            int rowsAffected = preparedStatement.executeUpdate();
            isInserted = rowsAffected > 0;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return isInserted;
    }


    public int getUltimoMantenimientoId() {
        int ultimoId = -1;
        try (Connection connection = getMysqlConnection()) {
            String query = "SELECT MAX(mantenimientoid) FROM MANTENIMIENTOS";
            try (PreparedStatement preparedStatement = connection.prepareStatement(query)) {
                ResultSet resultSet = preparedStatement.executeQuery();
                if (resultSet.next()) {
                    ultimoId = resultSet.getInt(1);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return ultimoId;
    }


    // INSERTAR EN LA TABLA: ACTUALIZACIONESSEG
    public boolean insertActualizacionSeg(String descripcion, String otras, int mantenimientoId) {
        String query = "INSERT INTO ACTUALIZACIONESSEG (descripcion, otrasactualizaciones, mantenimientoid) VALUES (?, ?, ?)";

        try (Connection connection = getMysqlConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(query)) {

            preparedStatement.setString(1, descripcion);
            preparedStatement.setString(2, otras);
            preparedStatement.setInt(3, mantenimientoId);

            int rowsInserted = preparedStatement.executeUpdate();
            return rowsInserted > 0;
        } catch (SQLException e) {
            System.err.println("Error al insertar actualizacionSeg: " + e.getMessage());
            return false;
        }
    }


    public void insertarDesdeExcel(InputStream inputStream) {
        String query = "INSERT INTO PLANANUAL (NOMEQUIPO, AREA, MONITOR, TECLADO, MOUSE, " +
                "REGULADOR, CPU, IMPRESORA, MINIPRINT, LAPTOP, ESCANER, FECHAPROG, TECNICOSMT, ESTADO) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

        try (Connection connection = getMysqlConnection();
             //FileInputStream file = new FileInputStream(rutaArchivoExcel);
            Workbook workbook = new XSSFWorkbook(inputStream)) {

            Sheet sheet = workbook.getSheetAt(0); // Primera hoja del archivo Excel

            for (Row row : sheet) {
                if (row.getRowNum() == 0) continue; // Saltar la primera fila si contiene encabezados

                try {
                    // Leer cada celda de la fila según el índice correcto
                    String nomequipo = getStringCellValue(row.getCell(0)); // Columna 1
                    String area = getStringCellValue(row.getCell(1)); // Columna 2
                    boolean monitor = getBooleanCellValue(row.getCell(2)); // Columna 3
                    boolean teclado = getBooleanCellValue(row.getCell(3)); // Columna 4
                    boolean mouse = getBooleanCellValue(row.getCell(4)); // Columna 5
                    boolean regulador = getBooleanCellValue(row.getCell(5)); // Columna 6
                    boolean cpu = getBooleanCellValue(row.getCell(6)); // Columna 7
                    boolean impresora = getBooleanCellValue(row.getCell(7)); // Columna 8
                    boolean miniprint = getBooleanCellValue(row.getCell(8)); // Columna 9
                    boolean laptop = getBooleanCellValue(row.getCell(9)); // Columna 10
                    boolean escaner = getBooleanCellValue(row.getCell(10)); // Columna 11

                    // Leer la fecha de la columna correcta
                    Date fechaprog = getDateCellValue(row.getCell(11)); // Columna 12
                    String tecnicosmt = getStringCellValue(row.getCell(12)); // Columna 13
                    String estado = getStringCellValue(row.getCell(13)); // Columna 14
                    Date fecharealizado = getDateCellValue(row.getCell(14)); // Columna 15

                    // Insertar datos en la base de datos
                    try (PreparedStatement preparedStatement = connection.prepareStatement(query)) {
                        preparedStatement.setString(1, nomequipo);
                        preparedStatement.setString(2, area);
                        preparedStatement.setBoolean(3, monitor);
                        preparedStatement.setBoolean(4, teclado);
                        preparedStatement.setBoolean(5, mouse);
                        preparedStatement.setBoolean(6, regulador);
                        preparedStatement.setBoolean(7, cpu);
                        preparedStatement.setBoolean(8, impresora);
                        preparedStatement.setBoolean(9, miniprint);
                        preparedStatement.setBoolean(10, laptop);
                        preparedStatement.setBoolean(11, escaner);

                        // Manejo de fechas
                        if (fechaprog != null) {
                            preparedStatement.setDate(12, new java.sql.Date(fechaprog.getTime()));
                        } else {
                            preparedStatement.setNull(12, java.sql.Types.DATE); // Manejo de valor nulo
                        }

                        preparedStatement.setString(13, tecnicosmt);
                        preparedStatement.setString(14, estado);

                        preparedStatement.executeUpdate();
                    }
                } catch (Exception e) {
                    System.err.println("Error procesando la fila " + row.getRowNum() + ": " + e.getMessage());
                }
            }

            System.out.println("Datos insertados desde Excel con éxito en PLANANUAL.");
        } catch (IOException e) {
            System.err.println("Error al leer el archivo Excel: " + e.getMessage());
        } catch (SQLException e) {
            System.err.println("Error al insertar datos en la BD: " + e.getMessage());
        }
    }

    // Método auxiliar para obtener un valor de tipo Date de una celda
    private Date getDateCellValue(Cell cell) {
        if (cell != null) {
            switch (cell.getCellType()) {
                case NUMERIC:
                    return new Date(cell.getDateCellValue().getTime()); // Retorna la fecha directamente
                case STRING:
                    try {
                        return Date.valueOf(LocalDate.parse(cell.getStringCellValue().trim())); // Asume formato ISO
                    } catch (Exception e) {
                        System.err.println("No se puede convertir la cadena a fecha: " + cell.getStringCellValue());
                    }
                    break;
                case BLANK:
                    return null; // Devuelve null si la celda está vacía
                default:
                    System.err.println("Tipo de celda inesperado en la fila " + cell.getRowIndex());
                    break;
            }
        }
        return null; // Retorna null si no se puede obtener una fecha
    }

    // Método auxiliar para obtener un valor de tipo String de una celda
    private String getStringCellValue(Cell cell) {
        if (cell != null) {
            switch (cell.getCellType()) {
                case STRING:
                    return cell.getStringCellValue().trim();
                case NUMERIC:
                    return String.valueOf((int) cell.getNumericCellValue()); // Convierte el número a cadena
                default:
                    return ""; // Devuelve cadena vacía si la celda no es de tipo STRING o NUMERIC
            }
        }
        return ""; // Devuelve cadena vacía si la celda es nula
    }

    // Método auxiliar para obtener un valor de tipo boolean de una celda
    private boolean getBooleanCellValue(Cell cell) {
        if (cell != null) {
            switch (cell.getCellType()) {
                case NUMERIC:
                    return cell.getNumericCellValue() != 0; // Considera 0 como false, cualquier otro número como true
                case BOOLEAN:
                    return cell.getBooleanCellValue();
                case STRING:
                    return Boolean.parseBoolean(cell.getStringCellValue().trim()); // Conversión de string a boolean
                default:
                    return false; // Valor por defecto
            }
        }
        return false; // Valor por defecto si la celda es nula
    }


    /* ----------------Actualizar los detalles del del mantenimiento por ID ---------------- */
    public boolean actualizarPlanAnual(int planAnualId, String nombreEquipo, LocalDate fechaProg) {
        String sql = "UPDATE PLANANUAL SET NOMEQUIPO=?, FECHAPROG=? WHERE PLANANUALID=?";
        try (Connection conn = getMysqlConnection();
            PreparedStatement stmt = conn.prepareStatement(sql)) {
                stmt.setString(1, nombreEquipo);
                stmt.setDate(2, fechaProg != null ? Date.valueOf(fechaProg) : null);
                stmt.setInt(3, planAnualId);
                return stmt.executeUpdate() > 0;
            } catch (SQLException e) {
                e.printStackTrace();
                return false;
            }
    }

    public boolean actualizarMantenimiento(int mantenimientoId, int tipoId, String departamentoId, int empleadoId, LocalDate fechaRealizado, String nombreEquipo) {
        String sql = "UPDATE MANTENIMIENTOS SET TIPOMANTID=?, DEPARTAMENTOID=?, EMPLEADOID=?, FECHA=?, NOMBREEQUIPO=? WHERE MANTENIMIENTOID=?";
        try (Connection conn = getMysqlConnection();
        PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setInt(1, tipoId);                // tipoId es int
            stmt.setString(2, departamentoId);     // departamentoId es String
            stmt.setInt(3, empleadoId);            // empleadoId es int
            stmt.setDate(4, fechaRealizado != null ? Date.valueOf(fechaRealizado) : null);
            stmt.setString(5, nombreEquipo);
            stmt.setInt(6, mantenimientoId);
            return stmt.executeUpdate() > 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }


    /* ----------------Actualizar los detalles del hardaware por ID ---------------- */
    public boolean actualizarHardwareDetalle(HardwareDetalle detalle) {
        String sql = "UPDATE HARDWAREDET SET MODELO=?, NUMSERIE=?, PLACA=? WHERE HARDWAREDETID=?";
        try (Connection conn = getMysqlConnection();
            PreparedStatement stmt = conn.prepareStatement(sql)) {
                stmt.setString(1, detalle.getModelo());
                stmt.setString(2, detalle.getNumSerie());
                stmt.setString(3, detalle.getPlaca());
                stmt.setInt(4, detalle.getHardwareDetId());
                return stmt.executeUpdate() > 0;
            } catch (SQLException e) {
                e.printStackTrace();
                return false;
            }
    }


    /* ----------------Actualizar las actualizaciones de seguridad por ID ---------------- */
    public boolean actualizarActualizacionSeg(ActualizacioneSeguridadModel actualizacion) {
        String sql = "UPDATE ACTUALIZACIONESSEG SET OTRASACTUALIZACIONES=? WHERE ACTUALIZACIONSEGID=?";
        try (Connection conn = getMysqlConnection();
            PreparedStatement stmt = conn.prepareStatement(sql)) {
                stmt.setString(1, actualizacion.getOtrasactualizaciones());
                stmt.setInt(2, actualizacion.getActualizacionsegId());
                return stmt.executeUpdate() > 0;
            } catch (SQLException e) {
                e.printStackTrace();
                return false;
            }
    }


    /* ---------------- Insertar en bitacora ---------------- */
    public boolean insertarBitacora(int mantenimientoid, String usuarioid, LocalDate fechora, String motivo) {
        String query = "INSERT INTO BITACORACTUALIZACIONES (MANTENIMIENTOID, USUARIOID, FECHORA, MOTIVO) VALUES (?, ?, ?, ?)";
        try (Connection conn = getMysqlConnection();
            PreparedStatement stmt = conn.prepareStatement(query)) {
                stmt.setInt(1, mantenimientoid);
                stmt.setString(2, usuarioid);
                stmt.setDate(3, fechora != null ? Date.valueOf(fechora) : null);
                stmt.setString(4, motivo);
                return stmt.executeUpdate() > 0;
            } catch (SQLException e) {
                e.printStackTrace();
                return false;
            }
    }
}
