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

import { IDashboardComponentDetail, NewDashboardComponentDetail } from '../dashboard-component-detail.model';

/**
 * A partial Type with required key is used as form input.
 */
type PartialWithRequiredKeyOf<T extends { id: unknown }> = Partial<Omit<T, 'id'>> & { id: T['id'] };

/**
 * Type for createFormGroup and resetForm argument.
 * It accepts IDashboardComponentDetail for edit and NewDashboardComponentDetailFormGroupInput for create.
 */
type DashboardComponentDetailFormGroupInput = IDashboardComponentDetail | PartialWithRequiredKeyOf<NewDashboardComponentDetail>;

type DashboardComponentDetailFormDefaults = Pick<NewDashboardComponentDetail, 'id'>;

type DashboardComponentDetailFormGroupContent = {
  id: FormControl<IDashboardComponentDetail['id'] | NewDashboardComponentDetail['id']>;
  name: FormControl<IDashboardComponentDetail['name']>;
  color: FormControl<IDashboardComponentDetail['color']>;
  help: FormControl<IDashboardComponentDetail['help']>;
  indexOrder: FormControl<IDashboardComponentDetail['indexOrder']>;
  dashboardComponent: FormControl<IDashboardComponentDetail['dashboardComponent']>;
  targetDashboardComponent: FormControl<IDashboardComponentDetail['targetDashboardComponent']>;
  variable: FormControl<IDashboardComponentDetail['variable']>;
  version: FormControl<IDashboardComponentDetail['version']>;
};

export type DashboardComponentDetailFormGroup = FormGroup<DashboardComponentDetailFormGroupContent>;

@Injectable({ providedIn: 'root' })
export class DashboardComponentDetailFormService {
  createDashboardComponentDetailFormGroup(dashboardComponentDetail: DashboardComponentDetailFormGroupInput = { id: null }): DashboardComponentDetailFormGroup {
    const dashboardComponentDetailRawValue = {
      ...this.getFormDefaults(),
      ...dashboardComponentDetail,
    };
    return new FormGroup<DashboardComponentDetailFormGroupContent>({
      id: new FormControl(
        { value: dashboardComponentDetailRawValue.id, disabled: true },
        {
          nonNullable: true,
          validators: [Validators.required],
        },
      ),
      name: new FormControl(dashboardComponentDetailRawValue.name, {
        validators: [Validators.required],
      }),
      color: new FormControl(dashboardComponentDetailRawValue.color),
      help: new FormControl(dashboardComponentDetailRawValue.help),
      indexOrder: new FormControl(dashboardComponentDetailRawValue.indexOrder, {
        validators: [Validators.required],
      }),
      version: new FormControl(dashboardComponentDetailRawValue.version),
      variable: new FormControl(dashboardComponentDetailRawValue.variable),
      dashboardComponent: new FormControl(dashboardComponentDetailRawValue.dashboardComponent),
      targetDashboardComponent: new FormControl(dashboardComponentDetailRawValue.targetDashboardComponent),
    });
  }

  getDashboardComponentDetail(form: DashboardComponentDetailFormGroup): IDashboardComponentDetail | NewDashboardComponentDetail {
    return form.getRawValue() as IDashboardComponentDetail | NewDashboardComponentDetail;
  }

  resetForm(form: DashboardComponentDetailFormGroup, dashboardComponentDetail: DashboardComponentDetailFormGroupInput): void {
    const dashboardComponentDetailRawValue = { ...this.getFormDefaults(), ...dashboardComponentDetail };
    form.reset(
      {
        ...dashboardComponentDetailRawValue,
        id: { value: dashboardComponentDetailRawValue.id, disabled: true },
      } as any /* cast to workaround https://github.com/angular/angular/issues/46458 */,
    );
  }

  private getFormDefaults(): DashboardComponentDetailFormDefaults {
    return {
      id: null,
    };
  }
}