
package com.jasamedika.medifirst2000.controller;

import com.jasamedika.medifirst2000.constants.MessageResource;
import com.jasamedika.medifirst2000.controller.base.LocaleController;
import com.jasamedika.medifirst2000.exception.ServiceVOException;
import com.jasamedika.medifirst2000.service.DetailAnggaranService;
import com.jasamedika.medifirst2000.service.KartuPengendaliService;
import com.jasamedika.medifirst2000.vo.*;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.jasamedika.medifirst2000.constants.Constants.MessageInfo.ERROR_MESSAGE;
import static com.jasamedika.medifirst2000.core.web.WebConstants.HttpHeaderInfo.LABEL_SUCCESS;
import static com.jasamedika.medifirst2000.util.rest.RestUtil.getJsonHttpStatus;
import static com.jasamedika.medifirst2000.util.rest.RestUtil.getJsonResponse;
import static org.slf4j.LoggerFactory.getLogger;
import static org.springframework.http.HttpStatus.*;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

@RestController
@RequestMapping("/kartu-pengendali")
public class KartuPengendaliController extends LocaleController<KartuPengendaliVO> {

	private static final Logger LOGGER = getLogger(KartuPengendaliController.class);

	@Autowired
	private KartuPengendaliService service;

	@Autowired
	private DetailAnggaranService detailAnggaranService;

	@RequestMapping(value = "/save-kartu-pengendali", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> saveKartuPengendali(@Valid @RequestBody KartuPengendaliCustomVO vo,
			HttpServletRequest request) {
		try {
			Map<String, Object> result = service.saveKartuPengendali(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when saveKartuPengendali", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when saveKartuPengendali", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/kartu-pengendali-list")
	@ResponseBody
	public Map<String, Object> multipleCondition(
			@RequestParam(value = "page", required = false, defaultValue = "0") Integer page,
			@RequestParam(value = "take", required = false, defaultValue = "100") Integer limit,
			@RequestParam(value = "sort", required = false, defaultValue = "id") String sort,
			@RequestParam(value = "dir", required = false, defaultValue = "asc") String dir,
			@RequestParam(value = "dateStart", required = false) String dateStart,
			@RequestParam(value = "dateEnd", required = false) String dateEnd,
			@RequestParam(value = "pengendaliId", required = false) Integer pengendaliId,
			@RequestParam(value = "kelompokUser", required = false) Boolean isPpk,
			@RequestParam(value = "isUlp", required = false) Boolean isUlp,
			@RequestParam(value = "isPp", required = false) Boolean isPp) {
		return service.kartuPengenDaliPAging(page, limit, sort, dir, dateStart, dateEnd, pengendaliId, isPpk, isUlp,
				isPp);
	}

	@RequestMapping(value = "/kartu-pengendali-header-list")
	@ResponseBody
	public Map<String, Object> kartuPengendaliHeader(
			@RequestParam(value = "page", required = false, defaultValue = "0") Integer page,
			@RequestParam(value = "take", required = false, defaultValue = "100") Integer limit,
			@RequestParam(value = "sort", required = false, defaultValue = "id") String sort,
			@RequestParam(value = "dir", required = false, defaultValue = "asc") String dir,
			@RequestParam(value = "dateStart", required = false) String dateStart,
			@RequestParam(value = "dateEnd", required = false) String dateEnd,
			@RequestParam(value = "pengendaliId", required = false) Integer pengendaliId,
			@RequestParam(value = "isPpk", required = false) Boolean isPpk,
			@RequestParam(value = "isUlp", required = false) Boolean isUlp,
			@RequestParam(value = "isPp", required = false) Boolean isPp,
			@RequestParam(value = "isAnggaran", required = false) Boolean isAnggaran,
			@RequestParam(value = "isPengendali", required = false) Boolean isPengendali,
			@RequestParam(value = "isDirekturTerkait", required = false) Boolean isDirekturTerkait) {
		return service.kartuPengenDaliPagingHeader(page, limit, sort, dir, dateStart, dateEnd, pengendaliId, isPpk,
				isUlp, isPp, isAnggaran, isPengendali, isDirekturTerkait);
	}

	@RequestMapping(value = "/pre-add-penerimaan")
	@ResponseBody
	public Map<String, Object> preAddPenerimaan(
			@RequestParam(value = "page", required = false, defaultValue = "0") Integer page,
			@RequestParam(value = "take", required = false, defaultValue = "100") Integer limit,
			@RequestParam(value = "sort", required = false, defaultValue = "id") String sort,
			@RequestParam(value = "dir", required = false, defaultValue = "asc") String dir,
			@RequestParam(value = "dateStart", required = false) String dateStart,
			@RequestParam(value = "dateEnd", required = false) String dateEnd,
			@RequestParam(value = "supplierId", required = false) Integer supplierId) {
		return service.preAddPenerimaan(page, limit, sort, dir, dateStart, dateEnd, supplierId);
	}

	@RequestMapping(value = "/generate-template-exel")
	@ResponseBody
	public void generateTemplateExcel(@RequestParam(value = "noRec", required = false) String noRec,
			HttpServletResponse response) throws IOException {
		String fileName = service.generateTemplateExcel(noRec);
		String fileType = "application/vnd.ms-excel";
		response.setContentType(fileType);
		response.setHeader("Content-disposition", "attachment; filename=" + fileName);
		File my_file = new File(fileName);
		OutputStream out = response.getOutputStream();
		FileInputStream in = new FileInputStream(my_file);
		byte[] buffer = new byte[4096];
		int length;
		while ((length = in.read(buffer)) > 0) {
			out.write(buffer, 0, length);
		}
		in.close();
		out.flush();
	}

	@RequestMapping(value = "/save-verifikasi-spek-anggaran", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> saveVerifikasiKartuPengendaliDetail(
			@Valid @RequestBody VerifikasiKartuPengendaliDetailVO vo, HttpServletRequest request) {
		try {
			Map<String, Object> result = service.verifikasiPpk(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when verifikasiPpk", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when verifikasiPpk", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/rekap-pemenang", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> rekapPemenang(@Valid @RequestBody VerifikasiKartuPengendaliDetailVO vo,
			HttpServletRequest request) {
		try {
			Map<String, Object> result = service.rekapPemenang(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when rekapPemenang", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when rekapPemenang", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/rekap-pemenang-from-ulp", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> rekapPemenangFromUlp(@Valid @RequestBody RekapPemenangUlpVO vo,
			HttpServletRequest request) {
		try {
			Map<String, Object> result = service.rekapPemenangFromUlp(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when rekapPemenangFromUlp", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when rekapPemenangFromUlp", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/verifikasi-kartu-pengendali-by-anggaran", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> verifikasiKartuPengendaliByAnggaran(
			@Valid @RequestBody VerifikasiKartuPengendaliDetailVO vo, HttpServletRequest request) {
		try {
			Map<String, Object> result = service.verifikasiKartuPengendaliDetailByAnggaran(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when verifikasiKartuPengendaliDetailByAnggaran", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when verifikasiKartuPengendaliDetailByAnggaran", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/verifikasi-kartu-pengendali-by-header", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> verifikasiKartuPengendaliHeadByAnggaran(
			@Valid @RequestBody VerifikasiKartuPengendaliHeaderVO vo, HttpServletRequest request) {
		try {
			Map<String, Object> result = service.verifikasiAnggaran(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when verifikasiAnggaran", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when verifikasiAnggaran", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/verifikasi-kartu-pengendali-by-direktur", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> verifikasiKartuPengendaliByDirektur(
			@Valid @RequestBody VerifikasiKartuPengendaliHeaderVO vo, HttpServletRequest request) {
		try {
			Map<String, Object> result = service.verfikasiDirekturTerkait(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when verfikasiDirekturTerkait", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when verfikasiDirekturTerkait", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/verifikasi-kartu-pengendali-by-pp", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> verifikasiKartuPengendaliByPp(
			@Valid @RequestBody VerifikasiKartuPengendaliHeaderVO vo, HttpServletRequest request) {
		try {
			Map<String, Object> result = service.verfikasiPp(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when verfikasiPp", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when verfikasiPp", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/verifikasi-kartu-pengendali-by-ulp", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> verifikasiKartuPengendaliByUlp(
			@Valid @RequestBody VerifikasiKartuPengendaliHeaderVO vo, HttpServletRequest request) {
		try {
			Map<String, Object> result = service.verfikasiULP(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when verfikasiULP", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when verfikasiULP", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/update-jadwal", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> updateJadwal(@Valid @RequestBody UpdateJadwalVO vo,
			HttpServletRequest request) {
		try {
			Map<String, Object> result = service.updateJadwal(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when updateJadwal", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when updateJadwal", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/get-detail-kartu-pengendali-list/", method = GET, produces = APPLICATION_JSON_VALUE)
	public List<Map<String, Object>> kartuPengendliDetailList(@RequestParam(value = "noRec") String noRec) {
		return service.kartuPengendliDetailList(noRec);
	}

	@RequestMapping(value = "/get-kartu-pengendali-header-by-norec/", method = GET, produces = APPLICATION_JSON_VALUE)
	public Map<String, Object> getKartuPengendaliHeaderByNoRec(@RequestParam(value = "noRec") String noRec) {
		return service.getKartuPengendaliHeaderByNoRec(noRec);
	}

	@RequestMapping(value = "/pre-rekap-pemenang/", method = GET, produces = APPLICATION_JSON_VALUE)
	public Map<String, Object> preRekapPemenang(@RequestParam(value = "noRec") String noRec) {
		return service.preRekapPemenang(noRec);
	}

	@RequestMapping(value = "/get-get-struk-rekap", method = GET, produces = APPLICATION_JSON_VALUE)
	public Map<String, Object> getStrukRekap(@RequestParam(value = "noRec") String noRec) {
		return service.getStrukRekap(noRec);
	}

	@RequestMapping(value = "/pre-add-jadwal", method = GET, produces = APPLICATION_JSON_VALUE)
	public Map<String, Object> preAddJadwal(@RequestParam(value = "noRec") String noRec) {
		return service.getPreAddJadwal(noRec);
	}

	@RequestMapping(value = "/get-metode-pengadaan-detail", method = GET, produces = APPLICATION_JSON_VALUE)
	public Map<String, Object> getMetodePengadaanDetail(@RequestParam(value = "id") Integer id) {
		return service.metodePengadaanDetail(id);
	}

	@RequestMapping(value = "/upload-exel/", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> upload(@Valid @RequestBody UploadExcelVO vo, HttpServletRequest request)
			throws IOException {
		try {
			Map<String, Object> result = service.uploadExel(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when uploadExel", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when uploadExel", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/save-penawaran-harga-supplier/", method = POST, produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE)
	public ResponseEntity<Map<String, Object>> savePenawaranHargaSupplier(@Valid @RequestBody PenawaranHargaVO vo,
			HttpServletRequest request) throws IOException {
		try {
			Map<String, Object> result = service.savePenawaranHargaSupplier(vo);
			if (null != result)
				mapHeaderMessage.put(LABEL_SUCCESS, getMessage(MessageResource.LABEL_SUCCESS, request));
			return getJsonResponse(result, CREATED, mapHeaderMessage);
		} catch (ServiceVOException e) {
			LOGGER.error("Got ServiceVOException {} when savePenawaranHargaSupplier", e.getMessage());
			addHeaderMessage(ERROR_MESSAGE, e.getMessage());
			return getJsonHttpStatus(INTERNAL_SERVER_ERROR, mapHeaderMessage);
		} catch (JpaSystemException jse) {
			LOGGER.error("Got JpaSystemException {} when savePenawaranHargaSupplier", jse.getMessage());
			addHeaderMessage(ERROR_MESSAGE, jse.getMessage());
			return getJsonHttpStatus(CONFLICT, mapHeaderMessage);
		}
	}

	@RequestMapping(value = "/list-kontrak-grid")
	@ResponseBody
	public Map<String, Object> listKontrakGrid(
			@RequestParam(value = "page", required = false, defaultValue = "0") Integer page,
			@RequestParam(value = "take", required = false, defaultValue = "100") Integer limit,
			@RequestParam(value = "sort", required = false, defaultValue = "id") String sort,
			@RequestParam(value = "dir", required = false, defaultValue = "asc") String dir,
			@RequestParam(value = "dateStart", required = false) String dateStart,
			@RequestParam(value = "dateEnd", required = false) String dateEnd,
			@RequestParam(value = "supplierId", required = false) Integer supplierId,
			@RequestParam(value = "tahun", required = false) Integer tahun) {
		return service.listKontrakGrid(page, limit, sort, dir, dateStart, dateEnd, supplierId, tahun);
	}

	@RequestMapping(value = "/get-kelompok-user/", method = GET, produces = APPLICATION_JSON_VALUE)
	public Map<String, Object> getKelompokUser() {
		Map<String, Object> result = new HashMap<>();
		result.put("kelompokUser", detailAnggaranService.getKelompokUserLogin());
		return result;
	}

}
