package com.jasamedika.medifirst2000.task.schedule;

import com.jasamedika.medifirst2000.dao.*;
import com.jasamedika.medifirst2000.entities.KelompokPasien;
import com.jasamedika.medifirst2000.entities.Pegawai;
import com.jasamedika.medifirst2000.entities.RekapLogbookDokter;
import com.jasamedika.medifirst2000.service.LogbookRemunService;
import com.jasamedika.medifirst2000.service.PelayananPasienService;
import com.jasamedika.medifirst2000.service.RekapLogbookDokterService;
import com.jasamedika.medifirst2000.service.RemunerasiService;
import com.jasamedika.medifirst2000.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author salmanoe
 * @version 1.0.0
 * @since 07/11/2023
 */
@Component
public class LogbookTask {
	private static final Logger LOGGER = LoggerFactory.getLogger(LogbookTask.class);

	@Autowired
	private PelayananPasienPetugasDao pelayananPasienPetugasDao;

	@Autowired
	private RekapLogbookDokterDao rekapLogbookDokterDao;

	@Autowired
	private PelayananPasienService pelayananPasienService;

	@Autowired
	private RemunerasiService remunerasiService;

	@Autowired
	private RekapLogbookDokterService rekapLogbookDokterService;

	@Autowired
	private LogbookRemunService logbookRemunService;

	@Scheduled(cron = "0 0 0 1-6 * ?")
	public void saveRekapLogbookDokter() {
		LOGGER.info("Start simpan rekapitulasi logbook dokter");

		LocalDate localDate = LocalDate.now().minusMonths(1);
		Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
		Date tglAwal = DateUtil.startMonth(date);
		Date tglAkhir = DateUtil.endMonth(date);
		{
			// Delete untuk pembaharuan data
			rekapLogbookDokterService.deleteByPeriod(tglAwal, tglAkhir);
		}
		Set<Integer> idPegawaiByTglPelayanan = pelayananPasienPetugasDao.findPegawaiByTglPelayanan(tglAwal, tglAkhir);
		DateFormat df = new SimpleDateFormat("yyyy-MM");
		String bulan = df.format(date);
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
		YearMonth oct24 = YearMonth.parse("2024-10", formatter);
		YearMonth month = YearMonth.parse(bulan, formatter);
		List<RekapLogbookDokter> models = new ArrayList<>();
		idPegawaiByTglPelayanan.forEach(idPegawai -> {
			{
				Map<String, Object> kinerjaDokter;
				if (month.isBefore(oct24)) {
					kinerjaDokter = pelayananPasienService.logbookRemunTarifDokter(idPegawai, bulan, null);
				} else {
					kinerjaDokter = remunerasiService.logbookRemunTarifDokter(idPegawai, bulan, null);
				}
				List<Map<String, Object>> remun = (List<Map<String, Object>>) kinerjaDokter.get("data");
				List<Integer> listIdKelompokPasien = new ArrayList<>();
				remun.forEach(r -> {
					if (!listIdKelompokPasien.contains(Integer.parseInt(r.get("idKelompokPasien").toString())))
						listIdKelompokPasien.add(Integer.parseInt(r.get("idKelompokPasien").toString()));
				});
				listIdKelompokPasien.forEach(idKelompokPasien -> {
					double jumlah = remun.stream().filter(r -> idKelompokPasien.equals(r.get("idKelompokPasien")))
							.mapToDouble(r -> Double.parseDouble(r.get("jumlah").toString())).sum();
					double hargaJasa = remun.stream().filter(r -> idKelompokPasien.equals(r.get("idKelompokPasien")))
							.mapToDouble(r -> Double.parseDouble(r.get("jumlahHargaJasa").toString())).sum();
					RekapLogbookDokter rekapLogbookDokter = new RekapLogbookDokter();
					rekapLogbookDokter.setKdProfile((short) 0);
					rekapLogbookDokter.setStatusEnabled(true);
					Pegawai pegawai = new Pegawai();
					pegawai.setId(idPegawai);
					rekapLogbookDokter.setPegawai(pegawai);
					rekapLogbookDokter.setJenisLogbook("JKN");
					KelompokPasien kelompokPasien = new KelompokPasien();
					kelompokPasien.setId(idKelompokPasien);
					rekapLogbookDokter.setKelompokPasien(kelompokPasien);
					rekapLogbookDokter.setBulan(date);
					rekapLogbookDokter.setJumlah(jumlah);
					rekapLogbookDokter.setCapaian(hargaJasa);
					models.add(rekapLogbookDokter);
				});
			}
			{
				List<Map<String, Object>> ffs;
				if (month.isBefore(oct24)) {
					ffs = pelayananPasienService.logbookFfsTarifDokter(idPegawai, bulan, null);
				} else {
					ffs = remunerasiService.logbookFfsTarifDokter(idPegawai, bulan, null);
				}
				List<String> listJenisRuangan = new ArrayList<>();
				List<Integer> listIdKelompokPasien = new ArrayList<>();
				ffs.forEach(r -> {
					if (!listJenisRuangan.contains(r.get("jenisRuangan").toString()))
						listJenisRuangan.add(r.get("jenisRuangan").toString());
					if (!listIdKelompokPasien.contains(Integer.parseInt(r.get("idKelompokPasien").toString())))
						listIdKelompokPasien.add(Integer.parseInt(r.get("idKelompokPasien").toString()));
				});
				listJenisRuangan.forEach(jenisRuangan -> listIdKelompokPasien.forEach(idKelompokPasien -> {
					double jumlah = ffs.stream()
							.filter(r -> jenisRuangan.equals(r.get("jenisRuangan"))
									&& idKelompokPasien.equals(r.get("idKelompokPasien")))
							.mapToDouble(r -> Double.parseDouble(r.get("jumlah").toString())).sum();
					double hargaJasa = ffs.stream()
							.filter(r -> jenisRuangan.equals(r.get("jenisRuangan"))
									&& idKelompokPasien.equals(r.get("idKelompokPasien")))
							.mapToDouble(r -> Double.parseDouble(r.get("jumlahHargaJasa").toString())).sum();
					RekapLogbookDokter rekapLogbookDokter = new RekapLogbookDokter();
					rekapLogbookDokter.setKdProfile((short) 0);
					rekapLogbookDokter.setStatusEnabled(true);
					Pegawai pegawai = new Pegawai();
					pegawai.setId(idPegawai);
					rekapLogbookDokter.setPegawai(pegawai);
					rekapLogbookDokter.setJenisLogbook("NON_JKN");
					rekapLogbookDokter.setJenisRuangan(jenisRuangan);
					KelompokPasien kelompokPasien = new KelompokPasien();
					kelompokPasien.setId(idKelompokPasien);
					rekapLogbookDokter.setKelompokPasien(kelompokPasien);
					rekapLogbookDokter.setBulan(date);
					rekapLogbookDokter.setJumlah(jumlah);
					rekapLogbookDokter.setCapaian(hargaJasa);
					models.add(rekapLogbookDokter);
				}));
			}
			{
				List<Map<String, Object>> fixedPay;
				if (month.isBefore(oct24)) {
					fixedPay = pelayananPasienService.logbookFixedPayDokter(idPegawai, bulan, null);
				} else {
					fixedPay = remunerasiService.logbookFixedPayDokter(idPegawai, bulan, null);
				}
				List<String> listJenisRuangan = new ArrayList<>();
				List<Integer> listIdKelompokPasien = new ArrayList<>();
				List<String> listBulanIbuPulangRanap = new ArrayList<>();
				fixedPay.forEach(r -> {
					if (!listJenisRuangan.contains(r.get("jenisRuangan").toString()))
						listJenisRuangan.add(r.get("jenisRuangan").toString());
					if (!listIdKelompokPasien.contains(Integer.parseInt(r.get("idKelompokPasien").toString())))
						listIdKelompokPasien.add(Integer.parseInt(r.get("idKelompokPasien").toString()));
					if (!listBulanIbuPulangRanap.contains(r.get("bulanPulangIbu").toString()))
						listBulanIbuPulangRanap.add(r.get("bulanPulangIbu").toString());
				});
				listJenisRuangan.forEach(jenisRuangan -> listIdKelompokPasien
						.forEach(idKelompokPasien -> listBulanIbuPulangRanap.forEach(bulanIbuPulangRanap -> {
							double jumlah = fixedPay.stream()
									.filter(r -> jenisRuangan.equals(r.get("jenisRuangan"))
											&& idKelompokPasien.equals(r.get("idKelompokPasien"))
											&& bulanIbuPulangRanap.equals(r.get("bulanPulangIbu")))
									.mapToDouble(r -> Double.parseDouble(r.get("jumlah").toString())).sum();
							double hargaJasa = fixedPay.stream()
									.filter(r -> jenisRuangan.equals(r.get("jenisRuangan"))
											&& idKelompokPasien.equals(r.get("idKelompokPasien"))
											&& bulanIbuPulangRanap.equals(r.get("bulanPulangIbu")))
									.mapToDouble(r -> Double.parseDouble(r.get("jumlahHargaJasa").toString())).sum();
							RekapLogbookDokter rekapLogbookDokter = new RekapLogbookDokter();
							rekapLogbookDokter.setKdProfile((short) 0);
							rekapLogbookDokter.setStatusEnabled(true);
							Pegawai pegawai = new Pegawai();
							pegawai.setId(idPegawai);
							rekapLogbookDokter.setPegawai(pegawai);
							rekapLogbookDokter.setJenisLogbook("FIXED_PAY");
							rekapLogbookDokter.setJenisRuangan(jenisRuangan);
							KelompokPasien kelompokPasien = new KelompokPasien();
							kelompokPasien.setId(idKelompokPasien);
							rekapLogbookDokter.setKelompokPasien(kelompokPasien);
							rekapLogbookDokter.setBulanPulangIbu(bulanIbuPulangRanap);
							rekapLogbookDokter.setBulan(date);
							rekapLogbookDokter.setJumlah(jumlah);
							rekapLogbookDokter.setCapaian(hargaJasa);
							models.add(rekapLogbookDokter);
						})));
			}
		});
		rekapLogbookDokterDao.save(models);

		LOGGER.info("Simpan rekapitulasi logbook dokter berhasil...!");
	}

	@Scheduled(cron = "0 0 0 1-6 * ?")
	public void saveRekapDetailLogbookDokter() {
		logbookRemunService.generateRecap();
	}

}
