"""General utilisation functions."""

from __future__ import annotations

from datetime import datetime

import numpy as np
import pandas as pd
import torch


def get_current_time() -> str:
    """Get the current time as a string."""
    d = datetime.now()
    return (
        f"{d.year:04d}/"
        f"{d.month:02d}/"
        f"{d.day:02d} "
        f"{d.hour:02d}:"
        f"{d.minute:02d}:"
        f"{d.second:02d} "
        f"{d.microsecond:06d}"
    )


def ts_to_tensor(
    df: pd.DataFrame,
    cols: list[str] | None = None,
) -> torch.FloatTensor:
    """
    Transform the preprocessed dataframe to a PyTorch tensor.

    Parameters
    ----------
    df : pd.DataFrame
        Dataframe to transform
    cols: list[str], Optional
        Columns to transform from the dataframe, all columns are used if None
    stack_ts: bool, Optional
        Stack timeseries instead of concatenating them

    Returns
    -------
    torch.FloatTensor
        Transformed dataframe in torch.FloatTensor format
    """
    arr = df[cols if cols else df.columns].to_numpy()
    return torch.FloatTensor(np.asarray([np.vstack(x).T for x in arr]))  # N, L, F


def sc_to_tensor(
    df: pd.DataFrame,
    cols: list[str] | None = None,
) -> torch.FloatTensor:
    """Transform scalar values in dataframe to pytorch tensor.

    Parameters
    ----------
    df : pd.DataFrame
        Dataframe to transform
    cols: list[str], Optional
        Columns to transform from the dataframe, all columns are used if None

    Returns
    -------
    torch.FloatTensor
        Transformed dataframe in torch.FloatTensor format
    """
    cols = [c for c in cols if type(df[c].iloc[0]) != str] if cols is not None else df.columns
    return torch.FloatTensor(df[cols].to_numpy())
