<?php

class UtilMysql
{

    // Update a unique field in a table 
    public static function updateField($conexion, $table, $id, $fieldName, $fieldValue)
    {
        try {
            // Log para depurar el valor de la tabla
            // error_log("Tabla recibida: " . $table);
		    $info = '';
		    $info .= '------- table: '.  $table;
		    $info .= ' id: ' . $id;
		    $info .= ' fieldName: ' . $fieldName;
		    $info .= ' fieldValue: ' . $fieldValue;
            
	        Tools::debugTXT( $info );

            // Encapsular 'from' y 'to' en comillas invertidas
            if ($fieldName === 'from' || $fieldName === 'to') {
                $fieldName = "`$fieldName`";
            }

            // Forzar el valor a int si es el campo 'israin' o si debería ser un booleano !!!!!!
            if ($fieldName === '`israin`' || is_bool($fieldValue) || $fieldValue === '0' || $fieldValue === '1') {
                $fieldValue = (int)$fieldValue;
            }

            $sql = "UPDATE $table SET $fieldName = ? WHERE id = ?";
            // error_log("Consulta SQL: " . $sql); // Log para depurar la consulta SQL
	        Tools::debugTXT("------- " . $sql);


            $stmt = $conexion->prepare($sql);
            if (!$stmt) {
                throw new Exception('Error en la preparación de la consulta SQL: ' . $conexion->error);
            }
    
            // check fieldValue type
            if (is_bool($fieldValue) || $fieldValue === 0 || $fieldValue === 1)   {
                $stmt->bind_param("ii", $fieldValue, $id); // Booleano o TINYINT        
            }
            else if (is_numeric($fieldValue))       {
                $stmt->bind_param("ii", $fieldValue, $id); // Si el valor es numérico
            } 
            else       {
                $stmt->bind_param("si", $fieldValue, $id); // Si el valor es una cadena
            }
        
            if (!$stmt->execute()) {
                throw new Exception('Error: ' . $stmt->error);
            }
        
            $stmt->close();

    	    Tools::debugTXT("------- ok");
            return true;        
        }
        catch (mysqli_sql_exception $e) {
            // Manejar el error de la base de datos
            error_log("Error de SQL: " . $e->getMessage());  // Puedes guardar el error en el log
            throw new Exception("Hubo un probfflema con la base de datos. Por favor, intenta más tarde." . $sql .  $e->getMessage() );
        }        
    }


    public static function acumularHorasYMinutos($total, $nuevoTiempo)
    {
        // Separar las horas y minutos del total
        list($totalHoras, $totalMinutos) = explode(':', $total);
        
        // Separar las horas y minutos del nuevo tiempo
        list($nuevasHoras, $nuevosMinutos) = explode(':', $nuevoTiempo);
    
        // Convertir todo a minutos
        $totalMinutos += ($totalHoras * 60);  // Convertir horas a minutos
        $nuevoMinutos = ($nuevasHoras * 60) + $nuevosMinutos;  // Convertir el nuevo tiempo a minutos
    
        // Sumar los minutos totales
        $totalMinutos += $nuevoMinutos;
    
        // Convertir el total acumulado de minutos a horas y minutos
        $horasFinales = floor($totalMinutos / 60);
        $minutosFinales = $totalMinutos % 60;
    
        // Formatear el resultado en HH:MM
        return str_pad($horasFinales, 2, "0", STR_PAD_LEFT) . ':' . str_pad($minutosFinales, 2, "0", STR_PAD_LEFT);
    }



    // Calcula un time x un multiplicador
    public static function multiplicaTime($tiempo, $multi)
    {
        // Separar las horas y minutos del tiempo dado
        list($horas, $minutos) = explode(':', $tiempo);
    
        // Convertir todo a minutos
        $totalMinutos = ($horas * 60) + $minutos;
    
        // Multiplicar el total de minutos por el multiplicador
        $totalMinutos *= $multi;
    
        // Convertir el total acumulado de minutos a horas y minutos
        $horasFinales = floor($totalMinutos / 60);
        $minutosFinales = round($totalMinutos % 60); // Redondear los minutos

        // Asegurar que el formato sea HH:MM con ceros a la izquierda
        return str_pad($horasFinales, 2, "0", STR_PAD_LEFT) . ':' . str_pad($minutosFinales, 2, "0", STR_PAD_LEFT);
    }


    public static function diferenciaTime($horaInicio, $horaFin)
    {
//        Tools::debugTXT("horainicio" + $horaInicio);
//        Tools::debugTXT("horafin" + $horaFin);
        // Convertir las horas a objetos DateTime
        $inicio = DateTime::createFromFormat('H:i:s', $horaInicio);
        $fin = DateTime::createFromFormat('H:i:s', $horaFin);
    
        if (!$inicio || !$fin) {
            throw new Exception("Formato de hora inválido");
        }
    
        // Si la hora de inicio es mayor que la hora de fin, significa que cruzamos la medianoche
        if ($inicio > $fin) {
            $fin->modify('+1 day'); // Sumar un día a la hora de fin
        }    
            
        // Calcular la diferencia
        $diferencia = $inicio->diff($fin);
    
        // Formatear la diferencia en HH:MM
        $horas = str_pad($diferencia->h, 2, "0", STR_PAD_LEFT);
        $minutos = str_pad($diferencia->i, 2, "0", STR_PAD_LEFT);
    
 //    Tools::debugTXT("horas" + $horas);
 //        Tools::debugTXT("minutos" + $minutos);
       return "$horas:$minutos";
    }


    // Calcula los totales de un formulario, y devolvemos la respuesta en json
    // se usa cuando modificamos una campo sobre el cual tb queremos realizar algun cálculo
    public static function updateTotals($allModels, $idFormCrv)
    {
        if ($idFormCrv == null)
        {
            header('Content-Type: application/json');
            echo json_encode(['success' => false, 'message' => 'idform no proporcionado.']);
        }

        // calcula los totales de craneCharges
        $craneCharges = $allModels['form_crv_craneCharges']->selectAll($idFormCrv);
        $total_straight_craneCharges = "00:00";
        $total_overtime_craneCharges = "00:00";
        $total_nunmoves_craneCharges = 0;
        $total_lids_craneCharges = 0;
    
        foreach ($craneCharges as $row)
        {
           $total_straight_craneCharges  = UtilMysql::acumularHorasYMinutos($total_straight_craneCharges, $row['straight']);
           $total_overtime_craneCharges  = UtilMysql::acumularHorasYMinutos($total_overtime_craneCharges, $row['overtime']);
           $total_nunmoves_craneCharges    += $row['nunmoves'];
           $total_lids_craneCharges      += $row['lids'];
        }
    
        // calcula los totales de delay times
        $delaytimes = $allModels['form_crv_delaytimes']->selectAll($idFormCrv);
        $total_straight_delaytimes = 0;
        $total_overtime_delaytimes = 0;
        
        foreach ($delaytimes as $row)
        {
            $total_straight_delaytimes  = $total_straight_delaytimes + $row['straightminutes'];
            $total_overtime_delaytimes  = $total_overtime_delaytimes + $row['overtimeminutes'];
        }

        // calcula los totales de crane start-up & security charges
        $craneStartup = $allModels['form_crv_craneStartup']->selectAll($idFormCrv);
        $total_start    = "00:00";
        $total_secure   = "00:00";
        $total_duration_craneStartup = "00:00";
        
        foreach ($craneStartup as $row)
        {
           $total_start  = UtilMysql::acumularHorasYMinutos($total_start, $row['start']);
           $total_secure = UtilMysql::acumularHorasYMinutos($total_secure, $row['secure']);

           // new 17/07/2025
           $duration       = UtilMysql::diferenciaTime($row['start'], $row['secure']);
           $total_duration_craneStartup = UtilMysql::acumularHorasYMinutos( $total_duration_craneStartup, $duration );
        }


        // calcula los totales de standby for vessel arrival, standby for rain
        $others    = $allModels['form_crv_others']->select_byId_form($idFormCrv);
        $diff_standby_arrival_hrs       = UtilMysql::diferenciaTime($others['standby_arrival_from_hrs'], $others['standby_arrival_to_hrs']);
        $total_standby_arrival_straight = UtilMysql::multiplicaTime($others['standby_arrival_straight_hrs'], $others['standby_arrival_straight_crane']);
        $total_standby_arrival_overtime = UtilMysql::multiplicaTime($others['standby_arrival_overtime_hrs'], $others['standby_arrival_overtime_crane']);

        $diff_standby_rain_hrs          = UtilMysql::diferenciaTime($others['standby_rain_from_hrs'], $others['standby_rain_to_hrs']);
        $total_standby_rain_straight    = UtilMysql::multiplicaTime($others['standby_rain_straight_hrs'], $others['standby_rain_straight_crane']);
        $total_standby_rain_overtime    = UtilMysql::multiplicaTime($others['standby_rain_overtime_hrs'], $others['standby_rain_overtime_crane']);

        $diff_prevailing_hrs            = UtilMysql::diferenciaTime($others['prevailing_from_hrs'], $others['prevailing_to_hrs']);
        $diff_balance_hrs               = UtilMysql::diferenciaTime($others['balance_from_hrs'], $others['balance_to_hrs']);
        $diff_misc_hrs                  = UtilMysql::diferenciaTime($others['misc_from_hrs'], $others['misc_to_hrs']);

        // response
            header('Content-Type: application/json');
            echo json_encode
            ([
                'success' => true,
                'data' => [
                    'total_straight_cranecharges'  => $total_straight_craneCharges,
                    'total_overtime_cranecharges'  => $total_overtime_craneCharges,
                    'total_nunmoves_cranecharges'  => $total_nunmoves_craneCharges,
                    'total_lids_cranecharges'      => $total_lids_craneCharges,

                    'total_straight_delaytimes'    => $total_straight_delaytimes,
                    'total_overtime_delaytimes'    => $total_overtime_delaytimes,

                    'total_start'        => $total_start,
                    'total_secure'       => $total_secure,
                    'total_duration_craneStartup'     => $total_duration_craneStartup,

                    'diff_standby_arrival_hrs'        => $diff_standby_arrival_hrs,
                    'total_standby_arrival_straight'  => $total_standby_arrival_straight,
                    'total_standby_arrival_overtime'  => $total_standby_arrival_overtime,

                    'diff_standby_rain_hrs'        => $diff_standby_rain_hrs,
                    'total_standby_rain_straight'  => $total_standby_rain_straight,
                    'total_standby_rain_overtime'  => $total_standby_rain_overtime,

                    'diff_prevailing_hrs'          => $diff_prevailing_hrs,
                    'diff_balance_hrs'             => $diff_balance_hrs,
                    'diff_misc_hrs'                => $diff_misc_hrs
                ],
            ]);
    }


} 
?>