package gov.va.med.esr.common.batchprocess;

import java.util.List;
import java.util.Date;
import java.lang.StringBuffer;

import gov.va.med.esr.common.model.comms.AacLetterRequest;
import gov.va.med.esr.common.model.comms.CommsLogEntry;
import gov.va.med.esr.common.model.comms.CommsTemplate;
import gov.va.med.esr.common.model.financials.IncomeTest;
import gov.va.med.esr.common.model.lookup.ComLetterTemplateType;
import gov.va.med.esr.common.model.lookup.ComLetterType;
import gov.va.med.esr.common.model.lookup.AddressType;
import gov.va.med.esr.common.model.lookup.AssociationType;
import gov.va.med.esr.common.model.lookup.Gender;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.Association;
import gov.va.med.esr.common.util.CommsLetterConstants;
import gov.va.med.esr.common.util.RuleAbstractTestCase;
import gov.va.med.esr.service.FinancialsHelperService;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.esr.common.builder.comms.DocumentBuilder;
import gov.va.med.esr.common.builder.comms.EnrollTransmission;
import gov.va.med.esr.common.builder.comms.GeneralTransmission;
import gov.va.med.esr.common.builder.comms.GenerateValues;
import gov.va.med.esr.common.builder.comms.ITransmission;
import gov.va.med.esr.common.builder.comms.InsufficientDataException;
import gov.va.med.esr.common.builder.comms.SsnTransmission;
import gov.va.med.esr.common.model.comms.CommsTransByFormNumber;
import gov.va.med.esr.common.model.comms.CommsTransLog;
import gov.va.med.esr.common.persistent.comms.CommsTemplateDAO;
import gov.va.med.esr.common.persistent.comms.ExportFileDAO;

public class TestCommsBuilders extends RuleAbstractTestCase {
	
	public TestCommsBuilders(String testName) {
		super(testName);
	}
	


	public void testBuilderAndFormatter() throws Exception {
        DocumentBuilder builder = new DocumentBuilder();
        Person person = this.buildSimplePerson();
        person.addAddress(this.createAddress(
        		this.getLookupService().getAddressTypeByCode(AddressType.CODE_PERMANENT_ADDRESS.getCode())));
        ExportFileDAO fileDAO = (ExportFileDAO)applicationContext.getBean("exportFileDAO");
        CommsTemplateDAO dao = ((CommsTemplateDAO) applicationContext.getBean("commsTemplateDAO"));
        CommsTemplate template = (CommsTemplate) dao
                .findTemplateListByFormNumber("742-600C").get(0);        
        
        String fileName = fileDAO.getAacFileName(fileDAO.getAacExtractId());        
        CommsLogEntry log = new CommsLogEntry();
        CommsTemplate templ = new CommsTemplate();
        templ.setLetterType(this.getLookupService().getComLetterTypeByCode(ComLetterType.CODE_IVM.getCode()));
        templ.setCommsTemplateName("Copay Exempt(Priority Group 5)");
        
        log.setTemplate(templ);
        templ.setCommsTemplateFormNumber(ComLetterTemplateType.FORM_NUMBER_400.getCode());
        AacLetterRequest request = new AacLetterRequest();
        request.setCommsLogEntry(log);


        // set the mailing address in the log entry so that we can
        // check the letter rules
        //build the ASCII text
        List textLst = null;
        try {
        	//builder return a list of ASCII text String
        	//for now, index 0 as veteran letter, index 1+ as POA letter if exists
        	GenerateValues values = this.getInputValues(person, request);
        	values.setAacExtractId(fileDAO.getAacExtractId());
        	values.setPrintLocationCd(CommsLetterConstants.MAIL_CENTER_CMS);
        	log.setAddress(((GeneralTransmission) values.getTransmission())
        			.getMailingAdress());        

        	textLst = builder.build(person, values);
        	System.out.println(textLst.get(0));
        }
        catch (InsufficientDataException idex) {
        	logger.error("ERROR: Insufficient Data to build a letter while requesting an AAC letter", idex);
        	throw new ServiceException(idex.toString());
        }

	}

	public void testBuilderAndFormatterCompassionLetter() throws Exception {
        DocumentBuilder builder = new DocumentBuilder();
        Person person = this.buildSimplePerson();
        Association nok = this.createAssociation("none", "brother");
        nok.getRepresentativeName().setPrefix(null);
        nok.getRepresentativeName().setMiddleName("nokMiddleName");
        Gender g = this.getLookupService().getGenderByCode(Gender.MALE.getCode());
        person.setGender(g);
        nok.setType(this.getLookupService().getAssociationTypeByCode(AssociationType.CODE_PRIMARY_NEXT_OF_KIN.getCode()));

        person.addAssociation(nok);
        person.addAddress(this.createAddress(
        		this.getLookupService().getAddressTypeByCode(AddressType.CODE_PERMANENT_ADDRESS.getCode())));
        
        ExportFileDAO fileDAO = (ExportFileDAO)applicationContext.getBean("exportFileDAO");
        CommsTemplateDAO dao = ((CommsTemplateDAO) applicationContext.getBean("commsTemplateDAO"));
        String fileName = fileDAO.getAacFileName(fileDAO.getAacExtractId());        

        CommsTemplate templ = (CommsTemplate) dao.findTemplateListByFormNumber("683A").get(0);        
        CommsLogEntry log = new CommsLogEntry();     
        log.setIvmCaseClosureDate(new Date());
        log.setIvmCaseNumber("34535");
        log.setTemplate(templ);
        log.setBarcode("FAKEBID");
        AacLetterRequest request = new AacLetterRequest();
        request.setCommsLogEntry(log);
        List textLst = null;
        try {
        	//builder return a list of ASCII text String
        	//for now, index 0 as veteran letter, index 1+ as POA letter if exists
        	GenerateValues values = this.getInputValues(person, request);
        	values.setAacExtractId(fileDAO.getAacExtractId());
        	values.setPrintLocationCd(CommsLetterConstants.MAIL_CENTER_CMS);
        	log.setAddress(((GeneralTransmission) values.getTransmission())
        			.getMailingAdress());        

        	textLst = builder.build(person, values);
        	System.out.println(textLst.get(0));
        }
        catch (InsufficientDataException idex) {
        	logger.error("ERROR: Insufficient Data to build a letter while requesting an AAC letter", idex);
        	throw new ServiceException(idex.toString());
        }

	}
	
	public void testBuilderAndFormatterCompassionLetterNullMiddle() throws Exception {
        DocumentBuilder builder = new DocumentBuilder();
        Person person = this.buildSimplePerson();
        Association nok = this.createAssociation("none", "brother");
        nok.getRepresentativeName().setPrefix(null);
        nok.getRepresentativeName().setMiddleName(null);
        Gender g = this.getLookupService().getGenderByCode(Gender.MALE.getCode());
        person.setGender(g);
        nok.setType(this.getLookupService().getAssociationTypeByCode(AssociationType.CODE_PRIMARY_NEXT_OF_KIN.getCode()));

        person.addAssociation(nok);
        person.addAddress(this.createAddress(
        		this.getLookupService().getAddressTypeByCode(AddressType.CODE_PERMANENT_ADDRESS.getCode())));
        
        ExportFileDAO fileDAO = (ExportFileDAO)applicationContext.getBean("exportFileDAO");
        CommsTemplateDAO dao = ((CommsTemplateDAO) applicationContext.getBean("commsTemplateDAO"));
        String fileName = fileDAO.getAacFileName(fileDAO.getAacExtractId());        

        CommsTemplate templ = (CommsTemplate) dao.findTemplateListByFormNumber("683A").get(0);        
        CommsLogEntry log = new CommsLogEntry();     
        log.setIvmCaseClosureDate(new Date());
        log.setIvmCaseNumber("34535");
        log.setTemplate(templ);
        log.setBarcode("FAKEBID");
        AacLetterRequest request = new AacLetterRequest();
        request.setCommsLogEntry(log);
        List textLst = null;
        try {
        	//builder return a list of ASCII text String
        	//for now, index 0 as veteran letter, index 1+ as POA letter if exists
        	GenerateValues values = this.getInputValues(person, request);
        	values.setAacExtractId(fileDAO.getAacExtractId());
        	values.setPrintLocationCd(CommsLetterConstants.MAIL_CENTER_CMS);
        	log.setAddress(((GeneralTransmission) values.getTransmission())
        			.getMailingAdress());        

        	textLst = builder.build(person, values);
        	System.out.println(textLst.get(0));
        }
        catch (InsufficientDataException idex) {
        	logger.error("ERROR: Insufficient Data to build a letter while requesting an AAC letter", idex);
        	throw new ServiceException(idex.toString());
        }

	}	
	
	public void testBuilderAndFormatterFinalLetter() throws Exception {
        DocumentBuilder builder = new DocumentBuilder();
        Person person = this.buildSimplePerson();
        person.getLegalName().setPrefix(null);
        person.getLegalName().setMiddleName("MIDDLENAMECCR12890");
        Gender g = this.getLookupService().getGenderByCode(Gender.MALE.getCode());
        person.setGender(g);
        person.addAddress(this.createAddress(
        		this.getLookupService().getAddressTypeByCode(AddressType.CODE_PERMANENT_ADDRESS.getCode())));
        
        ExportFileDAO fileDAO = (ExportFileDAO)applicationContext.getBean("exportFileDAO");
        CommsTemplateDAO dao = ((CommsTemplateDAO) applicationContext.getBean("commsTemplateDAO"));
        String fileName = fileDAO.getAacFileName(fileDAO.getAacExtractId());        

        CommsTemplate templ = (CommsTemplate) dao.findTemplateListByFormNumber("742-450").get(0);        
        CommsLogEntry log = new CommsLogEntry();     
        log.setIvmCaseClosureDate(new Date());
        log.setIvmCaseNumber("34535");
        log.setTemplate(templ);
        log.setBarcode("FAKEBID");
        AacLetterRequest request = new AacLetterRequest();
        request.setCommsLogEntry(log);
        List textLst = null;
        try {
        	//builder return a list of ASCII text String
        	//for now, index 0 as veteran letter, index 1+ as POA letter if exists
        	GenerateValues values = this.getInputValues(person, request);
        	values.setAacExtractId(fileDAO.getAacExtractId());
        	values.setPrintLocationCd(CommsLetterConstants.MAIL_CENTER_CMS);
        	log.setAddress(((GeneralTransmission) values.getTransmission())
        			.getMailingAdress());        

        	textLst = builder.build(person, values);
        	System.out.println(textLst.get(0));
        }
        catch (InsufficientDataException idex) {
        	logger.error("ERROR: Insufficient Data to build a letter while requesting an AAC letter", idex);
        	throw new ServiceException(idex.toString());
        }

	}
	
	public void testBuilderAndFormatterFinalLetterMiddleNull() throws Exception {
        DocumentBuilder builder = new DocumentBuilder();
        Person person = this.buildSimplePerson();
        person.getLegalName().setPrefix(null);
        person.getLegalName().setMiddleName(null);
        Gender g = this.getLookupService().getGenderByCode(Gender.MALE.getCode());
        person.setGender(g);
        person.addAddress(this.createAddress(
        		this.getLookupService().getAddressTypeByCode(AddressType.CODE_PERMANENT_ADDRESS.getCode())));
        
        ExportFileDAO fileDAO = (ExportFileDAO)applicationContext.getBean("exportFileDAO");
        CommsTemplateDAO dao = ((CommsTemplateDAO) applicationContext.getBean("commsTemplateDAO"));
        String fileName = fileDAO.getAacFileName(fileDAO.getAacExtractId());        

        CommsTemplate templ = (CommsTemplate) dao.findTemplateListByFormNumber("742-450").get(0);        
        CommsLogEntry log = new CommsLogEntry();     
        log.setIvmCaseClosureDate(new Date());
        log.setIvmCaseNumber("34535");
        log.setTemplate(templ);
        log.setBarcode("FAKEBID");
        AacLetterRequest request = new AacLetterRequest();
        request.setCommsLogEntry(log);
        List textLst = null;
        try {
        	//builder return a list of ASCII text String
        	//for now, index 0 as veteran letter, index 1+ as POA letter if exists
        	GenerateValues values = this.getInputValues(person, request);
        	values.setAacExtractId(fileDAO.getAacExtractId());
        	values.setPrintLocationCd(CommsLetterConstants.MAIL_CENTER_CMS);
        	log.setAddress(((GeneralTransmission) values.getTransmission())
        			.getMailingAdress());        

        	textLst = builder.build(person, values);
        	System.out.println(textLst.get(0));
        }
        catch (InsufficientDataException idex) {
        	logger.error("ERROR: Insufficient Data to build a letter while requesting an AAC letter", idex);
        	throw new ServiceException(idex.toString());
        }

	}		
	
	private GenerateValues getInputValues(Person person, AacLetterRequest request)throws ServiceException
	{
		CommsLogEntry log = request.getCommsLogEntry();
		CommsTemplate templ = log.getTemplate();
		String formNumber = templ.getCommsTemplateFormNumber();

		ITransmission trans = getTransmission(formNumber, person, request.getCommsLogEntry());


		GenerateValues inputValues = new GenerateValues(person, formNumber, null,
				log.getWorkflowCaseId(), trans);

		inputValues.setPrintLocationCd(CommsLetterConstants.MAIL_CENTER_AAC);
		inputValues.setOrigTemplate(templ);
		inputValues.setCommsLog(log);
		if(request.isVeteranLetter())
			inputValues.setCategoryType(AacLetterRequest.VETERAN_LETTER);
		else if(request.isSpouseLetter())
			inputValues.setCategoryType(AacLetterRequest.SPOUSE_LETTER);
		else if(request.isDependentLetter())
			inputValues.setCategoryType(AacLetterRequest.DEPENDENT_LETTER);


		return inputValues;
	}
	   
	private ITransmission getTransmission(String formNumber, Person person, CommsLogEntry log) throws ServiceException
	{
		if (formNumber == null)
			return null;

		ITransmission trans = null;

		if (ComLetterTemplateType.FORM_NUMBER_290.getCode().equals(formNumber) ||
				ComLetterTemplateType.FORM_NUMBER_291.getCode().equals(formNumber) ||
				ComLetterTemplateType.FORM_NUMBER_292.getCode().equals(formNumber) ||
				ComLetterTemplateType.FORM_NUMBER_293.getCode().equals(formNumber) ||
				ComLetterTemplateType.FORM_NUMBER_298.getCode().equals(formNumber) ||
				ComLetterTemplateType.FORM_NUMBER_299.getCode().equals(formNumber))
		{
			SsnTransmission ssnTrans = new SsnTransmission(person, log.getWorkflowCaseId());
			ssnTrans.setFormNumber(formNumber);
			ssnTrans.setHelperService(this.getPersonHelperService());
			trans = ssnTrans;
		} else
		{
			// get the data objects - transmission and inputValues
			EnrollTransmission enrTrans = new EnrollTransmission(person, log.getWorkflowCaseId());
			enrTrans.setFormNumber(formNumber);
			enrTrans.setHelperService(this.getPersonHelperService());

			String mostRecentNonNullPriorityLevel = "8C";
			enrTrans.setMostRecentNonNullPriorityLevel(mostRecentNonNullPriorityLevel);

			// init "current" IncomeTest
			IncomeTest currentIncomeTest = this.getPersonHelperService().getCurrentIncomeTest(person);
			enrTrans.setLocalIncomeTest(currentIncomeTest);

			//calculate and set income threshold for financial information
			if (currentIncomeTest != null) {
				Integer currentIncomeYear = currentIncomeTest.getIncomeYear();

				if (currentIncomeYear != null) {
					Integer total = (currentIncomeTest.getTotalNumberOfDependents() != null) ? currentIncomeTest.getTotalNumberOfDependents() : new Integer(0);
					enrTrans.setIncomeThreshold(((FinancialsHelperService)this.applicationContext.getBean("financialsHelperService"))
							.calculateIncomeThresholds(currentIncomeYear, total));
				}
			}
			trans = enrTrans;

		}

		return trans;
	}

	public void testNewFormTemplates() throws Exception {

	}
}
