'use client';

import { getClassNames, toKebabCase } from '@websolutespa/bom-core';
import { FormArray, FormGroup, mapState_ } from '@websolutespa/bom-mixer-forms';
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
import styled from 'styled-components';
import { ThemeProps, UIComponentWithRef, UIStyledComponentProps } from '../../components/types';
import { getCssResponsive } from '../../components/utils';
import { IThemeFormVariant } from '../../theme';

type Props = {
  form?: FormGroup | FormArray;
  variant?: IThemeFormVariant;
};

export type FormProps = UIStyledComponentProps<Props, 'form'>;

export type FormComponent<C extends React.ElementType = 'form'> = UIComponentWithRef<C, Props>;

const StyledForm = styled.div<FormProps>`
  ${props => getForm(props)}
  ${props => getCssResponsive(props)}
`;

export const Form: FormComponent = forwardRef(({
  className,
  form,
  variant,
  ...props
}, ref) => {
  const innerRef = useRef<HTMLFormElement>(null);
  useImperativeHandle(ref, () => innerRef.current);
  useEffect(() => {
    if (form) {
      const onChange = (value: any) => {
        // console.log('FormComponent.onChange', form.state);
        if (innerRef.current !== null) {
          const formElement = innerRef.current;
          Object.entries(mapState_(form.state)).forEach(([k, v]) => {
            formElement.classList.toggle(k, v);
          });
        }
      };
      form.on('change', onChange);
      return () => form.off('change', onChange);
    }
    return;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [form]);
  const classNames = getClassNames('form', className, variant);
  return (
    <StyledForm ref={innerRef} className={classNames} as="form" variant={variant} {...props} />
  );
});

Form.displayName = 'Form';

export function getForm(props: FormProps & ThemeProps) {
  const variant: IThemeFormVariant = props.variant || 'default';
  const form = props.theme.form[variant];
  if (form) {
    return Object.keys(form).map((k) => {
      const key: string = toKebabCase(k);
      const rule = `--form-${key}: var(--form-${variant}-${key}, --form-${key});`;
      return rule;
    }).join('\n');
  } else {
    return undefined;
  }
}
