package de.jottyfan.camporganizer.module.dashboard;

import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSON;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSONDOCUMENT;
import static de.jottyfan.camporganizer.db.jooq.Tables.T_RSS;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jooq.DSLContext;
import org.jooq.DeleteConditionStep;
import org.jooq.InsertValuesStep2;
import org.jooq.InsertValuesStep4;
import org.jooq.UpdateConditionStep;
import org.jooq.exception.DataAccessException;
import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import de.jottyfan.camporganizer.db.jooq.enums.EnumFiletype;
import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TPersondocumentRecord;
import de.jottyfan.camporganizer.db.jooq.tables.records.TRssRecord;
import de.jottyfan.camporganizer.module.camplist.model.BookingBean;
import de.jottyfan.camporganizer.module.camplist.model.LambdaResultWrapper;

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

	@Autowired
	private DSLContext jooq;

	/**
	 * update defined fields of the bean
	 *
	 * @param bean the bean
	 * @return number of affected database rows; should be 1
	 */
	public Integer update(BookingBean bean) {
		UpdateConditionStep<TPersonRecord> sql = jooq
		// @formatter:off
			.update(T_PERSON)
			.set(T_PERSON.FORENAME, bean.getForename())
			.set(T_PERSON.SURNAME, bean.getSurname())
			.set(T_PERSON.STREET, bean.getStreet())
			.set(T_PERSON.ZIP, bean.getZip())
			.set(T_PERSON.CITY, bean.getCity())
			.set(T_PERSON.PHONE, bean.getPhone())
			.set(T_PERSON.EMAIL, bean.getEmail())
			.set(T_PERSON.COMMENT, bean.getComment())
			.where(T_PERSON.PK.eq(bean.getPk()));
		// @formatter:on
		LOGGER.trace(sql.toString());
		return sql.execute();
	}


	/**
	 * delete entry from t_persondocument where pk = ?
	 *
	 * @param pk
	 *          to be used as reference
	 * @return number of affected database lines
	 * @throws DataAccessException
	 */
	public Integer deletePersondocument(PersondocumentBean bean) throws DataAccessException {
		LambdaResultWrapper lrw = new LambdaResultWrapper();
		jooq.transaction(t -> {

			DeleteConditionStep<TPersondocumentRecord> sql = DSL.using(t)
			// @formatter:off
				.deleteFrom(T_PERSONDOCUMENT)
				.where(T_PERSONDOCUMENT.PK.eq(bean.getPk()));
			// @formatter:on
			LOGGER.trace(sql);
			lrw.add(sql.execute());

			StringBuilder buf = new StringBuilder("Dokument ");
			buf.append(bean.getName());
			buf.append(" wurde wieder gelöscht.");
			InsertValuesStep2<TRssRecord, String, String> sql2 = DSL.using(t)
			// @formatter:off
		    .insertInto(T_RSS,
		    		         T_RSS.MSG,
		    		         T_RSS.RECIPIENT)
		    .values(buf.toString(), "registrator");
		  // @formatter:on
			LOGGER.trace(sql);
			sql2.execute();
		});
		return lrw.getCounter();
	}

	/**
	 * add document to database
	 *
	 * @param bean
	 * @throws DataAccessException
	 */
	public void addPersondocument(PersondocumentBean bean) throws DataAccessException {
		jooq.transaction(t -> {

			InsertValuesStep4<TPersondocumentRecord, String, EnumFiletype, Integer, String> sql = DSL.using(t)
		  // @formatter:off
		    	.insertInto(T_PERSONDOCUMENT,
		    			       T_PERSONDOCUMENT.NAME,
		    			       T_PERSONDOCUMENT.FILETYPE,
		    			       T_PERSONDOCUMENT.FK_PERSON,
		    			       T_PERSONDOCUMENT.DOCUMENT
		    			       )
		    	.values(bean.getName(), bean.getFiletype(), bean.getFkPerson(), bean.getDocument());
		  // @formatter:on
			LOGGER.trace(sql);
			sql.execute();

			StringBuilder buf = new StringBuilder("Dokument ");
			buf.append(bean.getName());
			buf.append(" wurde angelegt.");
			InsertValuesStep2<TRssRecord, String, String> sql2 = DSL.using(t)
		  // @formatter:off
	      .insertInto(T_RSS,
	      		         T_RSS.MSG,
	      		         T_RSS.RECIPIENT)
	      .values(buf.toString(), "registrator");
	    // @formatter:on
			LOGGER.trace(sql2);
			sql2.execute();
		});
	}
}
