package com.agilex.healthcare.schedulingmanager.resources;

import com.agilex.healthcare.mobilehealthplatform.domain.PatientSearchResults;
import com.agilex.healthcare.mobilehealthplatform.domain.Patients;
import com.agilex.healthcare.mobilehealthplatform.domain.ResourceDirectory;
import com.agilex.healthcare.mobilehealthplatform.domain.filter.datefilter.DateFilterFactory;
import com.agilex.healthcare.schedulingmanager.domain.*;
import com.agilex.healthcare.utility.DateHelper;
import com.agilex.healthcare.utility.ModeHelper;
import com.agilex.healthcare.utility.XpathHelper;

import org.junit.*;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import javax.ws.rs.core.UriBuilder;

import com.agilex.healthcare.schedulingmanager.clientapi.MobileHealthClientTestVersion;
import com.agilex.healthcare.schedulingmanager.testutility.IntegrationTestConfiguration;
import com.agilex.healthcare.schedulingmanager.testutility.TestHelper;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Date;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class SchedulingResourceTest {

	private static MobileHealthClientTestVersion client;
	private static final String PROVIDER_FACING_MODE = "va-provider-prod";
    private final String siteCode ="777";
    private final String clinicId = "23";
    private final Date startDate = new Date();
    private final Date endDate = DateHelper.plusDays(startDate, 60);
    private static String mhpResourceUri;
    private static Node schedulingResourceDirectoryLinkNode;
    private static Node patientLinkNode;
    private static String deleteTokenURI = null;

	@BeforeClass
	public static void startup() {
        if(ModeHelper.isMode(PROVIDER_FACING_MODE))
        client = TestHelper.createProviderMobileHealthClient();
        Assume.assumeTrue(ModeHelper.isMode(PROVIDER_FACING_MODE));
        mhpResourceUri = IntegrationTestConfiguration.getMobileHealthServerBaseUri() + "/mhpuser" ;
        Document mhpUserXml = client.getAsXml(mhpResourceUri);
        schedulingResourceDirectoryLinkNode = XpathHelper.getNode(mhpUserXml, "//m:mhpUser/atom:link[@title='scheduling-resource-directory']");
        patientLinkNode = XpathHelper.getNode(mhpUserXml, "//m:mhpUser/atom:link[@title='patients-operational']");
        deleteTokenURI = TestHelper.getDeleteTokenURI();
	}

	@AfterClass
	public static void destroy() {
		if (client != null) {
            client.getJerseyClient().destroy();
            client = null;
		}
	}

	@Test
	public void fetchAvailableAppointmentSlotsforClinic() {

		URI uri = createAppointmentSlotUri(siteCode, clinicId, DateHelper.format(startDate,"MM/dd/yyyy").toString(), DateHelper.format(endDate,"MM/dd/yyyy").toString());
		uri = UriBuilder.fromUri(uri.toString()).build();
		AppointmentTimeSlots appointmentTimeSlots = client.getJerseyClient().resource(uri).get(AppointmentTimeSlots.class);
		assertNotNull(appointmentTimeSlots);
		assertTrue(appointmentTimeSlots.size() > 0);
	}
	private URI createAppointmentSlotUri(String siteCode, String clinicId, String startDate, String endDate) {
		String uriFormat = String.format("%s/scheduling-service/site/%s/available-appointment-slots/clinic/%s?startDate=%s&endDate=%s",
										IntegrationTestConfiguration.getSchedulingManagerBaseUri(),
										siteCode,
										clinicId, startDate, endDate);
		URI uri = UriBuilder.fromUri(uriFormat).build();
		return uri;
	}

    @Test
    public void testFetchPurposeDropdownList(){
        String resourceDirectoryUri = schedulingResourceDirectoryLinkNode.getAttributes().item(0).getNodeValue();
        ResourceDirectory resourceDirectory = client.getJerseyClient().resource(resourceDirectoryUri).get(ResourceDirectory.class);
        String purposeListStringUri = resourceDirectory.getLink().getUriByTitle("purpose-list").toString();
        URI purposeListUri = null;
        try {
            purposeListUri = new URI(purposeListStringUri.replaceAll("688", "777"));
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        AppointmentTypes appointmentTypes = client.getJerseyClient().resource(purposeListUri).get(AppointmentTypes.class);
        assertNotNull(appointmentTypes);
        assertEquals(11, appointmentTypes.size());
    }

    @Test
    public void testGetCancelReasonsDropdownList() {
        String resourceDirectoryUri = schedulingResourceDirectoryLinkNode.getAttributes().item(0).getNodeValue();
        ResourceDirectory resourceDirectory = client.getJerseyClient().resource(resourceDirectoryUri).get(ResourceDirectory.class);
        String purposeListStringUri = resourceDirectory.getLink().getUriByTitle(SchedulingManagerLinkTitles.CancelReasonsList).toString();
        URI purposeListUri = null;
        try {
            purposeListUri = new URI(purposeListStringUri.replaceAll("688", "777"));
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        CancelReasons cancelReasonsList = client.getJerseyClient().resource(purposeListUri).get(CancelReasons.class);
        assertNotNull(cancelReasonsList);
        assertEquals(13, cancelReasonsList.size());
    }

    @Test
    public void testUpdateNearList() {
        String resourceDirectoryUri = schedulingResourceDirectoryLinkNode.getAttributes().item(0).getNodeValue();
        ResourceDirectory resourceDirectory = client.getJerseyClient().resource(resourceDirectoryUri).get(ResourceDirectory.class);
        String purposeListStringUri = resourceDirectory.getLink().getUriByTitle(SchedulingManagerLinkTitles.CancelReasonsList).toString();

        assertNotNull(purposeListStringUri);
    }

    @Test
    public void testUpdateEwlEntryResource(){
        Patients patients = searchForPatient("666000001");
        URI ewlUpdateUri = patients.get(0).getLink().getUriByTitle("update-ewl-entry");
        assertNotNull(ewlUpdateUri);
    }

    public Patients searchForPatient(String searchString){
        Assume.assumeTrue(ModeHelper.isProviderMode());
        String searchUri = patientLinkNode.getAttributes().item(0).getNodeValue() + "?searchstring=" + searchString;
        Patients patients = client.getJerseyClient().resource(searchUri).get(PatientSearchResults.class);
        return  patients;
    }

    @Test
    public void testGetConsultsByService(){
        String resourceDirectoryUri = schedulingResourceDirectoryLinkNode.getAttributes().item(0).getNodeValue();
        ResourceDirectory resourceDirectory = client.getJerseyClient().resource(resourceDirectoryUri).get(ResourceDirectory.class);
        String consultUri = resourceDirectory.getLink().getUriByTitle("consult-by-service").toString();
        consultUri += "?serviceId=5&providerId=1&startDate=01/01/1997&endDate=04/01/2014";
        URI uri = null;
        try{
            uri = new URI(consultUri);
        }catch(URISyntaxException e) {
            e.printStackTrace();
        }
        SMConsults smConsults = client.getJerseyClient().resource(uri).get(SMConsults.class);
        assertTrue(smConsults.size() > 0);
    }

    @Test
    public void testGetListOfServicesForConsult(){
        String resourceDirectoryUri = schedulingResourceDirectoryLinkNode.getAttributes().item(0).getNodeValue();
        ResourceDirectory resourceDirectory = client.getJerseyClient().resource(resourceDirectoryUri).get(ResourceDirectory.class);
        String consultServiceUri = resourceDirectory.getLink().getUriByTitle("consulting-services").toString();
        URI uri = null;
        try {
            uri = new URI(consultServiceUri);
        }catch (URISyntaxException e) {
            e.printStackTrace();
        }
        SMConsultServices smConsultServices = client.getJerseyClient().resource(uri).get(SMConsultServices.class);
        assertTrue(smConsultServices.size() > 0);
    }

    @Test
    public void deleteToken(){
        if(client!=null){
            client.getJerseyClient().resource(deleteTokenURI).delete();
        }
    }
}
