package gov.va.med.esr.service;



// Java classes

// Library classes

// Framework classes

// ESR classes
import java.math.BigDecimal;

import gov.va.med.esr.common.clock.Clock;
import gov.va.med.esr.common.model.ee.PurpleHeart;
import gov.va.med.esr.common.model.ee.PurpleHeartDocument;
import gov.va.med.esr.common.model.lookup.DecorationStatus;
import gov.va.med.esr.common.model.lookup.EnrollmentPriorityGroup;
import gov.va.med.esr.common.model.lookup.PHDocumentType;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.lookup.EnrollmentStatus;
import gov.va.med.esr.common.model.lookup.WkfCaseType;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.id.PersonIdEntityKeyImpl;
import gov.va.med.esr.service.PurpleHeartService;
import gov.va.med.esr.service.WorkflowService;
import gov.va.med.esr.common.util.RuleAbstractTestCase;
import gov.va.med.esr.common.model.cases.WorkflowCase;

public class PurpleHeartServiceTest extends RuleAbstractTestCase {

    private PurpleHeartService purpleHeartService = null;
    private WorkflowService workflowService = null;
    
    public PurpleHeartServiceTest(String testName) {
        super(testName);
        // TODO Auto-generated constructor stub
    }
    public void testPHDocumentationAcceptable() throws Exception 
    {
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("457752"));        
        Person upd = this.getPersonService().getPerson(personKey);
        Person incoming = (Person)upd.clone();

        this.getPurpleHeartService().updatePurpleHeart(incoming);
        
       /* 
        assertEquals(1, updated.getDecorations().size());
        PurpleHeart resultPurpleHeart = updated.getPurpleHeart();
        assertNotNull(resultPurpleHeart);
        
        Boolean PHIndicator = resultPurpleHeart.getPhIndicator();
        assertTrue("Indicator is set to false.",PHIndicator.booleanValue());
        String purpleHeartStatus = resultPurpleHeart.getStatus().getCode();
        assertEquals(DecorationStatus.CODE_CONFIRMED.getName(), purpleHeartStatus);
        String facility = resultPurpleHeart.getFacility().getCode();
        assertEquals(facility,VAFacility.CODE_HEC.getName());
        
        // The incoming PH had no remark text so processing should reset text 
        assertNull(resultPurpleHeart.getRejectionRemark());
        */
    }
    
    public void testPHYesToNo() throws Exception 
    {
        Person onFile = buildSimplePerson();
        this.attachVerifiedEnrollment(onFile);
        this.attachPurpleHeartWithPHStatusPending(onFile);        
        Person updated = this.getPersonService().save(onFile);
        
        Person incoming = (Person)updated.clone();        
        attachFacilityToPurpleHeart(incoming,VAFacility.CODE_HEC.getName());
        PurpleHeartDocument purpleHeartDocument = new PurpleHeartDocument();
        purpleHeartDocument.setAcceptable(Boolean.FALSE);
        purpleHeartDocument.setDocumentType((PHDocumentType)this.getLookupService().getByCode(PHDocumentType.class,"1"));
        purpleHeartDocument.setReceivedDate(this.getDate(2005,1,1));  // I tested for validation error with future date already      
        incoming.getPurpleHeart().addDocument(purpleHeartDocument);
        incoming.getPurpleHeart().setPhIndicator(Boolean.FALSE);
        incoming.getPurpleHeart().setRejectionRemark(this.getLookupService().getRejectionRemarkByCode("1"));        

        Person result = this.getPurpleHeartService().updatePurpleHeart(incoming);
        
        PurpleHeart resultPurpleHeart = result.getPurpleHeart();
        assertFalse(resultPurpleHeart.getPhIndicator().booleanValue());              
    }
    
    public void test4133() throws Exception 
    {
        Person onFile = buildSimplePerson();
        this.attachVerifiedEnrollment(onFile);
        this.attachPurpleHeartWithPHStatusPending(onFile);        
        Person updated = this.getPersonService().save(onFile);
        
        Person incoming = (Person)updated.clone();        
        this.setPurpleHeartStatus(DecorationStatus.CODE_INITIAL_LETTER_SENT, incoming);     
        Person result = this.getPurpleHeartService().updatePurpleHeart(incoming);
        
        PurpleHeart resultPurpleHeart = result.getPurpleHeart();
        assertTrue(resultPurpleHeart.getPhIndicator().booleanValue());              

    }       
    
    public void test630A() throws Exception {
        //288740
        /*
         * IF isExistingPerson and incoming PHDocument is not Acceptable AND
         * Prior document Document was Acceptable AND incoming
         * PurpleHeartIndicator = "Y" AND incoming PurpleHeartStatus = "4" &&
         * Prior PurpleHeartStatus != "4" THEN send 630A
         */
        // 4 is initial letter sent
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("72006"));        
        Person updated = this.getPersonService().getPerson(personKey);
        Person incoming = (Person)updated.clone();
        this.setPurpleHeartStatus(DecorationStatus.CODE_INITIAL_LETTER_SENT, incoming);
        ((PurpleHeartDocument)incoming.getPurpleHeart().getDocuments().iterator().next()).setAcceptable(Boolean.FALSE);
        this.getPurpleHeartService().updatePurpleHeart(incoming);
    }
    
    public void test630C() throws Exception {
        //288740
        /*
         * IF isExistingPerson and incoming PHDocument is not Acceptable AND
         * Prior document Document was Acceptable AND incoming
         * PurpleHeartIndicator = "Y" AND incoming PurpleHeartStatus = "4" &&
         * Prior PurpleHeartStatus != "4" THEN send 630A
         */
        // 4 is initial letter sent
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("72006"));        
        Person updated = this.getPersonService().getPerson(personKey);
        Person incoming = (Person)updated.clone();
        this.setPurpleHeartStatus(DecorationStatus.CODE_INITIAL_LETTER_SENT, incoming);
        ((PurpleHeartDocument)incoming.getPurpleHeart().getDocuments().iterator().next()).setAcceptable(Boolean.FALSE);
        this.getPurpleHeartService().updatePurpleHeart(incoming, Clock.Type.PH_37_DAY_CLOCK );
    }    
    public void testPH37DAYCLOCK() throws Exception {
    	// CCR 12484 test for George 
        Person onFile = this.buildSimplePerson();
        this.attachVerifiedEnrollment(onFile);
        this.attachPurpleHeartWithPHStatusPending(onFile);
        this.setPurpleHeartStatus(DecorationStatus.CODE_INITIAL_LETTER_SENT, onFile);
        onFile.getPurpleHeart().setRejectionRemark(null);        
        Person incoming = this.savePerson(onFile);
        Person result = this.getPurpleHeartService().updatePurpleHeart(incoming, Clock.Type.PH_37_DAY_CLOCK );
        assertNotNull(result.getPurpleHeart());
        assertNotNull(result.getPurpleHeart().getRejectionRemark());        
    }
    public void testPH14DAYCLOCK() throws Exception {
    	// CCR 12484 test for George 
        Person onFile = this.buildSimplePerson();
        this.attachVerifiedEnrollment(onFile);
        this.attachPurpleHeartWithPHStatusPending(onFile);
        onFile.getPurpleHeart().setRejectionRemark(null);
        this.setPurpleHeartStatus(DecorationStatus.CODE_PENDING, onFile);
        Person incoming = this.savePerson(onFile);
        Person result = this.getPurpleHeartService().updatePurpleHeart(incoming, Clock.Type.PH_14_DAY_CLOCK);
        assertNotNull(result.getPurpleHeart());
        assertNotNull(result.getPurpleHeart().getRejectionRemark());        
    }        
    
    public void test1UpdatePersonFor630A() throws Exception {
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("288740"));        
        Person updated = this.getPersonService().getPerson(personKey);
        Person incoming = (Person)updated.clone();
        this.attachPurpleHeartWithPHStatusPending(incoming);
        this.setPurpleHeartStatus(DecorationStatus.CODE_INITIAL_LETTER_SENT, incoming);
        this.getPurpleHeartService().updatePurpleHeart(incoming, Clock.Type.PH_37_DAY_CLOCK);
        this.setComplete();
    }
    
    public void test2UpdatePersonFor630A() throws Exception {
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("288740"));        
        Person updated = this.getPersonService().getPerson(personKey);
        Person incoming = (Person)updated.clone();
        this.setPurpleHeartStatus(DecorationStatus.CODE_PENDING, incoming);
        ((PurpleHeartDocument)incoming.getPurpleHeart().getDocuments().iterator().next()).setAcceptable(Boolean.TRUE);
        this.getPurpleHeartService().updatePurpleHeart(incoming);
        this.setComplete();
    }        
 
    // 630H test
    
    /*
     * 
  Person incoming = this.getPersonService().getPerson(personKey);
        Person updated = (Person)incoming.clone();
        this.setEnrollmentStatus(EnrollmentStatus.CODE_VERIFIED.getName(), updated);        
        this.setEnrollmentPriority(updated, code);        
        this.setPurpleHeartStatus(DecorationStatus.CODE_CONFIRMED, updated);         
     */
    
    public void test630H_PH() throws Exception {
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("293607"));        
        Person updated = this.getPersonService().getPerson(personKey);
        Person incoming = (Person)updated.clone();
        this.setEligibilityStatusToVerified(incoming);

        this.attachPurpleHeartWithPHStatusPending(incoming);
        this.setPurpleHeartStatus(DecorationStatus.CODE_CONFIRMED, incoming);
        PurpleHeartDocument purpleHeartDocument = new PurpleHeartDocument();
        purpleHeartDocument.setAcceptable(Boolean.TRUE);
        purpleHeartDocument.setDocumentType((PHDocumentType)this.getLookupService().getByCode(PHDocumentType.class,"1"));
        purpleHeartDocument.setReceivedDate(this.getDate(2005,1,1));  // I tested for validation error with future date already      
        incoming.getPurpleHeart().addDocument(purpleHeartDocument);        
        this.getPurpleHeartService().updatePurpleHeart(incoming);
        this.setComplete();
    }
    
    public void update630H_PH() throws Exception {
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("293484"));        
        Person updated = this.getPersonService().getPerson(personKey);
        this.setEligibilityStatusToVerified(updated);
           this.getPersonService().save(updated);
        updated.getEnrollmentDetermination().setEnrollmentStatus(this.getLookupService().getEnrollmentStatusByCode(EnrollmentStatus.CODE_VERIFIED.getCode()));           
        this.setComplete();
    }    
    
    public void createPHPerson() throws Exception {
        Person incoming = this.createPHPerson(EnrollmentPriorityGroup.GROUP_3);
        Person updated = this.getPersonService().save(incoming);
        WorkflowCase item = this.getWorkflowService().getWorkItem(updated, this.getLookupService().getWkfCaseTypeByCode(WkfCaseType.CODE_PURPLE_HEART.getCode()), true);
        this.getWorkflowService().update(item);
        this.setComplete();
        System.out.println("Person id=" + incoming.getPersonEntityKey().getKeyValueAsString());        
    }
    
    public void createPerson() throws Exception {
        Person incoming = this.buildSimplePerson();
        this.attachApplication(incoming);
        Person updated = this.getPersonService().save(incoming);

        this.setComplete();
        System.out.println("Person id=" + updated.getPersonEntityKey().getKeyValueAsString());        
    }
    
    public void testFirstPHDocumentationAcceptable() throws Exception 
    {
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("457789"));        
        Person upd = this.getPersonService().getPerson(personKey);
        Person incoming = (Person)upd.clone();
        this.attachPurpleHeartWithPHStatusPending(incoming);
        incoming.getPurpleHeart().setAssignedContactUser("test user");
        this.setPurpleHeartStatus(DecorationStatus.CODE_CONFIRMED, incoming);
        PurpleHeartDocument purpleHeartDocument = new PurpleHeartDocument();
        purpleHeartDocument.setAcceptable(Boolean.TRUE);
        purpleHeartDocument.setDocumentType((PHDocumentType)this.getLookupService().getByCode(PHDocumentType.class,"1"));
        purpleHeartDocument.setReceivedDate(this.getDate(2005,1,1));  // I tested for validation error with future date already      
        incoming.getPurpleHeart().addDocument(purpleHeartDocument);        

        this.getPurpleHeartService().updatePurpleHeart(incoming);
        
       /* 
        assertEquals(1, updated.getDecorations().size());
        PurpleHeart resultPurpleHeart = updated.getPurpleHeart();
        assertNotNull(resultPurpleHeart);
        
        Boolean PHIndicator = resultPurpleHeart.getPhIndicator();
        assertTrue("Indicator is set to false.",PHIndicator.booleanValue());
        String purpleHeartStatus = resultPurpleHeart.getStatus().getCode();
        assertEquals(DecorationStatus.CODE_CONFIRMED.getName(), purpleHeartStatus);
        String facility = resultPurpleHeart.getFacility().getCode();
        assertEquals(facility,VAFacility.CODE_HEC.getName());
        
        // The incoming PH had no remark text so processing should reset text 
        assertNull(resultPurpleHeart.getRejectionRemark());
        */
    }    
    
    public void create630PHPerson() throws Exception {
        Person onFile = this.buildSimplePerson();
        this.attachVerifiedEnrollment(onFile);
        Person updated = this.getPersonService().save(onFile);
        Person incoming = (Person)updated.clone();
        this.setEligibilityStatusToVerified(incoming);        
        this.setServiceConnectedPercentage(new Integer(100), incoming);
        Person result = this.getEligibilityEnrollmentService().updateEligibilityData(incoming);
        
        this.setComplete();
        System.out.println("Person id=" + result.getEntityKey().getKeyValueAsString());                
    }   
    
    protected Person createPHPerson(EnrollmentPriorityGroup.Code code) throws Exception {
        Person onFile = this.buildSimplePerson();
        this.attachVerifiedEnrollment(onFile);
        this.setEnrollmentPriority(onFile, code);     
        this.attachPurpleHeartWithPHStatusPending(onFile);
        this.setEligibilityStatusToVerified(onFile);
        PurpleHeartDocument purpleHeartDocument = new PurpleHeartDocument();
        purpleHeartDocument.setAcceptable(Boolean.TRUE);
        purpleHeartDocument.setDocumentType((PHDocumentType)this.getLookupService().getByCode(PHDocumentType.class,"1"));

        onFile.getPurpleHeart().addDocument(purpleHeartDocument);
        
        
        return onFile;
    }
    
    
    
    /**
     * @return Returns the purpleHeartService.
     */
    public PurpleHeartService getPurpleHeartService() {
        return purpleHeartService;
    }
    
    /**
     * @param purpleHeartService The purpleHeartService to set.
     */
    public void setPurpleHeartService(PurpleHeartService purpleHeartService) {
        this.purpleHeartService = purpleHeartService;
    }
    
    protected void setEnrollmentPriority (Person person, EnrollmentPriorityGroup.Code type) throws Exception {
        person.getEnrollmentDetermination().setPriorityGroup(this.getLookupService().getEnrollmentPriorityGroupByCode(type.getName()));
    }
    /**
     * @return Returns the workflowService.
     */
    public WorkflowService getWorkflowService() {
        return workflowService;
    }
    /**
     * @param workflowService The workflowService to set.
     */
    public void setWorkflowService(WorkflowService workflowService) {
        this.workflowService = workflowService;
    }    
    
    public void test3985() throws Exception {
        Person onFile = buildSimplePerson();
        this.attachVerifiedEnrollment(onFile);
        this.attachPurpleHeartWithPHStatusPending(onFile);
        onFile.getPurpleHeart().setStatus(this.getLookupService().getDecorationStatusByCode(DecorationStatus.CODE_CONFIRMED.getCode()));
        Person incoming = this.savePerson(onFile);

        this.setPurpleHeartStatus(DecorationStatus.CODE_REJECTED,        incoming);
        this.getPurpleHeartService().updatePurpleHeart(incoming);
       
    }    
}
