# -*- coding: utf-8 -*-

import numpy as np
import pandas as pd

from ..aerosol2d import Aerosol2D
from .Common import detect_delimiter

###############################################################################


def Load_OPCN3_file(file: str, extra_data: bool = False) -> Aerosol2D:
    """
    Load and format data from a CSV file generated by the OPC-N3 particle sensor.

    Parameters
    ----------
    file : str
        Path to the OPCN3 CSV export file.
    extra_data : bool, optional
        If True, retains non-bin data in `.extra_data` attribute. Default is False.

    Returns
    -------
    OPCN : Aerosol2D
        Object containing:
        - Time-resolved particle number concentrations per bin (in cm⁻³)
        - Metadata including bin edges, serial number, instrument type, etc.
    """
    encoding, delimiter = detect_delimiter(file)

    df = pd.read_csv(file, delimiter=delimiter, encoding=encoding)
    df.rename(columns={"date": "Datetime"}, inplace=True)
    df.dropna(inplace=True)
    df.reset_index(drop=True, inplace=True)

    # Parse ISO-formatted timestamp strings (e.g., '2024-01-21T15:30:01.000Z')
    df["Datetime"] = pd.to_datetime(
        df["Datetime"].str.slice(0, 19), format="%Y-%m-%dT%H:%M:%S"
    )

    # Determine bin edges/mids
    bin_cols = df.columns[1:25]
    bin_edges = (
        np.array([float(col.split("Bin")[1]) for col in bin_cols] + [40.0]) * 1000
    )  # in nm
    bin_mids = (bin_edges[:-1] + bin_edges[1:]) / 2

    # Correct Period and FlowRate values
    df["Period"] = df["Period"].astype(float) / 100  # seconds
    df["FlowRate"] = df["FlowRate"].astype(float) / 100  # ml/s

    df.rename(
        columns={"Period": "Period [s]", "FlowRate": "FlowRate [ml/s]"}, inplace=True
    )

    # Optional: store extra data
    if extra_data:
        extra_df = df.drop(columns=bin_cols)
        extra_df.set_index("Datetime", inplace=True)
    else:
        extra_df = pd.DataFrame([])

    # Compute sample volume per row
    sample_volume = df["Period [s]"] * df["FlowRate [ml/s]"]  # in cm³

    # Convert counts to concentrations
    raw_counts = df[bin_cols].astype(float).values
    concentrations = raw_counts / sample_volume.values[:, None]  # #/cm³

    total_conc = np.nansum(concentrations, axis=1)
    total_df = pd.DataFrame(total_conc, columns=["Total_conc"])
    bin_df = pd.DataFrame(concentrations, columns=bin_mids.astype(str))

    final_df = pd.concat([df["Datetime"], total_df, bin_df], axis=1)

    OPCN = Aerosol2D(final_df)
    OPCN._meta = {
        "instrument": "OPCN",
        "bin_edges": bin_edges,
        "bin_mids": bin_mids,
        "density": 1.0,
        "serial_number": "unknown",
        "unit": "cm⁻³",
        "dtype": "dN",
    }

    if extra_data:
        OPCN._extra_data = extra_df

    return OPCN
