package gov.va.med.esr.common.rule.service;

import gov.va.med.esr.common.util.RuleAbstractTestCase;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.Date;


// Framework classes

import gov.va.med.fw.rule.RuleException;
import gov.va.med.fw.service.ServiceException;


// ESR classes
import gov.va.med.esr.common.model.lookup.EnrollmentStatus;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.ee.EnrollmentDetermination;
import gov.va.med.esr.common.model.financials.IncomeTest;
import gov.va.med.esr.common.model.person.id.PersonIdEntityKeyImpl;
import gov.va.med.esr.service.EligibilityEnrollmentService;
import gov.va.med.esr.service.impl.ChangeEvent;
import gov.va.med.esr.service.impl.HistoricalInfo;



public class HistoryTest extends RuleAbstractTestCase {

    public HistoryTest(String testName) {
        super(testName);
        // TODO Auto-generated constructor stub
    }

    public void testHistoryOneAccess() throws Exception {
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("72096"));        
        Person updated = this.getPersonService().getPerson(personKey);
        this.showPriorEnrollmentDateStamp(updated);
    }
    
    public void testMostRecentUnverifiedEnrollment() throws Exception {
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("72096"));        
        Person updated = this.getPersonService().getPerson(personKey);
        this.showMostRecentUnverifiedEnrollmentDateStamp(updated);
    }
    
    public void testApplicationDateFromEarliestUnverifiedOrPendingEnrollment() throws Exception {
        // 246 5621
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("5612"));        
        Person updated = this.getPersonService().getPerson(personKey);
        this.showEarliestUnverifiedorPendingEnrollmentAppDate(updated);
    }
    
    public void testEarliestEnrollmentEffectiveDate() throws Exception {
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("72096"));        
        Person updated = this.getPersonService().getPerson(personKey);
        Date d = this.getEligibilityEnrollmentService().getFirstNotNullEffDate(personKey);
        if (d != null)
            System.out.println("enroll effective date=" + d.toString());        
    }              
    
    public void testHistory() throws Exception {
        PersonIdEntityKeyImpl personKey = new PersonIdEntityKeyImpl(new BigDecimal("72096"));        
        Person updated = this.getPersonService().getPerson(personKey);
        this.showEnrollmentDateStamps(updated);
        this.showEligibilityDateStamps(updated);        
     //   this.showFinancialDateStamps(updated);        
    }
    
    private void showEnrollmentDateStamps(Person person) throws RuleException {
        try {
            EligibilityEnrollmentService enrollmentService = this.getEligibilityEnrollmentService(); 
            Set dates = enrollmentService.getEnrollmentHistoryChangeTimes(person.getEntityKey());
            List sortedDates = getSortedChangeEvents(dates);
            for (int i = 0; i < sortedDates.size(); i++) {
                ChangeEvent changeEvent = (ChangeEvent)sortedDates.get(i);                    
                HistoricalInfo hi = (HistoricalInfo) enrollmentService.getEnrollmentHistoryByChangeTime(changeEvent);

                System.out.println("enroll change date=" + changeEvent.getTimeStamp().toString());
                    
            }
        }
        catch (ServiceException serviceEx) {
            throw new RuleException("Error retrieving and calling EE history service", serviceEx);
        }
        

    }
    
    private void showPriorEnrollmentDateStamp(Person person) throws RuleException {
        try {
            EligibilityEnrollmentService enrollmentService = this.getEligibilityEnrollmentService(); 
            Set dates = enrollmentService.getEnrollmentHistoryChangeTimes(person.getEntityKey());
            List sortedDates = getSortedChangeEvents(dates);
            int index = sortedDates.size()-2;
            if (index >= 0) {
                ChangeEvent changeEvent = (ChangeEvent)sortedDates.get(index);                    
                HistoricalInfo hi = (HistoricalInfo) enrollmentService.getEnrollmentHistoryByChangeTime(changeEvent);
                
                System.out.println("enroll change date=" + changeEvent.getTimeStamp().toString());
            }
        }
        catch (ServiceException serviceEx) {
            throw new RuleException("Error retrieving and calling EE history service", serviceEx);
        }
        

    }
    
    private void showMostRecentUnverifiedEnrollmentDateStamp(Person person) throws RuleException {
        try {
            EligibilityEnrollmentService enrollmentService = this.getEligibilityEnrollmentService(); 
            Set dates = enrollmentService.getEnrollmentHistoryChangeTimes(person.getEntityKey());
            List sortedDates = getSortedChangeEvents(dates);
            if (sortedDates.size() > 0) {
                for (int i = sortedDates.size() - 1; i >= 0 ; i--) {
                    ChangeEvent changeEvent = (ChangeEvent)sortedDates.get(i);                    
                    HistoricalInfo hi = (HistoricalInfo) enrollmentService.getEnrollmentHistoryByChangeTime(changeEvent);
                    Person historyPerson = hi != null ? (Person) hi.getEntity() : null;
                    
                    if(historyPerson != null ) {
                        System.out.println("examining enrollment status...");                        
                        EnrollmentDetermination enrollment = historyPerson.getEnrollmentDetermination();
                        if(enrollment != null && enrollment.getEnrollmentStatus() != null &&
                                EnrollmentStatus.CODE_UNVERIFIED.getName().equals(enrollment.getEnrollmentStatus().getCode())) {
                                System.out.println("unverified enrollment found");                            
                        }
                    }
                }                
            }
        }
        catch (ServiceException serviceEx) {
            throw new RuleException("Error retrieving and calling EE history service", serviceEx);
        }
        

    }
    
    private void showEarliestUnverifiedorPendingEnrollmentAppDate(Person person) throws Exception {
            EligibilityEnrollmentService enrollmentService = this.getEligibilityEnrollmentService(); 
            Date date = enrollmentService.getAppDateFromEarliestUnverifiedEnrollment(person.getEntityKey());
            if (date != null)
                    System.out.println("earliest unverified or pending enrollment application date..." + date.toString());                        
    }        
    
    
    private void showEligibilityDateStamps(Person person) throws RuleException {
        try {
            EligibilityEnrollmentService enrollmentService = this.getEligibilityEnrollmentService(); 
            Set dates = enrollmentService.getEligibilityHistoryChangeTimes(person.getEntityKey());
            List sortedDates = getSortedChangeEvents(dates);
            for (int i = 0; i < sortedDates.size(); i++) {
                ChangeEvent changeEvent = (ChangeEvent)sortedDates.get(i);                    
                enrollmentService.getEligibilityHistoryByChangeTime(changeEvent);

                System.out.println("elig change date=" + changeEvent.getTimeStamp().toString());
                    
            }
        }
        catch (ServiceException serviceEx) {
            throw new RuleException("Error retrieving and calling EE history service", serviceEx);
        }
        

    }
    
 /*   private void showFinancialDateStamps(Person person) throws RuleException {
        try {
            EligibilityEnrollmentService enrollmentService = this.getEligibilityEnrollmentService(); 
            Set dates = enrollmentService.getRulesEnrollmentHistoryChangeTimes(person.getEntityKey());
            List sortedDates = getSortedChangeEvents(dates);
            for (int i = 0; i < sortedDates.size(); i++) {
                ChangeEvent changeEvent = (ChangeEvent)sortedDates.get(i);                    
                HistoricalInfo hi = (HistoricalInfo) enrollmentService.getRulesEnrollmentHistoryByChangeTime(changeEvent);
                Person h = hi != null ? (Person)hi.getEntity() : null;
                if (h != null) {
                    IncomeTest it = h.getIncomeTest(new Integer(2005));
                    if (it != null) {
                        System.out.println("Financial effective date=" + it.getEffectiveDate().toString());                        
                        System.out.println("Financial status=" + it.getStatus().getDescription());                        
                    }
                }
 
                System.out.println("rule enrollment change date=" + changeEvent.getTimeStamp().toString());
                    
            }
        }
        catch (ServiceException serviceEx) {
            throw new RuleException("Error retrieving and calling EE history service", serviceEx);
        }
        

    }        
   */ 
    protected List getSortedChangeEvents(Set events) {
        List sortedEvents = new ArrayList();
        if (events != null) {
            sortedEvents.addAll(events);
            Collections.sort(sortedEvents);
        }
        return sortedEvents;
    }             
}
