package at.medevit.elexis.emediplan.ui.handler;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;

import at.medevit.elexis.emediplan.core.EMediplanServiceHolder;
import at.medevit.elexis.emediplan.core.model.chmed16a.Medicament;
import at.medevit.elexis.emediplan.core.model.chmed16a.Medication;
import at.medevit.elexis.emediplan.core.model.chmed16a.Posology;
import ch.elexis.core.common.ElexisEventTopics;
import ch.elexis.core.model.IPatient;
import ch.elexis.core.model.IPrescription;
import ch.elexis.core.model.builder.IPrescriptionBuilder;
import ch.elexis.core.model.prescription.EntryType;
import ch.elexis.core.services.holder.ContextServiceHolder;
import ch.elexis.core.services.holder.CoreModelServiceHolder;
import ch.elexis.core.services.holder.MedicationServiceHolder;
import ch.rgw.tools.TimeTool;

public class DirectImportHandler extends AbstractHandler implements IHandler {
	
	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException{
		String emediplan =
			event.getParameter("at.medevit.elexis.emediplan.ui.directImport.parameter.emediplan");
		String patientid =
			event.getParameter("at.medevit.elexis.emediplan.ui.directImport.parameter.patientid");
		String stopreason =
			event.getParameter("at.medevit.elexis.emediplan.ui.directImport.parameter.stopreason");
		String medicationType =
			event.getParameter("at.medevit.elexis.emediplan.ui.directImport.parameter.medication"); //$NON-NLS-1$
		// if not set use all
		if (medicationType == null || medicationType.isEmpty()) {
			medicationType = "all";
		}
		
		if (StringUtils.isNotEmpty(patientid) && StringUtils.isNotEmpty(emediplan)) {
			Medication medication =
				EMediplanServiceHolder.getService().createModelFromChunk(emediplan);
			
			EMediplanServiceHolder.getService().addExistingArticlesToMedication(medication);
			
			IPatient patient =
				CoreModelServiceHolder.get().load(patientid, IPatient.class).orElse(null);
			if (patient != null) {
				ContextServiceHolder.get().setActivePatient(patient);
				
				List<IPrescription> currentMedication = getPrescriptions(patient, medicationType);
				LocalDateTime now = LocalDateTime.now();
				for (IPrescription prescription : currentMedication) {
					MedicationServiceHolder.get().stopPrescription(prescription, now,
						stopreason != null ? stopreason : "Direct Import");
					prescription.setDateTo(now);
					CoreModelServiceHolder.get().save(prescription);
				}
				currentMedication.forEach(
					pr -> ContextServiceHolder.get().postEvent(ElexisEventTopics.EVENT_UPDATE, pr));
				List<Medicament> notFoundMedicament = new ArrayList<>();
				for (Medicament medicament : medication.Medicaments) {
					if (medicament.artikelstammItem != null) {
						createPrescription(medicament, patient);
					} else {
						notFoundMedicament.add(medicament);
					}
				}
				if (!notFoundMedicament.isEmpty()) {
					StringBuilder sb = new StringBuilder();
					sb.append(
						"Folgende Medikamente konnte im Artikelstamm nicht gefunden werden\n\n");
					notFoundMedicament
						.forEach(m -> sb.append(" - " + m.Id + " " + m.AppInstr + " " + m.TkgRsn));
					MessageDialog.openWarning(Display.getDefault().getActiveShell(), "Warnung",
						sb.toString());
				}
			}
		}
		return null;
	}
	
	private List<IPrescription> getPrescriptions(IPatient patient, String medicationType){
		if ("all".equals(medicationType)) {
			return patient.getMedication(Collections.emptyList());
		} else if ("fix".equals(medicationType)) {
			return patient.getMedication(Arrays.asList(EntryType.FIXED_MEDICATION));
		} else if ("reserve".equals(medicationType)) {
			return patient.getMedication(Arrays.asList(EntryType.RESERVE_MEDICATION));
		} else if ("symptomatic".equals(medicationType)) {
			return patient.getMedication(Arrays.asList(EntryType.SYMPTOMATIC_MEDICATION));
		}
		return Collections.emptyList();
	}
	
	private IPrescription createPrescription(Medicament medicament, IPatient patient){
		medicament.entryType = EntryType.FIXED_MEDICATION;
		if (medicament.Pos != null && !medicament.Pos.isEmpty()) {
			for (Posology pos : medicament.Pos) {
				if (pos.InRes == 1) {
					medicament.entryType = EntryType.RESERVE_MEDICATION;
				}
			}
		}
		
		IPrescription prescription = new IPrescriptionBuilder(CoreModelServiceHolder.get(),
			medicament.artikelstammItem, patient, medicament.dosis).build();
		
		getLocalDateTime(medicament.dateFrom).ifPresent(ldt -> prescription.setDateFrom(ldt));
		getLocalDateTime(medicament.dateTo).ifPresent(ldt -> prescription.setDateTo(ldt));
		
		prescription.setRemark(medicament.AppInstr);
		prescription.setEntryType(medicament.entryType);
		prescription.setDisposalComment(medicament.TkgRsn);
		
		CoreModelServiceHolder.get().save(prescription);
		return prescription;
	}
	
	private java.util.Optional<LocalDateTime> getLocalDateTime(String dateString){
		if (dateString != null && !dateString.isEmpty()) {
			return java.util.Optional.of(new TimeTool(dateString).toLocalDateTime());
		}
		return java.util.Optional.empty();
	}
}

@@ -2762,42 +2762,8 @@
 %22);%0A
-%09%09%09%09%09prescription.setDateTo(now);%0A
 %09%09%09%09

remove double set prescription stop workaround