import type { FillFormArgs, InputsType } from './types';

const dateFormat = (v: Date) => v.toISOString().slice(0, 10);

const fillForm = function (args: FillFormArgs) {
  const { theForm, state, path = [] } = args;
  if (!state) return;

  Object.entries(state).forEach(([key, val]) => {
    if (typeof key !== 'string' || '' + parseInt(key, 10) == key) return;
    let target: InputsType | undefined = undefined;
    const targets = Array.from(document.querySelectorAll(`[name=${key}]`));
    if (targets.length === 1) {
      target = targets[0] as InputsType;
    } else {
      if (targets.every((t) => (t as HTMLInputElement).type === 'radio')) {
        target = theForm[key];
      } else {
        if (path.length === 0) {
          target = theForm.querySelector(`[name=${key}]`) as InputsType | undefined;
        }
        let fieldset: Element | null = theForm;
        for (let i = 0; i < path.length; i++) {
          fieldset = fieldset?.querySelector(`fieldset[name=${path[i]}]`) ?? null;
        }
        if (fieldset) {
          target = fieldset.querySelector(`[name=${key}]`) as InputsType | undefined;
        }
      }
    }

    if (target && val === null) {
      if (['text', 'number'].includes(target.type)) {
        target.value = '';
      }
    }

    if (target && typeof val === 'boolean') {
      if (target) {
        const element = target as HTMLInputElement;
        element.checked = val;
      }
    }

    if (target && val && val.constructor === Date) {
      target.value = dateFormat(val);
    }

    if (target && typeof val !== 'object') {
      target.value = val.toString();
      return;
    }

    if (Array.isArray(val)) {
      // if (element?.[0]?.type.toLowerCase() === 'checkbox') {
      //   const checkboxes: HTMLInputElement[] = Array.from(target.querySelectorAll(`[name=${key}]`));
      //   checkboxes.forEach((checkbox) => {
      //     if (checkbox.type.toLowerCase() === 'checkbox') {
      //       checkbox.checked = val.includes(checkbox.value);
      //     }
      //   });
      // } else
      if (target && target.nodeName === 'SELECT') {
        const element = target as HTMLSelectElement;
        const options: HTMLOptionElement[] = Array.from(element.querySelectorAll('option'));
        options.forEach((option) => {
          option.selected = val.includes(option.value);
        });
      }
      return;
    }

    fillForm({ theForm, state: state[key], path: [...path, key] });
  });
};

export default fillForm;
