package de.jottyfan.camporganizer.module.business.camp;

import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMPPROFILE;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSON;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PROFILE;
import static de.jottyfan.camporganizer.db.jooq.Tables.V_CAMP;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jooq.DSLContext;
import org.jooq.Record6;
import org.jooq.Record8;
import org.jooq.SelectConditionStep;
import org.jooq.SelectSeekStep4;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import de.jottyfan.camporganizer.db.EnumConverter;
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
import de.jottyfan.camporganizer.db.jooq.enums.EnumModule;
import de.jottyfan.camporganizer.db.jooq.enums.EnumProgress;
import de.jottyfan.camporganizer.db.jooq.enums.EnumSex;
import de.jottyfan.camporganizer.module.business.camp.model.CampBean;
import de.jottyfan.camporganizer.module.business.camp.model.PersonBean;

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

	@Autowired
	private DSLContext jooq;

	/**
	 * get the camp referenced by pk
	 *
	 * @param pk       the ID of the camp
	 * @param username the name of the current user in this session
	 *
	 * @return the camp if found or null
	 */
	public CampBean getCamp(Integer pk, String username) {
		SelectConditionStep<Record6<String, Double, LocalDateTime, LocalDateTime, String, String>> sql = jooq
		// @formatter:off
			.select(V_CAMP.NAME, V_CAMP.YEAR, V_CAMP.ARRIVE, V_CAMP.DEPART, V_CAMP.LOCATION_NAME, V_CAMP.PRICE)
			.from(V_CAMP)
			.leftJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_CAMP.eq(V_CAMP.PK)).and(T_CAMPPROFILE.MODULE.eq(EnumModule.business))
			.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_CAMPPROFILE.FK_PROFILE))
			.where(V_CAMP.PK.eq(pk))
			.and(T_PROFILE.USERNAME.eq(username));
		// @formatter:on
		LOGGER.trace(sql);
		CampBean bean = new CampBean();
		Iterator<Record6<String, Double, LocalDateTime, LocalDateTime, String, String>> i = sql.fetch().iterator();
		while (i.hasNext()) {
			Record6<String, Double, LocalDateTime, LocalDateTime, String, String> r = i.next();
			bean.setName(r.get(V_CAMP.NAME));
			bean.setYear(r.get(V_CAMP.YEAR));
			bean.setArrive(r.get(V_CAMP.ARRIVE));
			bean.setDepart(r.get(V_CAMP.DEPART));
			bean.setLocationName(r.get(V_CAMP.LOCATION_NAME));
			bean.setPrice(r.get(V_CAMP.PRICE));
		}
		return bean;
	}

	/**
	 * get a list of all registered persons that have booked the camp
	 *
	 * @param pk       the ID of the camp
	 * @param username the name of the current user in this session
	 *
	 * @return a list of bookings; an empty one at least
	 */
	public List<PersonBean> getBookings(Integer pk, String username) {
		SelectSeekStep4<Record8<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime>, EnumCamprole, EnumSex, String, String> sql = jooq
		// @formatter:off
		  .select(T_PERSON.PK, T_PERSON.PROGRESS, T_PERSON.PAID, T_PERSON.FORENAME, T_PERSON.SURNAME, T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.CREATED)
		  .from(T_PERSON)
			.leftJoin(T_CAMPPROFILE).on(T_CAMPPROFILE.FK_CAMP.eq(T_PERSON.FK_CAMP)).and(T_CAMPPROFILE.MODULE.eq(EnumModule.business))
			.leftJoin(T_PROFILE).on(T_PROFILE.PK.eq(T_CAMPPROFILE.FK_PROFILE))
		  .where(T_PERSON.FK_CAMP.eq(pk))
		  .and(T_PROFILE.USERNAME.eq(username))
		  .orderBy(T_PERSON.CAMPROLE, T_PERSON.SEX, T_PERSON.SURNAME, T_PERSON.FORENAME);
		// @formatter:on
		LOGGER.trace(sql);
		List<PersonBean> list = new ArrayList<>();
		Iterator<Record8<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime>> i = sql.fetch().iterator();
		while (i.hasNext()) {
			Record8<Integer, EnumProgress, BigDecimal, String, String, EnumCamprole, EnumSex, LocalDateTime> r = i.next();
			String forename = r.get(T_PERSON.FORENAME);
			String surname = r.get(T_PERSON.SURNAME);
			EnumCamprole role = r.get(T_PERSON.CAMPROLE);
			EnumSex sex = r.get(T_PERSON.SEX);
			EnumProgress progress = r.get(T_PERSON.PROGRESS);
			PersonBean bean = new PersonBean();
			bean.setPk(r.get(T_PERSON.PK));
			bean.setName(String.format("%s %s", forename, surname));
			bean.setRole(EnumConverter.role2GermanNames(role));
			bean.setSex(EnumConverter.sex2GermanNames(sex));
			bean.setBookingDate(r.get(T_PERSON.CREATED));
			bean.setProgress(progress == null ? null : progress.getLiteral());
			bean.setPaid(r.get(T_PERSON.PAID));
			list.add(bean);
		}
		return list;
	}
}
