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

import { IDashboardComponentDetail, NewDashboardComponentDetail } from '../dashboard-component-detail.model';
import { IDashboardComponentOrganization, NewDashboardComponentOrganization } from '../dashboard-component-organization.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 IDashboardComponentOrganization for edit and NewDashboardComponentOrganizationFormGroupInput for create.
 */
type DashboardComponentOrganizationFormGroupInput = IDashboardComponentOrganization | PartialWithRequiredKeyOf<NewDashboardComponentOrganization>;

type DashboardComponentOrganizationFormDefaults = Pick<NewDashboardComponentOrganization, 'id'>;

type DashboardComponentOrganizationFormGroupContent = {
  id: FormControl<IDashboardComponentOrganization['id'] | NewDashboardComponentOrganization['id']>;
  dashboardComponent: FormControl<IDashboardComponentOrganization['dashboardComponent']>;
  organization: FormControl<IDashboardComponentOrganization['organization']>;
  version: FormControl<IDashboardComponentDetail['version']>;
};

export type DashboardComponentOrganizationFormGroup = FormGroup<DashboardComponentOrganizationFormGroupContent>;

@Injectable({ providedIn: 'root' })
export class DashboardComponentOrganizationFormService {
  createDashboardComponentOrganizationFormGroup(dashboardComponentOrganization: DashboardComponentOrganizationFormGroupInput = { id: null }): DashboardComponentOrganizationFormGroup {
    const dashboardComponentOrganizationRawValue = {
      ...this.getFormDefaults(),
      ...dashboardComponentOrganization,
    };
    return new FormGroup<DashboardComponentOrganizationFormGroupContent>({
      id: new FormControl(
        { value: dashboardComponentOrganizationRawValue.id, disabled: true },
        {
          nonNullable: true,
          validators: [Validators.required],
        },
      ),
      dashboardComponent: new FormControl(dashboardComponentOrganizationRawValue.dashboardComponent),
      organization: new FormControl(dashboardComponentOrganizationRawValue.organization, {
        validators: [Validators.required],
      }),
      version: new FormControl(dashboardComponentOrganizationRawValue.version),
    });
  }

  getDashboardComponentOrganization(form: DashboardComponentOrganizationFormGroup): IDashboardComponentOrganization | NewDashboardComponentOrganization {
    return form.getRawValue() as IDashboardComponentOrganization | NewDashboardComponentOrganization;
  }

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

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