import { AbstractControl, ValidatorFn } from '@angular/forms';
import { ANNAN_ORSAK_ID } from '@msfa-constants/franvaro-reasons';
import { CHARACTER_REGEX } from '@msfa-constants/regex';
import { Franvaro } from '@msfa-models/franvaro.model';

const TIME_REGEX = /^([0-1]?[0-9]|2[0-4]):([0-5][0-9])(:[0-5][0-9])?$/;

function isTimeValid(value: string): boolean {
  return TIME_REGEX.test(value);
}

export class FranvaroReportFormValidator {
  static isFranvaroReportValid(): ValidatorFn {
    return (c: AbstractControl): { [key: string]: string } => {
      let errors: { [key: string]: string } = null;
      const {
        reason,
        date,
        wholeDay,
        startTime,
        endTime,
        knownReasonComment,
        expectedPresenceStartTime,
        expectedPresenceEndTime,
      } = c.value as Franvaro;

      if (!reason) {
        errors = {
          ...errors,
          reason: 'Orsak till frånvaro måste väljas',
        };
      }
      if (reason === ANNAN_ORSAK_ID) {
        if (!knownReasonComment) {
          errors = {
            ...errors,
            knownReasonComment: 'Beskrivning av frånvaro är obligatorisk',
          };
        } else if (!CHARACTER_REGEX.test(knownReasonComment)) {
          errors = {
            ...errors,
            knownReasonComment: 'Beskrivning av frånvaro har en ogiltig värde',
          };
        }
      }
      if (!date) {
        errors = {
          ...errors,
          date: 'Dag för frånvaro måste väljas',
        };
      }
      if (!wholeDay) {
        if (!startTime) {
          errors = {
            ...errors,
            startTime: 'Starttid för frånvaro måste väljas',
          };
        } else if (!isTimeValid(startTime)) {
          errors = {
            ...errors,
            startTime: 'Felaktig tid för starttid (HH:MM)',
          };
        }
        if (!endTime) {
          errors = {
            ...errors,
            endTime: 'Sluttid för frånvaro måste väljas',
          };
        } else if (!isTimeValid(endTime)) {
          errors = {
            ...errors,
            endTime: 'Felaktig tid för sluttid (HH:MM)',
          };
        }
        if (endTime && startTime && endTime < startTime) {
          errors = {
            ...errors,
            expectedEndTimeIsBeforeStartTime: 'Sluttid för frånvaro får inte vara före starttid',
          };
        }
      }
      if (!expectedPresenceStartTime) {
        errors = {
          ...errors,
          expectedPresenceStartTime: 'Starttid för förväntad närvaro måste väljas',
        };
      } else if (!isTimeValid(expectedPresenceStartTime)) {
        errors = {
          ...errors,
          expectedPresenceStartTime: 'Felaktig tid för starttid för förväntad närvaro (HH:MM)',
        };
      }
      if (!expectedPresenceEndTime) {
        errors = {
          ...errors,
          expectedPresenceEndTime: 'Sluttid för förväntad närvaro måste väljas',
        };
      } else if (!isTimeValid(expectedPresenceEndTime)) {
        errors = {
          ...errors,
          expectedPresenceEndTime: 'Felaktig tid för sluttid för förväntad närvaro (HH:MM)',
        };
      }

      if (expectedPresenceEndTime && expectedPresenceStartTime && expectedPresenceEndTime < expectedPresenceStartTime) {
        errors = {
          ...errors,
          expectedPresenceEndTimeIsBeforeStartTime: 'Sluttid för förväntad närvaro får inte vara före starttid',
        };
      }
      return errors;
    };
  }
}
