/* eslint-disable no-prototype-builtins */
import { UntypedFormArray, UntypedFormGroup } from '@angular/forms'
import { AnyType } from '@core/types'

export class FormUtils {
	static async updateandValidate(
		form: UntypedFormGroup | UntypedFormArray,
		data: AnyType | AnyType[],
		initiateForm?: UntypedFormGroup,
	) {
		if (data && Array.isArray(data) && Array.isArray(form?.controls)) {
			for (const [index, element] of data.entries()) {
				form.controls[index] = await FormUtils.assignValuestoForm(
					element,
					form.controls[index] as UntypedFormGroup,
					initiateForm,
				)
			}
		} else {
			form = await this.assignValuestoForm(data, form as UntypedFormGroup, initiateForm)
		}
		form.updateValueAndValidity()
		return form
	}

	private static async assignValuestoForm(
		data: AnyType,
		form: UntypedFormGroup,
		initiateForm?: UntypedFormGroup,
	): Promise<UntypedFormGroup> {
		const _form: UntypedFormGroup = form ?? initiateForm
		for (const property in data) {
			if (data.hasOwnProperty(property) && _form.get(property) && data[property] != null) {
				if (typeof data[property] === 'boolean') {
					_form.get(property)?.setValue(data[property])
				} else {
					if (typeof data[property] === 'object') {
						// child object loop
						const childData = data[property]

						let isStringArray = false
						if (Array.isArray(childData)) {
							isStringArray = childData?.some((value: AnyType) => {
								return typeof value === 'string'
							})
						}
						if (isStringArray) {
							_form.get(property)?.setValue(data[property])
						} else {
							for (const childProperty in childData) {
								if (
									childData.hasOwnProperty(childProperty) &&
									_form.get(`${property}.${childProperty}`) &&
									childData[childProperty] != null
								) {
									if (typeof childData[childProperty] === 'boolean') {
										_form.get(`${property}.${childProperty}`)?.setValue(childData[childProperty])
									} else {
										_form.get(`${property}.${childProperty}`)?.setValue(childData[childProperty])
									}
								}
							}
						}
					} else {
						_form.get(property)?.setValue(data[property])
					}
				}
			}
		}

		return _form
	}
}
