"""Read the MetImage relative spectral response functions.

Data from EUMETSAT. Published in March 2026:

https://sftp.eumetsat.int/public/folder/UsCVknVOOkSyCdgpMimJNQ/User-Materials/EPS-SGUP/EPS-SGA1_METIMAGE_SRF.nc

These are the so called low resolution macro pixel (=average over all detectors)
SRFs. Higher resolution SRFs per detector are available, however, currently
under export control, so not freely available.

"""

import logging
import os

import numpy as np
from netCDF4 import Dataset

from pyspectral.bandnames import BANDNAMES
from pyspectral.raw_reader import InstrumentRSR
from pyspectral.utils import get_central_wave

LOG = logging.getLogger(__name__)


METIMAGE_BAND_NAMES_DICT = {BANDNAMES['VII'][k]: k for k in BANDNAMES['VII']}
METIMAGE_BAND_NAMES = list(METIMAGE_BAND_NAMES_DICT.keys())


def get_groupname_from_bandname(band):
    """Get group name in netcdf file from band name."""
    groupname = "LVWIR"
    wv = int(band.split("_")[-1])
    if wv > 6000:
        groupname = "LVWIR"
    elif wv > 1000:
        groupname = "SMWIR"
    else:
        groupname = "VISNIR"
    return groupname


class MetImageRSR(InstrumentRSR):
    """Container for the EPS-SG MetImage RSR data."""

    def __init__(self, bandname, platform_name):
        """Initialize the class."""
        super(MetImageRSR, self).__init__(
            bandname, platform_name, list(METIMAGE_BAND_NAMES))

        self.instrument = 'metimage'
        self._get_options_from_config()

        LOG.debug("Filename: %s", str(self.path))
        if os.path.exists(self.path):
            self.requested_band_filename = self.path
            self.nc_band_name = METIMAGE_BAND_NAMES_DICT[bandname].replace("vii", "ISRF_cw")
            self.group_name = get_groupname_from_bandname(METIMAGE_BAND_NAMES_DICT[bandname])
            self._load()

        else:
            LOG.warning("Couldn't find an existing file for this band: %s",
                        str(self.bandname))

        # To be compatible with VIIRS....
        self.filename = self.requested_band_filename
        self.unit = 'micrometer'
        self.wavespace = 'wavelength'

    def _load(self, scale=1.0):
        """Load the METimage relative spectral responses."""
        LOG.debug("File: %s", str(self.requested_band_filename))
        ncf = Dataset(self.requested_band_filename, 'r', format='NETCDF4')
        wvl = ncf[self.group_name].variables[self.nc_band_name][:, 0] * scale
        resp = ncf[self.group_name].variables[self.nc_band_name][:, 1]
        resp = resp / max(resp)  # Not sure about this
        # The real MetImage has 24 detectors. However, for now we store the
        # single rsr as 'detector-1', indicating that there will be multiple
        # detectors in the future:
        detectors = {}
        detectors['det-1'] = {'wavelength': wvl, 'response': resp}
        self.rsr = detectors
        ncf.close()


def generate_metimage_file(platform_name):
    """Retrieve original RSR data and convert to internal hdf5 format."""
    import h5py

    bandnames = METIMAGE_BAND_NAMES
    instr = MetImageRSR(bandnames[0], platform_name)
    instr_name = instr.instrument.replace('/', '')
    filename = os.path.join(instr.output_dir,
                            "rsr_{0}_{1}.h5".format(instr_name,
                                                    platform_name))

    with h5py.File(filename, "w") as h5f:
        h5f.attrs['description'] = ('Relative Spectral Responses for ' +
                                    instr.instrument.upper())
        h5f.attrs['platform_name'] = platform_name
        h5f.attrs['band_names'] = bandnames

        for chname in bandnames:
            metimage = MetImageRSR(chname, platform_name)
            grp = h5f.create_group(chname)
            grp.attrs['number_of_detectors'] = len(metimage.rsr.keys())
            # Loop over each detector to check if the sampling wavelengths are
            # identical:
            det_names = list(metimage.rsr.keys())
            wvl = metimage.rsr[det_names[0]]['wavelength']
            wvl, idx = np.unique(wvl, return_index=True)
            wvl_is_constant = True
            for det in det_names[1:]:
                det_wvl = np.unique(metimage.rsr[det]['wavelength'])
                if not np.alltrue(wvl == det_wvl):
                    LOG.warning(
                        "Wavelngth arrays are not the same among detectors!")
                    wvl_is_constant = False

            if wvl_is_constant:
                arr = wvl
                dset = grp.create_dataset('wavelength', arr.shape, dtype='f')
                dset.attrs['unit'] = 'm'
                dset.attrs['scale'] = 1e-06
                dset[...] = arr

            # Loop over each detector:
            for det in metimage.rsr:
                det_grp = grp.create_group(det)
                wvl = metimage.rsr[det]['wavelength'][
                    ~np.isnan(metimage.rsr[det]['wavelength'])]
                rsp = metimage.rsr[det]['response'][
                    ~np.isnan(metimage.rsr[det]['wavelength'])]
                wvl, idx = np.unique(wvl, return_index=True)
                rsp = np.take(rsp, idx)
                LOG.debug("wvl.shape: %s", str(wvl.shape))
                det_grp.attrs[
                    'central_wavelength'] = get_central_wave(wvl, rsp)
                if not wvl_is_constant:
                    arr = wvl
                    dset = det_grp.create_dataset(
                        'wavelength', arr.shape, dtype='f')
                    dset.attrs['unit'] = 'm'
                    dset.attrs['scale'] = 1e-06
                    dset[...] = arr

                dset = det_grp.create_dataset('response', rsp.shape, dtype='f')
                dset[...] = rsp


if __name__ == "__main__":
    for platform_name in ["Metop-SG-A1", ]:
        generate_metimage_file(platform_name)
