package gov.va.med.pharmacy.web.track;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException; 
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.json.JsonSanitizer;

import gov.va.med.pharmacy.persistence.report.VisnSelectModel;
import gov.va.med.pharmacy.persistence.service.TrackMessageService;
import gov.va.med.pharmacy.persistence.track.NcpdpMessageListModel;
import gov.va.med.pharmacy.persistence.track.NcpdpMessageModel;
import gov.va.med.pharmacy.web.csv.CSVSupportBean;
import gov.va.med.pharmacy.web.csv.CSVView;
import net.rossillo.spring.web.mvc.CacheControl;
import net.rossillo.spring.web.mvc.CachePolicy;

@Controller
@RequestMapping(value = "/track")
public class TrackRxController {
	
	@Autowired
	private TrackMessageService trackMessageService;

	@RequestMapping(value = "/main")	
	public String getMainPage(HttpServletRequest request) {
		
		// TODO Track audit logic
		return "trackeRx.homepage";
	}
	
	
	private static final String[] TRACK_AUDIT_HEADERS = { "eRx Reference #", "Message Id", "Message Type",	"Prescriber Name", "Prescriber NPI", "VISN", "Station ID", "Pharmacy Name", "Address", "Patient Name", 
            "Patient DOB", "Patient SSN", "Drug Prescribed", "Relates to Message ID", "Received Date","Patient AutoCheck Status","Provider AutoCheck Status",
            "Drug AutoCheck Status","Message Status"};
	
	@RequestMapping(value = "/getMessage", method = RequestMethod.POST, produces = "application/json")
	@CacheControl(policy = {CachePolicy.NO_CACHE})
	@ResponseBody
	public NcpdpMessageModel getMessage(HttpServletRequest request, @RequestParam("json") String json)
			throws JsonParseException, JsonMappingException, IOException {

		//NcpdpMessageModel ncpdpMessageModel = new NcpdpMessageModel();
		
		String jsonString = JsonSanitizer.sanitize(json); // Sanitize the JSON coming from client
		//System.out.println("json is:" + jsonString);
		ObjectMapper jsonMapper = new ObjectMapper();
		
		JsonNode node = jsonMapper.readValue(jsonString, JsonNode.class);
		String messageId = node.get("messageId").asText();
		String inboundOutbound = node.get("inboundOutbound").asText();
		//System.out.println("messageId is:" + messageId);
		//System.out.println("inboundOutbound is:" + inboundOutbound);
		//ncpdpMessageModel = trackMessageService.findByMessageId(messageId);

		return trackMessageService.findByMessageId(messageId, inboundOutbound);
	}
	
	@RequestMapping(value = "/getMessages", method = RequestMethod.GET, produces = "application/json")
	@CacheControl(policy = {CachePolicy.NO_CACHE})
	
	public ModelAndView getMessages(HttpServletRequest request, @RequestParam("json") String json)
			throws JsonParseException, JsonMappingException, IOException {
		ModelAndView mav = new ModelAndView(new org.springframework.web.servlet.view.json.MappingJackson2JsonView());
		
		// Refactored code into a method to be shared between the UI and the CSV as both use same parameters to avoid code duplication.
		List<NcpdpMessageListModel> eRxMessageList = trackAuditSearch(json);
		
		mav.addObject("items", eRxMessageList);
		
		return mav;
	}


	private List<NcpdpMessageListModel> trackAuditSearch(String json)
			throws IOException, JsonParseException, JsonMappingException {
		String jsonString = JsonSanitizer.sanitize(json); // Sanitize the JSON coming from client
			
		ObjectMapper jsonMapper = new ObjectMapper();
		String messageType = "";
		String messageId = "%";
		String relatesToId = "%";
		String visn = "";
		String vaStationId = "%";
		String fromDate = "";
		String toDate = "";
		String patientSsn = "";
		String patientLastName = "%";
		String patientFirstName = "%";
		String patientDob = "";
		String prescriberNpi = "%";
		String prescriberLastName = "%";
		String prescriberFirstName = "%";
		String prescribedDrug = "%";
		String messageStatus = "";
		String inboundNcpdpMsgId = "%";
		String inboundOutbound = "";
		
		JsonNode node = jsonMapper.readValue(jsonString, JsonNode.class);
		if (node.get("inboundNcpdpMessageId") != null){
			inboundNcpdpMsgId = node.get("inboundNcpdpMessageId").asText().trim() + '%';};
		if (node.get("messageType") != null){
			messageType = node.get("messageType").asText();}
		if (node.get("messageId") != null){
			messageId = node.get("messageId").asText().trim() + '%';}	
		if (node.get("relatedMessageId") != null){
			relatesToId = node.get("relatedMessageId").asText().trim() + '%';}
		if (node.get("visn") != null){
			visn = node.get("visn").asText();}
		if (node.get("pharmacyVaStationId") != null){
			vaStationId = node.get("pharmacyVaStationId").asText().trim() + '%';}
		if (node.get("dateFrom") != null){
			fromDate = node.get("dateFrom").asText();}
		if (node.get("dateTo") != null){
			toDate = node.get("dateTo").asText();}
		if (node.get("patientSsn") != null){
			patientSsn = node.get("patientSsn").asText().trim().replace("-", "");}
		if (node.get("patientLastName") != null){
			patientLastName = node.get("patientLastName").asText().toUpperCase().trim() + '%';}
		if (node.get("patientFirstName") != null){
			patientFirstName = node.get("patientFirstName").asText().toUpperCase().trim() + '%';}
		if (node.get("patientDob") != null){
			patientDob = node.get("patientDob").asText();}
		if (node.get("prescriberNPI") != null){
			prescriberNpi = node.get("prescriberNPI").asText().trim() + '%';}
		if (node.get("prescriberLastName") != null){
			prescriberLastName = node.get("prescriberLastName").asText().toUpperCase().trim() + '%';}
		if (node.get("prescriberFirstName") != null){
			prescriberFirstName = node.get("prescriberFirstName").asText().toUpperCase().trim() + '%';}
		if (node.get("prescribedDrug") != null){
			prescribedDrug = node.get("prescribedDrug").asText().toUpperCase().trim() + '%';}
		if (node.get("messageStatus") != null){
			messageStatus = node.get("messageStatus").asText();}
		if (node.get("inboundOutbound") != null){
			inboundOutbound = node.get("inboundOutbound").asText();	
		}

		
		List<NcpdpMessageListModel> eRxMessageList = trackMessageService.searchMessages(messageType, messageId, relatesToId, visn, vaStationId, fromDate, toDate, patientSsn, patientLastName,
				patientFirstName, patientDob, prescriberNpi, prescriberLastName, prescriberFirstName, prescribedDrug, messageStatus, inboundNcpdpMsgId, inboundOutbound);
		return eRxMessageList;
	}
	
	@RequestMapping(value = "/getVisnSelect", method = RequestMethod.GET, produces = "application/json")
	@CacheControl(policy = {CachePolicy.NO_CACHE})
	@ResponseBody
	public List<VisnSelectModel> getVisnSelect(HttpServletRequest request)
			throws JsonParseException, JsonMappingException, IOException {
		

		List<VisnSelectModel> visnSelectModelList = new ArrayList<VisnSelectModel>();
		
		VisnSelectModel visnSelectModel = new VisnSelectModel();
		visnSelectModel.setId("");
		visnSelectModel.setLabel("All");
		visnSelectModelList.add(visnSelectModel);
		
		visnSelectModelList.addAll(trackMessageService.getVisns());
		
		return visnSelectModelList;
	}

	
	@RequestMapping(value = "/getTrackAuditListCSV", method = {RequestMethod.GET, RequestMethod.POST})
	public void csvExport(HttpServletRequest request, @RequestParam("json") String json,HttpServletResponse response) 
			throws JsonParseException, JsonMappingException, IOException{
		
		try {
			
			String csvFileName = "TrackAudit.csv";
			
			String responseHeaderKey = "Content-Disposition";
			
			String responseHeaderValue = String.format("attachment; filename=\"%s\"",   csvFileName);
			
			response.setContentType("text/csv");
			
			response.setHeader(responseHeaderKey, responseHeaderValue);
			
			List<NcpdpMessageListModel> eRxMessageList = trackAuditSearch(json);
			
			if(null!= eRxMessageList && eRxMessageList.size()>0){
				
				String[][] csvData = populateDataRows(eRxMessageList,	TRACK_AUDIT_HEADERS);		
				
				CSVSupportBean csvSupportBean = new CSVSupportBean();
				
				csvSupportBean.setHeaderRow(TRACK_AUDIT_HEADERS);

				csvSupportBean.setDataRows(csvData);
				
				Map<String,Object> csvModel = csvSupportBean.createModel();
				
				CSVView view = new CSVView();
				
				String data = view.getStringRepresentation(csvModel);
				
				response.getOutputStream().print(data);
				
				response.getOutputStream().flush();
			}
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
	private String[][] populateDataRows(List<NcpdpMessageListModel> rows, String[] headers) {
		// + 1 for the totals as the last row
		String[][] dataRows = new String[rows.size()+1][headers.length];
		for (int i = 0; i < rows.size(); i++) {
			
			String[] row = ((NcpdpMessageListModel) rows.get(i)).getStringArray();
						
			for (int j = 0; j < headers.length; j++) {
				
				dataRows[i][j] = row[j];
				
			}
		}
		
		return dataRows;
		
	}
	

}
