package de.accso.flexinale.data.services;

import de.accso.flexinale.data.model.Kino;
import de.accso.flexinale.data.model.KinoSaal;
import de.accso.flexinale.data.persistence.AbstractDao;
import de.accso.flexinale.data.persistence.KinoDao;
import de.accso.flexinale.shared_kernel.DeveloperMistakeException;
import de.accso.flexinale.shared_kernel.FlexinaleIllegalStateException;
import jakarta.transaction.Transactional;
import org.apache.poi.ss.usermodel.Row;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Service
@Transactional
public non-sealed class KinoUploadService extends AbstractExcelDataUploadService<Kino> {
    private static final Logger LOGGER = LoggerFactory.getLogger(KinoUploadService.class);

    @Autowired
    private KinoDao kinoDao;

    private final Map<String, Collection<KinoSaal>> alleKinosUndIhreSaele = new HashMap<>();

    @Override
    public AbstractDao<Kino> getDao() {
        return kinoDao;
    }

    @Override
    public String getNameOfExcelDataType() {
        return Kino.class.getSimpleName();
    }

    @Override
    public void beforeLoad(Object... o) {
        if ((o.length != 1) && (!(o[0] instanceof Map))) {
            throw new DeveloperMistakeException("wrong type: expecting a " +
                    "Map<String, Collection<KinoSaal>> of Kino and their KinoSaele");
        }

        @SuppressWarnings("unchecked")
        Map<String, Collection<KinoSaal>> newKinoAndKinoSaele = (Map<String, Collection<KinoSaal>>) o[0];
        this.alleKinosUndIhreSaele.putAll(newKinoAndKinoSaele);
    }

    @Override
    public void afterLoad(Object... o)  {
        alleKinosUndIhreSaele.clear();
    }

    @Override
    public Kino createDataFromExcelRow(final Row excelRow) {
        String kinoId = excelRow.getCell(0).getStringCellValue();

        Collection<KinoSaal> saeleImKino = alleKinosUndIhreSaele.get(kinoId);
        if (saeleImKino == null || saeleImKino.isEmpty()) {
            throw new FlexinaleIllegalStateException("no Saele for Kino %s found".formatted(kinoId));
        }

        Kino kino = new Kino(
                kinoId,
                excelRow.getCell(1).getStringCellValue(),
                excelRow.getCell(2).getStringCellValue(),
                excelRow.getCell(3).getStringCellValue(),
                Set.copyOf(saeleImKino)
        );

        LOGGER.debug("New Kino created: " + kino);

        return kino;
    }
}
