package de.accso.flexinale.backoffice.application.services;

import de.accso.flexinale.backoffice.domain.dao.FilmDao;
import de.accso.flexinale.backoffice.domain.model.Film;
import de.accso.flexinale.common.domain.dao.AbstractDao;
import de.accso.flexinale.common.application.services.AbstractExcelDataUploadService;
import de.accso.flexinale.common.shared_kernel.FlexinaleIllegalArgumentException;
import de.accso.flexinale.common.shared_kernel.Identifiable;
import jakarta.transaction.Transactional;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Transactional
public class FilmUploadService extends AbstractExcelDataUploadService<Film> {
    private static final Logger LOGGER = LoggerFactory.getLogger(FilmUploadService.class);

    private final FilmDao filmDao;

    public FilmUploadService(final FilmDao filmDao) {
        this.filmDao = filmDao;
    }

    @Override
    public AbstractDao<Film> getDao() {
        return filmDao;
    }

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

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

        Cell cellDauer = excelRow.getCell(3);
        int dauerInMinuten =
                switch(cellDauer.getCellType()) {
                    case NUMERIC -> (int) cellDauer.getNumericCellValue();
                    case STRING  -> Integer.parseInt(cellDauer.getStringCellValue());
                    default -> throw new FlexinaleIllegalArgumentException("Dauer is not a number");
                };

        Film film = new Film(
                Identifiable.Id.of(filmId),
                new Film.Titel(excelRow.getCell(1).getStringCellValue()),
                new Film.ImdbUrl(excelRow.getCell(2).getStringCellValue()),
                new Film.DauerInMinuten(dauerInMinuten)
        );

        LOGGER.debug("New Film created " + film);

        return film;
    }
}
