import { Injectable } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';

import dayjs from 'dayjs/esm';
import { DATE_TIME_FORMAT } from 'app/config/input.constants';
import { SearchInputData } from '../input-data.model';
import { SearchFormService } from 'app/entities/shared/shared-search-form.service';

/**
 * Type for createFormGroup and resetForm argument.
 * It accepts SearchInputData, for search. in the list
 */
type InputDataSearchFormGroupInput = SearchInputData;

type InputDataSearchFormDefaults = SearchInputData;

type InputDataSearchFormGroupContent = {
  id: FormControl<SearchInputData['id']>;
  sourceValue: FormControl<SearchInputData['sourceValue']>;
  variableValue: FormControl<SearchInputData['variableValue']>;
  imputedValue: FormControl<SearchInputData['imputedValue']>;
  sourceType: FormControl<SearchInputData['sourceType']>;
  dataDate: FormControl<SearchInputData['dataDate']>;
  changeUsername: FormControl<SearchInputData['changeUsername']>;
  dataSource: FormControl<SearchInputData['dataSource']>;
  dataUser: FormControl<SearchInputData['dataUser']>;
  dataComments: FormControl<SearchInputData['dataComments']>;
  creationUsername: FormControl<SearchInputData['creationUsername']>;
  version: FormControl<SearchInputData['version']>;
  variableId: FormControl<SearchInputData['variableId']>;
  variableNameOrCode: FormControl<SearchInputData['variableNameOrCode']>;
  variableClassNameOrCode: FormControl<SearchInputData['variableClassNameOrCode']>;
  periodId: FormControl<SearchInputData['periodId']>;
  ownerId: FormControl<SearchInputData['ownerId']>;
  sourceInputDataUploadId: FormControl<SearchInputData['sourceInputDataUploadId']>;
  variableScopeId: FormControl<SearchInputData['variableScopeId']>;
  variableCategoryId: FormControl<SearchInputData['variableCategoryId']>;
};

export type InputDataSearchFormGroup = FormGroup<InputDataSearchFormGroupContent>;

@Injectable({ providedIn: 'root' })
export class InputDataSearchFormService extends SearchFormService {
  createInputDataSearchFormGroup(inputData: InputDataSearchFormGroupInput = { id: null }): InputDataSearchFormGroup {
    const inputDataRawValue = {
      ...this.getSearchFormDefaults(),
      ...inputData,
    };
    return new FormGroup<InputDataSearchFormGroupContent>({
      id: new FormControl(inputDataRawValue.id),
      sourceValue: new FormControl(inputDataRawValue.sourceValue),
      variableValue: new FormControl(inputDataRawValue.variableValue),
      imputedValue: new FormControl(inputDataRawValue.imputedValue),
      sourceType: new FormControl(inputDataRawValue.sourceType),
      dataDate: new FormControl(inputDataRawValue.dataDate),
      changeUsername: new FormControl(inputDataRawValue.changeUsername),
      dataSource: new FormControl(inputDataRawValue.dataSource),
      dataUser: new FormControl(inputDataRawValue.dataUser),
      dataComments: new FormControl(inputDataRawValue.dataComments),
      creationUsername: new FormControl(inputDataRawValue.creationUsername),
      version: new FormControl(inputDataRawValue.version),
      variableId: new FormControl(inputDataRawValue.variableId),
      variableNameOrCode: new FormControl(inputDataRawValue.variableNameOrCode),
      variableClassNameOrCode: new FormControl(inputDataRawValue.variableClassNameOrCode),
      periodId: new FormControl(inputDataRawValue.periodId),
      ownerId: new FormControl(inputDataRawValue.ownerId),
      sourceInputDataUploadId: new FormControl(inputDataRawValue.sourceInputDataUploadId),
      variableScopeId: new FormControl(inputDataRawValue.variableScopeId),
      variableCategoryId: new FormControl(inputDataRawValue.variableCategoryId),
    });
  }

  getInputData(form: InputDataSearchFormGroup): SearchInputData {
    return form.getRawValue() as SearchInputData;
  }

  resetForm(form: InputDataSearchFormGroup, inputData: InputDataSearchFormGroupInput): void {
    const inputDataRawValue = { ...this.getSearchFormDefaults(), ...inputData };
    form.reset(
      {
        ...inputDataRawValue,
        id: { value: inputDataRawValue.id, disabled: true },
      } as any /* cast to workaround https://github.com/angular/angular/issues/46458 */,
    );
  }

  private getSearchFormDefaults(): InputDataSearchFormDefaults {
    const currentTime = dayjs();

    return {
      id: null,
    };
  }
}
