package gov.va.med.esr.service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import gov.va.med.esr.common.model.lookup.ComLetterGeneratedType;
import gov.va.med.esr.common.model.lookup.ComLetterType;
import gov.va.med.esr.common.model.party.Address;
import gov.va.med.esr.common.model.comms.CommsLogSearchQueryInfo;
import gov.va.med.esr.common.model.comms.CommsTemplate;
import gov.va.med.esr.common.model.comms.CommsLogEntry;
import gov.va.med.esr.common.persistent.comms.CommsTemplateDAO;

import gov.va.med.esr.common.util.RuleAbstractTestCase;
import gov.va.med.esr.service.DemographicService;
import gov.va.med.esr.service.LookupService;
import gov.va.med.esr.service.CommsLogService;

import gov.va.med.esr.common.model.person.id.PersonEntityKey;
import gov.va.med.esr.common.model.person.id.PersonIdEntityKeyImpl;
import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.util.CommsLetterConstants;


/**
 * @author DNS   TSAIG
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class TestCommsLogService extends RuleAbstractTestCase {

    private CommsLogService logService = null;
    private CommsLogEntry log = null;

    private LookupService lookupSrv = null;

    public TestCommsLogService(String testName) {
        super(testName);

    }

    public void setUpData() throws Exception {
    }

    public void tearDownData() throws Exception {

    }

    public void testFindBarcode()
    {
        try {

            logService = (CommsLogService) applicationContext.getBean("commsLogService");
            CommsLogSearchQueryInfo queryInfo = new CommsLogSearchQueryInfo();
            queryInfo.setBarcode("157878");

            java.util.List logs = logService.search(queryInfo);

            if(logs == null)
            {
                logger.fatal( "Failed to find the log entry");
                fail( "Failed to findthe log entry");
            }
        }
        catch( Exception e ) {
            fail( "Failed to find the log entry. Exception:" + e );
        }
    }

    public void testFindAllAddress()
    {
        try {

            logService = (CommsLogService) applicationContext.getBean("commsLogService");
            CommsLogSearchQueryInfo queryInfo = new CommsLogSearchQueryInfo();

            Date start = new Date();
            java.util.List logs = logService.search(queryInfo);
            Date end = new Date();

            System.out.println("Number of log entries = "+ logs.size() +" Time = " + start + "-" + end);


        }
        catch( Exception e ) {
            fail( "Failed to find the log entry. Exception:" + e );
        }

    }

    public void testgetPersonAddresses()
    {

        try
        {
            PersonEntityKey key = new PersonIdEntityKeyImpl(new BigDecimal("84379"));

        }
        catch( Exception e ) {
            fail( "Failed to find the log entry. Exception:" + e );
        }




    }

    public void testInsertCommsLogEntry() throws Exception{

        try {
            if (lookupSrv == null)
                lookupSrv = this.getLookupService();

            this.getLoginManager().loginAnonymous();
            log = new CommsLogEntry();
            java.util.Date now = new java.util.Date();
//    		Person person = getPersonService().getPerson(new PersonIdEntityKeyImpl(new BigDecimal("255566")));

//    		log.setAddress((Address)person.getAddresses().iterator().next());
//    		log.setName((Name)person.getLegalName());

            Address addr = new Address();
            addr.setLine1("5400 Legacy Dr");
            addr.setLine2("A3-2B-06");
            addr.setLine3("Line3");
            addr.setCity("Plano");
            addr.setCounty("Collin");
            addr.setCountry("US");
            addr.setProvince("Province");
            addr.setZipPlus4("1234");
            addr.setState("TX");
            addr.setZipCode("75028");

            log.setAddress(addr);


//   	       	log.setAddressId(new BigDecimal("74715"));
               log.setLogXML("This is logXML");
               log.setPersonId(new BigDecimal("255566"));
            log.setRecipient(CommsLetterConstants.RECIPIENT_VETERAN);
            log.setLetterType(lookupSrv.getComLetterTypeByCode("03"));
//    		log.setRemailIndicator(null);

/*    		log.setCode1RejectReason(lookupSrv.getComAACRejectReasonTypeByCode("H"));

    		ComMailingStatusType status = lookupSrv.getComMailingStatusTypeByCode("0");
    		ComMailingStatusType status2 = lookupSrv.getComMailingStatusTypeByCode("01");
    		log.addMailingStatus(status);
    		log.addMailingStatus(status2);
    		
    		
    		ComAACErrorType aacErr = lookupSrv.getComAACErrorTypeByCode("A02");
    		ComAACErrorType aacErr2 = lookupSrv.getComAACErrorTypeByCode("B02");
    		ComAACErrorType aacErr3 = lookupSrv.getComAACErrorTypeByCode("C10");
    		log.addAacErrorReason(aacErr);
    		log.addAacErrorReason(aacErr2);
    		log.addAacErrorReason(aacErr3);*/

            CommsTemplateDAO dao = ((CommsTemplateDAO)applicationContext.getBean("commsTemplateDAO"));
            CommsTemplate templ = (CommsTemplate)dao.findTemplateListByFormNumber("742-600C").get(0);
            log.setTemplate(templ);



//    		status.setReportDate(now);
/*    		
    		HecRejectReason rej= new HecRejectReason("Exception Failed: No address exists");
    		HecRejectReason rej2= new HecRejectReason("Error Msg: Veteran Has No Homeless Indicator");
//    		rej.setReportDate(now);
//    		rej2.setReportDate(now);
    		log.addRejectReason(rej);
    		log.addRejectReason(rej2);
*/
            logService = (CommsLogService) applicationContext.getBean("commsLogService");


            logService.insert(log);

//    		logId = log.getEntityKey().getKeyValueAsString();

            //verify by retriving the log entry just inserted
/*
    		this.getLogEntry(log.getEntityKey().getKeyValueAsString(),
    		        new String[] {"Error Msg: Veteran Has No Homeless Indicator",
    		        			"Exception Failed: No address exists"},
    		        REJECT_AT_HEC);
 */
        }
        catch( Exception e ) {
            fail( "Failed to insert a log entry due to exception", e );
        }

        setComplete();
    }

    public void testLogEntryListByPersonId()
    {
        BigDecimal id = new BigDecimal("67110");
        String idStr = id.toString();

        try {

            String personId = "67110";
            logService = (CommsLogService) applicationContext.getBean("commsLogService");
            java.util.List logs = logService.findLogEntriesByPersonId(personId);

            if(logs == null || logs.size() != 8)
            {
                logger.fatal( "Failed to find 8 log entry");
                fail( "Failed to find 8 log entries");
            }
        }
        catch( Exception e ) {
            fail( "Failed to find 8 log entry. Exception:" + e );
        }
    }


    public void testAppendActionComment()
    {
        BigDecimal id = new BigDecimal("264240");
        String idStr = id.toString();
        CommsLogEntry log = null;
        CommsLogEntry newLog = null;

        try {

            String personId = "67110";
            logService = (CommsLogService) applicationContext.getBean("commsLogService");
            log = logService.getCommsLogEntry(CommonEntityKeyFactory.createCommsLogEntryEntityKey(idStr));
            log.setActionComment("George Comment 1");
            newLog = logService.updateCommunicationLog(log);

            if(log == null)
            {
                logger.fatal( "Failed to find log entry");
                fail( "Failed to find log entries");
            }
        }
        catch( Exception e ) {
            fail( "Failed to find 8 log entry. Exception:" + e );
        }
    }
    /*
     * insert all the enrollment letter templates after R1/R2 (in addtion to
     * 600C, 601B, and 620A in R1/R2)
     */
    public void insertEnrollmentTemplatesAfterR1R2() throws Exception
    {
        CommsTemplate template = null;
        ComLetterType enrollLetterType = null;
        ComLetterType ssnLetterType = null;
        ComLetterGeneratedType both = null;
        ComLetterGeneratedType auto = null;
        ComLetterGeneratedType manual = null;
        CommsTemplateDAO tempDAO = null;

        if (lookupSrv == null)
            lookupSrv = this.getLookupService();
        try
        {
            enrollLetterType = (ComLetterType)lookupSrv.getComLetterTypeByCode("03");
            ssnLetterType = (ComLetterType)lookupSrv.getComLetterTypeByCode("05");
            both = (ComLetterGeneratedType)lookupSrv.getComLetterGeneratedTypeByCode("03");
            auto = (ComLetterGeneratedType)lookupSrv.getComLetterGeneratedTypeByCode("01");
            manual = (ComLetterGeneratedType)lookupSrv.getComLetterGeneratedTypeByCode("02");

            tempDAO = (CommsTemplateDAO)applicationContext.getBean("commsTemplateDAO");
        } catch (Exception ex)
        {
            ex.printStackTrace();
        }

        String[] formNums = {
                "742-600B",
                "724-601A",
                "724-601C",
                "742-601D",
                "742-601E",
                "724-601F",
                "724-623B",
                "724-623A",
                "742-624A",
                "742-624B",
                "742-624C",
                "742-630A",
                "742-630B",
                "742-630C",
                "742-630D",
                "742-630E",
                "742-630F",
                "742-630G",
                "742-630H",
                "742-625A",
                "742-625B",
                "742-625C",
                "742-640A",
                "742-640B",
                "742-640C",
                "742-640D",
                "742-604A",
                "742-604B"
        };

        String[] names ={
                "One Time Enrollment Priority Notification Letter",
                "Ineligible Notification; Enrollment Correction Letter",
                "Does Not Agree to Copay; Provide Opportunity to Agree",
                "Reminder Does Not Agree to Copay; Provide Opportunity to Agree",
                "Does Not Agree to Copay; End Enrollment",
                "Ineligible Notification Letter - No Previous Enrollment Notification",
                "Notify Enrollee Priority Below EGT",
                "Notify Applicant Priority Below EGT",
                "No Previous MT; MT Completion Request",
                "Reminder No Previous MT; MT Completion Request",
                "MT Required; End Enrollment",
                "Unacceptable Purple Heart Documentation",
                "Follow Up on Unacceptable Purple Heart Documentation",
                "Purple Heart Denial",
                "Purple Heart Enrollment Priority Change Letter",
                "Purple Heart Unacceptable Documentation Received; Not Enrolled",
                "Purple Heart Acceptable Documentation Received; Not Enrolled",
                "PH Confirmation; No Priority Change (Priority 2 or 3)",
                "PH Confirmation; No Priority Change (Priority 1)",
                "Proof of Eligibility Request",
                "Reminder; Proof of Eligibility Request",
                "Not Eligible; End Enrollment",
                "Priority Change Notification; Miscellaneous",
                "Priority Change Notification; Catastrophic Disability",
                "Priority Change Notification; POW",
                "MT Status Change Notification",
                "One-Time Notification of Conversion to Priority 8",
                "One-Time Notification of Conversion to GMT Copay"
        };

        String[] descs = {
                "One-time letter sent to current enrollees, notifying them of their priority group. The letter includes due process rights.",
                "This is the Veteran Correction Letter for ineligible veterans who were previously sent any one of the following Enrollment Notification Letters: 600A, 600B, 600C, 607A, or 607B, in error.",
                "Letter sent to veterans whose latest MT = Agree to copay = No and now do not agree to copayments. The letter will inform veteran of the ramifications for failing to agree & provide veteran with the 10-10EZ form to complete.",
                "Reminder letter sent, 45 days after 601C letter, to veterans who do not agree to pay copayments to remind veteran that they will be ineligible for enrollment/care of NSC conditions if they do not agree to copayment.",
                "Letter sent, 45 days after 601D letter, to veterans who do not agree to pay copayments to notify them that they are not no longer eligible for enrollment/care of NSC conditions due to refusal to agree to copayment.",
                "This is the letter for ineligible veterans who were NOT previously sent any one of the following Enrollment Notification Letters:  600A, 600B, 600C, 607A, or 607B in error.",
                "Notifies enrollees under the EGT that their enrollment will be discontinued as of the EGT EFFECTIVE DATE.",
                "Notifies enrollment applicants under the EGT that they have not been enrolled.",
                "This letter shall be sent to any applicant who has not completed a Means Test.",
                "Mailing to veterans currently in a \"Pending: Means Test Required\" enrollment status who have not responded to the first letter within 45 days.  (This includes the 30-day return by period plus the 15-day processing period on-site.)",
                "Letter sent to applicants who have not completed a Means Test to notify them that they cannot be enrolled due to their failure to complete a 10-10EZ. Sent after the 624B Reminder letter.",
                "This letter is sent to veterans who submitted inadequate documentation to support PH status and to request additional documentation.",
                "This letter is sent to veterans who submitted additional documentation that also failed to support PH Status.",
                "This letter is sent to veterans who failed to respond to the request to submit additional documentation to support PH status.",
                "A letter is generated for a veteran whose enrollment priority has changed as a result of the PH Award.",
                "Letter sent to veterans provided unacceptable documentation to support PH status and who are not yet enrolled.",
                "Letter sent to veterans who provided acceptable documentation to support PH status and who are not yet enrolled.",
                "This letter is mailed to veterans who are confirmed purple heart, but did not experience an improvement to their existing priority group.  This applies to all veterans currently in a priority group 2 or 3.",
                "This letter is mailed to veterans who are confirmed purple heart, but did not experience an improvement to their existing priority group.  This applies to all veterans currently in a priority group 1.",
                "This letter shall be sent to any veteran/applicant who has missing or unverified eligibility information.  This starts an 88-day process.",
                "This is the letter that is sent 45 days after the initial Proof of Eligibility Request (625A) if there is no response received.  This starts a 45-day process.",
                "This is the letter that is sent to a veteran who does not provide missing or unverified eligibility information within the required time period for due process (45 days after 625B letter).",
                "The letter sent to notify veterans that their priority for enrollment has changed. It is sent for all priority changes other than those associated with Catastrophic Disability, POW, or GMT Conversion.",
                "This is the letter that is sent to any veteran whose priority level changes due to catastrophic disability determination.  This results in a change to priority group \"4\".",
                "This is the letter that is sent to any POW veteran whose priority level changes.  This results in a change to priority group \"3\".",
                "Letter notifying veteran of change in enrollment priority/copay status.",
                "This letter is sent to veterans who were converted to Priority 8 and agree to pay MT copayments or have income above the GMT threshold.",
                "This letter is sent to veterans who were converted to GMT Copayment Required for Priority 4, 6, or 7 by GMT Conversion."
        };

        for (int i=0; i< formNums.length; i++)
        {
            template = new CommsTemplate();

            template.setCommsTemplateFormNumber(formNums[i]);
            template.setCommsTemplateName(names[i]);
            template.setCommsTemplateDesc(descs[i]);
            template.setLetterType(enrollLetterType);

            if (formNums[i].equals("742-600B") ||
                formNums[i].equals("742-601F") ||
                formNums[i].equals("742-625A"))
            {
                template.setGenerationType(manual);
            } else
            {
                if (formNums[i].equals("742-625C"))
                    template.setGenerationType(auto);
                else
                    template.setGenerationType(both);
            }

            if (tempDAO != null) {
            	tempDAO.insert(template);
            }

        }
//        setComplete();

    }

    public void insertSsnTemplates() throws Exception
    {
        CommsTemplate template = null;
        ComLetterType ssnLetterType = null;
        ComLetterGeneratedType both = null;
        CommsTemplateDAO tempDAO = null;

        if (lookupSrv == null)
            lookupSrv = this.getLookupService();
        try
        {
            ssnLetterType = (ComLetterType)lookupSrv.getComLetterTypeByCode("05");
            both = (ComLetterGeneratedType)lookupSrv.getComLetterGeneratedTypeByCode("03");

            tempDAO = (CommsTemplateDAO)applicationContext.getBean("commsTemplateDAO");
        } catch (Exception ex)
        {
            ex.printStackTrace();
        }

        String[] formNums = {
                "742-290 ",
                "742-291",
                "742-298",
                "742-299"
        };

        String[] names ={
                "SSN Validation Letter - Veteran",
                "Veteran SSN Reminder Letter",
                "SSN Validation Letter - Spouse",
                "Spouse SSN Reminder Letter "
        };

        String[] descs = {
                "This letter is sent when the SSN validation flag is set to invalid for only the veteran's social security number.",
                "This letter is sent 45 days after the Veteran SSN Validation letter (290) has been sent and no reply has been received by Income Verification.",
                "This letter is sent when the SSN validation flag is set to invalid for only the spouse's social security numbers.",
                "This letter is sent 45 days after the Spouse SSN letter (298) has been sent and no reply has been received."
        };

        for (int i=0; i< formNums.length; i++)
        {
            template = new CommsTemplate();

            template.setCommsTemplateFormNumber(formNums[i]);
            template.setCommsTemplateName(names[i]);
            template.setCommsTemplateDesc(descs[i]);
            template.setLetterType(ssnLetterType);
            template.setGenerationType(both);

            if (tempDAO != null) {
            	tempDAO.insert(template);
            }

        }
//        setComplete();

    }
}
