package de.jottyfan.camporganizer.module.ical;

import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMP;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_LOCATION;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Iterator;
import java.util.TimeZone;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jooq.DSLContext;
import org.jooq.Record5;
import org.jooq.SelectOnConditionStep;
import org.jooq.exception.DataAccessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import biweekly.ICalendar;
import biweekly.component.VEvent;
import biweekly.io.TimezoneAssignment;
import biweekly.property.Summary;

/**
*
* @author jotty
*
*/
@Repository
@Transactional(transactionManager = "transactionManager")
public class ICalRepository {
	private static final Logger LOGGER = LogManager.getLogger(ICalRepository.class);

	@Autowired
	private DSLContext jooq;

	/**
	 * load all camp dates from db and generate an ical from it
	 *
	 * @return ical containing all (at least none) of the camp dates
	 * @throws DataAccessException
	 */
	public ICalendar getIcal() throws DataAccessException {
		SelectOnConditionStep<Record5<String, LocalDateTime, LocalDateTime, String, String>> sql = jooq
		// @formatter:off
			.select(T_CAMP.NAME,
					    T_CAMP.ARRIVE,
					    T_CAMP.DEPART,
					    T_LOCATION.NAME,
					    T_LOCATION.URL)
			.from(T_CAMP)
		  .leftJoin(T_LOCATION).on(T_LOCATION.PK.eq(T_CAMP.FK_LOCATION));
		// @formatter:on
		LOGGER.trace(sql);
		ICalendar ical = new ICalendar();
		ical.getTimezoneInfo().setDefaultTimezone(TimezoneAssignment.download(TimeZone.getTimeZone("Europe/Berlin"), false));
		Iterator<Record5<String, LocalDateTime, LocalDateTime, String, String>> i = sql.fetch().iterator();
		while (i.hasNext()) {
			Record5<String, LocalDateTime, LocalDateTime, String, String> r = i.next();
			VEvent event = new VEvent();
			Summary summary = event.setSummary(r.get(T_CAMP.NAME));
			summary.setLanguage("de");
			LocalDateTime startDate = r.get(T_CAMP.ARRIVE);
			LocalDateTime endDate = r.get(T_CAMP.DEPART);
			// because of the specification, end dates are exclusive - and without time, the day won't be counted
			endDate = endDate.plusDays(1l);
			event.setLocation(r.get(T_LOCATION.NAME));
			event.setDateStart(startDate == null ? null : Date.from(startDate.atZone(ZoneId.of("Europe/Berlin")).toInstant()), false);
			event.setDateEnd(endDate == null ? null : Date.from(endDate.atZone(ZoneId.of("Europe/Berlin")).toInstant()), false);
			event.setUrl(r.get(T_LOCATION.URL));
			event.setDescription("zur Anmeldung: http://anmeldung.onkelwernerfreizeiten.de");
			ical.addEvent(event);
		}
		return ical;
	}
}
