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

import { IVariable, SearchVariable } from '../variable.model';

/**
 * Type for createFormGroup and resetForm argument.
 * It accepts IVariable for edit and NewVariableFormGroupInput for create.
 */
type VariableSearchFormGroupInput = SearchVariable;

type VariableSearchFormDefaults = Pick<SearchVariable, 'input' | 'output' | 'variableClassMandatory'>;

type VariableSearchFormGroupContent = {
  code: FormControl<SearchVariable['code']>;
  variableIndex: FormControl<SearchVariable['variableIndex']>;
  name: FormControl<SearchVariable['name']>;
  description: FormControl<SearchVariable['description']>;
  input: FormControl<SearchVariable['input']>;
  inputMode: FormControl<SearchVariable['inputMode']>;
  output: FormControl<SearchVariable['output']>;
  outputFormula: FormControl<SearchVariable['outputFormula']>;
  baseUnit: FormControl<SearchVariable['baseUnit']>;
  variableScopeId: FormControl<SearchVariable['variableScopeId']>;
  variableCategoryId: FormControl<SearchVariable['variableCategoryId']>;
  variableClassTypeId: FormControl<SearchVariable['variableClassTypeId']>;
  variableClassMandatory?: FormControl<SearchVariable['variableClassMandatory']>;
  variableClassLabel?: FormControl<SearchVariable['variableClassLabel']>;
};

export type VariableSearchFormGroup = FormGroup<VariableSearchFormGroupContent>;

@Injectable({ providedIn: 'root' })
export class VariableSearchFormService {
  constructor(private fb: FormBuilder) {} 
  
  createVariableSearchFormGroup(variable: VariableSearchFormGroupInput = { code: null }): VariableSearchFormGroup {
    const variableSearchRawValue = {
      ...this.getSearchFormDefaults(),
      ...variable,
    };
	
    return new FormGroup<VariableSearchFormGroupContent>({
      code: new FormControl(variableSearchRawValue.code),
      variableIndex: new FormControl(variableSearchRawValue.variableIndex),
      name: new FormControl(variableSearchRawValue.name),
      description: new FormControl(variableSearchRawValue.description),
      input: new FormControl(variableSearchRawValue.input),
      inputMode: new FormControl(variableSearchRawValue.inputMode),
      output: new FormControl(variableSearchRawValue.output),
      outputFormula: new FormControl(variableSearchRawValue.outputFormula),
      baseUnit: new FormControl(variableSearchRawValue.baseUnit),
      variableScopeId: new FormControl(variableSearchRawValue.variableScopeId),
      variableCategoryId: new FormControl(variableSearchRawValue.variableCategoryId),
	  variableClassTypeId: new FormControl(variableSearchRawValue.variableClassTypeId),
	  variableClassMandatory: new FormControl(variableSearchRawValue.variableClassMandatory),
	  variableClassLabel: new FormControl(variableSearchRawValue.variableClassLabel)
    });
  }

  getVariable(form: VariableSearchFormGroup): SearchVariable {
    return form.getRawValue() as SearchVariable ;
  }

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

  private getSearchFormDefaults(): VariableSearchFormDefaults {
    return {
      input: null,
      output: null,
	  variableClassMandatory: null,
    };
  }
}
