/*
 * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den
 * Ministerpräsidenten des Landes Schleswig-Holstein
 * Staatskanzlei
 * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
 *
 * Lizenziert unter der EUPL, Version 1.2 oder - sobald
 * diese von der Europäischen Kommission genehmigt wurden -
 * Folgeversionen der EUPL ("Lizenz");
 * Sie dürfen dieses Werk ausschließlich gemäß
 * dieser Lizenz nutzen.
 * Eine Kopie der Lizenz finden Sie hier:
 *
 * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
 *
 * Sofern nicht durch anwendbare Rechtsvorschriften
 * gefordert oder in schriftlicher Form vereinbart, wird
 * die unter der Lizenz verbreitete Software "so wie sie
 * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
 * ausdrücklich oder stillschweigend - verbreitet.
 * Die sprachspezifischen Genehmigungen und Beschränkungen
 * unter der Lizenz sind dem Lizenztext zu entnehmen.
 */
import {
  AbstractControl,
  FormControl,
  FormGroup,
  UntypedFormControl,
  UntypedFormGroup,
} from '@angular/forms';
import { createIssue } from '../../../test/error';
import { InvalidParam, Issue } from '../tech.model';
import {
  getControlForIssue,
  getMessageForInvalidParam,
  getMessageForIssue,
  setIssueValidationError,
} from './tech.validation.util';
import { ValidationMessageCode } from './tech.validation.messages';

describe('ValidationUtils', () => {
  describe('set issue validation error', () => {
    const baseField1Control: FormControl = new UntypedFormControl();
    const baseField2Control: FormControl = new UntypedFormControl();
    const subGroupFieldControl: FormControl = new UntypedFormControl();

    const form: FormGroup = new UntypedFormGroup({
      baseField1: baseField1Control,
      baseField2: baseField2Control,
      subGroup: new UntypedFormGroup({
        subGroupField1: subGroupFieldControl,
      }),
    });

    describe('get control for issue', () => {
      it('should return base field control', () => {
        const issue: Issue = { ...createIssue(), field: 'baseField1' };

        const control: AbstractControl = getControlForIssue(form, issue);

        expect(control).toBe(baseField1Control);
      });

      it('should return sub group field', () => {
        const issue: Issue = { ...createIssue(), field: 'subGroup.subGroupField1' };

        const control: AbstractControl = getControlForIssue(form, issue);

        expect(control).toBe(subGroupFieldControl);
      });

      it('should ignore path prefix', () => {
        const issue: Issue = { ...createIssue(), field: 'pathprefix.resource.baseField1' };

        const control: AbstractControl = getControlForIssue(form, issue, 'pathprefix.resource');

        expect(control).toBe(baseField1Control);
      });
    });

    describe('in base field', () => {
      const issue: Issue = { ...createIssue(), field: 'baseField1' };

      it('should set error in control', () => {
        setIssueValidationError(form, issue);

        expect(baseField1Control.errors).not.toBeNull();
      });

      it('should set message code in control', () => {
        setIssueValidationError(form, issue);

        expect(baseField1Control.hasError(issue.messageCode)).toBe(true);
      });

      it('should set control touched', () => {
        setIssueValidationError(form, issue);

        expect(baseField1Control.touched).toBe(true);
      });

      it('should not set error in other control', () => {
        setIssueValidationError(form, issue);

        expect(baseField2Control.errors).toBeNull();
      });
    });

    describe('in subGroup Field', () => {
      const issue: Issue = { ...createIssue(), field: 'subGroup.subGroupField1' };

      it('should set error in control', () => {
        setIssueValidationError(form, issue);

        expect(subGroupFieldControl.errors).not.toBeNull();
      });
    });
  });

  describe('get message for issue', () => {
    const fieldLabel: string = 'Field Label';

    it('should return message', () => {
      const msg: string = getMessageForIssue(fieldLabel, {
        ...createIssue(),
        messageCode: 'validation_field_size',
      });

      expect(msg).toContain('muss mindestens');
    });

    it('should set field label', () => {
      const msg: string = getMessageForIssue(fieldLabel, {
        ...createIssue(),
        messageCode: 'validation_field_size',
      });

      expect(msg).toContain(fieldLabel);
    });

    it('should replace min param', () => {
      const msg: string = getMessageForIssue(fieldLabel, {
        ...createIssue(),
        messageCode: 'validation_field_size',
        parameters: [{ name: 'min', value: '3' }],
      });

      expect(msg).toContain('3');
    });
  });

  describe('get message for invalid-params-item', () => {
    const item: InvalidParam = {
      name: 'name-of-field',
      reason: ValidationMessageCode.VALIDATION_FIELD_EMPTY,
    };

    it('should return message', () => {
      const msg: string = getMessageForInvalidParam(item);

      expect(msg).toEqual(`Bitte ${item.name} ausfüllen`);
    });
  });
});

// describe('setValidationDetails', () => {
//   let form: UntypedFormGroup;
//   const fieldName = 'test-field';

//   beforeEach(() => {
//     form = formService.form;
//     const control = new FormControl('');
//     form.addControl(fieldName, control);
//   });

//   it('should set invalid-params of validation-problem-details on control', () => {
//     const validationDetails: ProblemDetail = createAbsenderNameProblemDetail();
//     const item = validationDetails['invalid-params'][0];
//     item.name = '.' + fieldName;

//     formService.setErrorByProblemDetail(validationDetails);

//     const itemError = form.getError(item.reason, fieldName);
//     expect(itemError).toBe(
//       getMessageForInvalidParamsItem({
//         ...item,
//         name: fieldName,
//       }),
//     );
//   });
// });

// describe('set error by api error', () => {
//   // let form: UntypedFormGroup;
//   const fieldName: string = 'test-field';

//   beforeEach(() => {
//     // form = formService.form;
//     // const control = ;
//     formService.form.addControl(fieldName, new FormControl(''));
//   });

//   it('should set issues of api-error on control', () => {
//     const issue: Issue = { ...createIssue(), field: TestFormService + '.' + fieldName };
//     const apiError: ApiError = createApiError([issue]);

//     formService.setErrorByApiError(apiError);

//     expect(formService.form.getError(issue.messageCode, fieldName)).toBe(issue);
//   });
// });

// export function createAbsenderNameProblemDetail(invalidParams: InvalidParam[]): ProblemDetail {
//   return {
//     type: 'about:blank',
//     title: 'Unprocessable Entity',
//     status: HttpStatusCode.UnprocessableEntity,
//     detail: 'settingsBody.absender.name: validation_field_empty',
//     instance: '/api/configuration/settings/65df039a69eeafef365a42dd',
//     'invalid-params': invalidParams,
//   };
// }

// export function createAbsenderNameInvalidParam(): InvalidParam {
//   return {
//     name: 'settingsBody.absender.name',
//     reason: ValidationMessageCode.VALIDATION_FIELD_EMPTY,
//   };
// }