
from pathlib import Path
import numpy as np
import pandas as pd
import xarray as xr
from datetime import datetime

from gfatpy.lidar.nc_convert.types import Measurement
from gfatpy.generalife.licel import LicelReader

DZ = 7.5
MAX_BINS = 2000

def licel_to_datetime(licel_name: str) -> datetime | None:
    name, extension = licel_name.split(".")
    try:
        month_decimal = int(name[-5], 16)
        return datetime.strptime(f"{name[-7:-5]}{month_decimal:02d}{name[-4:-2]}T{name[-2:]}{extension[:4]}", r"%y%m%dT%H%M%S")
    except ValueError:
        print(f"Skipping file {licel_name} due to unexpected name format.")
        return None
    

def measurement_to_nc(measurement: Measurement, output_dir: Path):    
    files = measurement.get_filepaths()
    
    times = [licel_to_datetime(file.name) for file in files]
    
    df = pd.read_csv([*files][0].absolute().as_posix(), header=None, skiprows=3, delimiter=' ', encoding='ISO-8859-1', on_bad_lines='skip')
    wavelengths = df[8].dropna().astype(float).values
    voltages = df[6].dropna().astype(float).values

    data = np.empty((len(files), len(wavelengths), MAX_BINS), dtype=float)

    for file_idx, file_path in enumerate(files):
        sp = LicelReader.LicelFileReader(file_path)
        for i, _ in enumerate(wavelengths):
            data[file_idx, i, :] = sp.dataSet[i].physData

    # Create an xarray DataArray from the data array
    raw = xr.DataArray(
        data,
        coords={'wavelength': wavelengths, 'times': times, 'range': DZ*np.arange(MAX_BINS)},
        dims=['times', 'wavelength', 'range']
    )

    voltages = xr.DataArray(
        voltages,
        coords={'wavelength': wavelengths},
        dims=['wavelength']
    )

    center_wavelength = (wavelengths[16] + wavelengths[15]) / 2

    # Create an xarray Dataset from the DataArray
    ds = xr.Dataset({'raw': raw, 'voltages': voltages})

    ds.attrs.update({
            'system name': 'Generalife',  
            'location': 'Granada',
            'latitude': '37.1641° N',
            'longitude': '3.6026° W',
            'altitude': '680 m',
            'frequency': '10 Hz',
            'bin width': '7.5 m',
            'number of bins': '2000',
            'number of channels': '32',
            'center wavelength': center_wavelength,            
            'discriminator' : '4.0',
            'bin_corrected': 'False',
            'bcg_corrected': 'False',
        })

    if isinstance(times[0], datetime):
        datestr = times[0].strftime('%Y%m%d')   
        filename = f"gnl_1a_Prs_rs_ff_{datestr}.nc"
        output_path = output_dir / "generalife" / "1a" / f"{times[0].strftime('%Y')}" / f"{times[0].strftime('%m')}" / f"{times[0].strftime('%d')}" / filename
        ds.to_netcdf(output_path)

