package com.agilex.healthcare.schedulingmanager.validator;

import com.agilex.healthcare.mobilehealthplatform.domain.AppointmentRequestMessage;
import com.agilex.healthcare.mobilehealthplatform.domain.ValidationResult;
import com.agilex.healthcare.mobilehealthplatform.validator.appointmentrequestmessage.AppointmentRequestMessageValidator;
import com.agilex.healthcare.mobilehealthplatform.validator.appointmentrequestmessage.AppointmentRequestMessageValidatorFactory;
import org.junit.Before;
import org.junit.Test;

import java.util.Date;

import static org.junit.Assert.*;

public class AppointmentRequestMessageValidatorTest {

    private AppointmentRequestMessageValidator appointmentRequestMessageValidator;
    private AppointmentRequestMessage appointmentRequestMessage;


    @Before
    public void setup(){
        appointmentRequestMessage = createValidAppointmentRequestMessage();
        appointmentRequestMessageValidator = AppointmentRequestMessageValidatorFactory
                .createAppointmentRequestMessageValidator();
    }

    @Test
    public void givenMessageLengthOver100CharactersValidationShouldFail(){

        appointmentRequestMessage.setMessageText(createMessageOver100Characters());

        ValidationResult<AppointmentRequestMessage> result = appointmentRequestMessageValidator.validate(appointmentRequestMessage);
        assertFalse(result.isValid());
        assertFalse(result.getErrors().isEmpty());
        assertEquals("messageText", result.getErrors().get(0).getFieldName());
        assertEquals("Appointment request message is required and must be between 1 and 100 characters.", result.getErrors().get(0).getErrorMessage());

    }

    @Test
    public void givenNullMessageValidationShouldFail(){

        appointmentRequestMessage.setMessageText(null);

        ValidationResult<AppointmentRequestMessage> result = appointmentRequestMessageValidator.validate(appointmentRequestMessage);
        assertFalse(result.isValid());
        assertFalse(result.getErrors().isEmpty());
        assertEquals("messageText", result.getErrors().get(0).getFieldName());
        assertEquals("Appointment request message is required and must be between 1 and 100 characters.", result.getErrors().get(0).getErrorMessage());

    }

    @Test
    public void givenEmptyMessageValidationShouldFail(){

        appointmentRequestMessage.setMessageText("");

        ValidationResult<AppointmentRequestMessage> result = appointmentRequestMessageValidator.validate(appointmentRequestMessage);
        assertFalse(result.isValid());
        assertFalse(result.getErrors().isEmpty());
        assertEquals("messageText", result.getErrors().get(0).getFieldName());
        assertEquals("Appointment request message is required and must be between 1 and 100 characters.", result.getErrors().get(0).getErrorMessage());

    }

    @Test
    public void givenMinimumLengthOfOneValidationShouldPass(){

        appointmentRequestMessage.setMessageText("a");

        ValidationResult<AppointmentRequestMessage> result = appointmentRequestMessageValidator.validate(appointmentRequestMessage);
        assertTrue(result.isValid());
        assertTrue(result.getErrors().isEmpty());

    }

    @Test
    public void givenMaximumAllowedLengthValidationShouldPass(){

        appointmentRequestMessage.setMessageText(createMessageWith100Characters());

        ValidationResult<AppointmentRequestMessage> result = appointmentRequestMessageValidator.validate(appointmentRequestMessage);
        assertTrue(result.isValid());
        assertTrue(result.getErrors().isEmpty());

    }



    private AppointmentRequestMessage createValidAppointmentRequestMessage(){

        AppointmentRequestMessage aptRequestMessage = new AppointmentRequestMessage();
        aptRequestMessage.setMessageDateTime(new Date());
        aptRequestMessage.setPatientId("1");
        aptRequestMessage.setUniqueId("1");
        aptRequestMessage.setSenderId("1");
        aptRequestMessage.setMessageText("Hello");

        return aptRequestMessage;

    }

    private String createMessageWith100Characters(){
        return createStringOfGivenLength(100);
    }

    private String createMessageOver100Characters(){
        return createStringOfGivenLength(101);
    }

    private String createStringOfGivenLength(int stringLength){
        char fillerChar = 'a';
        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < stringLength ; i++){
            stringBuilder.append(fillerChar);
        }
        return stringBuilder.toString();
    }
}
