package de.oaa.xxx.session.sperre;

import java.time.LocalDateTime;
import java.util.Optional;
import java.util.Random;
import java.util.UUID;

import de.oaa.xxx.session.aufgaben.AufgabenList;
import de.oaa.xxx.session.aufgaben.Sperre;
import de.oaa.xxx.session.entity.AktiveSperreDAO;
import de.oaa.xxx.session.entity.AktiveSperreEntity;
import de.oaa.xxx.session.entity.MitspielerDAO;
import de.oaa.xxx.session.entity.MitspielerEntity;
import de.oaa.xxx.session.entity.SessionDAO;
import de.oaa.xxx.session.entity.SessionEntity;
import jakarta.json.bind.JsonbBuilder;

public class SperreVerarbeiten {

	public void sperreAnwenden(SperreCallback callback, SessionDAO sessionDao, MitspielerDAO mitspielerDAO, AktiveSperreDAO sperreDao) {
		SessionEntity session = sessionDao.findById(callback.getSessionId());
		MitspielerEntity mitspieler = mitspielerDAO.findById(callback.getSpielerId());
		if (session != null) {
			AufgabenList aufgaben = JsonbBuilder.create().fromJson(session.getAufgaben(), AufgabenList.class);
			Optional<Sperre> first = aufgaben.getSperren().stream().filter(sperre -> sperre.getSperreId().equals(callback.getSperreId())).findFirst();
			if (first.isPresent()) {
				Sperre sperre = first.get();
				AktiveSperreEntity aktiv = new AktiveSperreEntity();
				fill(callback, session, mitspieler, sperre, aktiv);
				sperreDao.persist(aktiv);
				sperre.getSperreFuer().forEach(mitspieler.getWerkzeuge()::remove);
				mitspielerDAO.update(mitspieler);
			}
		}
	}
	
	public String sperreAufheben(AktiveSperreEntity aufzuheben, AktiveSperreDAO sperreDAO, MitspielerDAO mitspielerDAO) {
		MitspielerEntity mitspieler = aufzuheben.getMitspieler();
		aufzuheben.getFuer().forEach(mitspieler.getWerkzeuge()::add);
		mitspielerDAO.update(mitspieler);
		String releaseText = aufzuheben.getReleaseText();
		sperreDAO.remove(aufzuheben);
		return releaseText;
	}
	
	public void SperreVerlaengern(AktiveSperreEntity verlaengern, Integer faktor, AktiveSperreDAO dao) {
		Integer neueDauer = verlaengern.getMinuten() * faktor;
		verlaengern.setEndzeit(verlaengern.getStartzeit().plusMinutes(neueDauer));
		verlaengern.setMinuten(neueDauer);
		dao.update(verlaengern);
	}

	private void fill(SperreCallback callback, SessionEntity session, MitspielerEntity mitspieler, Sperre sperre,
			AktiveSperreEntity aktiv) {
		aktiv.setAktiveSperreId(UUID.randomUUID());
		LocalDateTime now = LocalDateTime.now();
		Integer minuten = berechneDauer(session, sperre);
		aktiv.setStartzeit(now);
		aktiv.setEndzeit(now.plusMinutes(minuten));
		aktiv.setMinuten(minuten);
		aktiv.setMitspieler(mitspieler);
		aktiv.setFuer(sperre.getSperreFuer());
		aktiv.setReleaseText(callback.getReleaseText());
	}

	private Integer berechneDauer(SessionEntity session, Sperre sperre) {
		Integer minuten = 30;
		if (sperre.getMinutenVon() != null) {
			if (sperre.getMinutenBis() != null) {
				minuten = new Random().nextInt(sperre.getMinutenVon(), sperre.getMinutenBis());
			} else {
				minuten = sperre.getMinutenVon();
			}
		}
		if (session.getZeitfaktorZeitstrafen() != null) {
			 minuten = (int) (minuten * session.getZeitfaktorZeitstrafen());
		}
		if (minuten == 0) {
			minuten = 1;
		}
		return minuten;
	}
}
