'use client'

import { FC } from 'react'
import { PktCheckbox } from '../checkbox/Checkbox'
import { PktDatepicker } from '../datepicker/Datepicker'
import { PktInputWrapper } from '../inputwrapper/InputWrapper'
import { PktSelect } from '../select/Select'
import { PktTextinput } from '../textinput/Textinput'
import icons from '@oslokommune/punkt-assets/dist/icons/icons.json'
import { PktButton } from '../button/Button'

interface PropEditorProps {
  propKey: string
  spec: any
  props: any
  handleChange: (key: string, value: any, displayAsFalse?: boolean) => void
}

export const PktPreviewPropEditor: FC<PropEditorProps> = ({ propKey, spec, props, handleChange }) => {
  const editorTypes = {
    BOOLEAN: 'boolean',
    ICON: 'icon',
    ARRAY: 'array',
    OBJECT: 'object',
    DATE: 'ISOdatestring',
    NUMBER: 'number',
    STRING: 'string',
  }

  const handleObjectChange = (key: string, value: any) => {
    handleChange(propKey, { ...props[propKey], [key]: value })
  }

  const handleArrayChange = (index: number, key: string, value: any) => {
    const newArray = [...props[propKey]]
    newArray[index] = { ...newArray[index], [key]: value }
    handleChange(propKey, newArray)
  }

  const addObjectToArray = () => {
    const newArray = [...props[propKey], {}]
    handleChange(propKey, newArray)
  }

  const removeObjectFromArray = (index: number) => {
    const newArray = props[propKey].filter((_: any, i: number) => i !== index)
    handleChange(propKey, newArray)
  }

  if (spec.type === editorTypes.BOOLEAN) {
    return (
      <PktInputWrapper
        label={spec.name || propKey}
        forId={propKey}
        helptext={spec.description || null}
        hasFieldset
        requiredTag={spec.required}
      >
        <PktCheckbox
          id={propKey}
          label={propKey}
          type="checkbox"
          checked={props[propKey] || false}
          onChange={(e) => handleChange(propKey, e.target.checked, spec.displayAsFalse)}
          labelPosition="right"
          isSwitch
        />
      </PktInputWrapper>
    )
  }

  if (spec.type === editorTypes.ICON) {
    return (
      <PktSelect
        label={spec.name || propKey}
        helptext={spec.description || null}
        id={propKey}
        value={props[propKey] || ''}
        onChange={(e) => handleChange(propKey, e.target.value)}
        requiredTag={spec.required}
      >
        <option value=""></option>
        {(icons as { id: string }[]).map((icon) => (
          <option key={icon.id} value={icon.id}>
            {icon.id}
          </option>
        ))}
      </PktSelect>
    )
  }

  if (spec.type === editorTypes.DATE) {
    return (
      <PktDatepicker
        id={propKey}
        label={spec.name || propKey}
        helptext={spec.description || null}
        value={props[propKey] || ''}
        multiple={!!(spec.variant === 'multiple')}
        maxlength={999}
        onChange={(e) => handleChange(propKey, (e.target as HTMLInputElement).value)}
        requiredTag={spec.required}
      />
    )
  }

  if (Array.isArray(spec) || Array.isArray(spec.type) || Array.isArray(spec.values)) {
    const arr = Array.isArray(spec) ? spec : spec.values || spec.type
    return (
      <PktSelect
        label={spec.name || propKey}
        helptext={spec.description || null}
        id={propKey}
        value={props[propKey]}
        onChange={(e) => handleChange(propKey, e.target.value)}
        requiredTag={spec.required}
      >
        <option value=""></option>
        {arr.map((option: string) => (
          <option key={option} value={option}>
            {option}
          </option>
        ))}
      </PktSelect>
    )
  }

  if (spec.type === editorTypes.NUMBER) {
    return (
      <PktTextinput
        id={propKey}
        label={spec.name || propKey}
        helptext={spec.description || null}
        type="number"
        value={props[propKey] || ''}
        onChange={(e) => handleChange(propKey, parseFloat(e.currentTarget.value))}
        requiredTag={spec.required}
      />
    )
  }

  if (spec.type === editorTypes.OBJECT) {
    if (!props[propKey]) {
      props[propKey] = {}
    }
    return (
      <div>
        <div className="pkt-inputwrapper__label">
          <h2>{spec.name || propKey}</h2>
        </div>
        {spec.description && <p>{spec.description}</p>}

        <fieldset>
          <legend>{spec.name || propKey}</legend>
          {Object.entries(spec.properties).map(([key, prop]) => (
            <PktPreviewPropEditor
              key={key}
              propKey={key}
              props={props[propKey]}
              spec={prop}
              handleChange={(key, value) => handleObjectChange(key, value)}
            ></PktPreviewPropEditor>
          ))}
        </fieldset>
      </div>
    )
  }

  if (spec.type === editorTypes.ARRAY && spec.items.type === editorTypes.OBJECT) {
    if (!props[propKey]) {
      props[propKey] = []
    }
    return (
      <div>
        <div className="pkt-inputwrapper__label">
          <h2>{spec.name || propKey}</h2>
        </div>
        {spec.description && <p>{spec.description}</p>}
        {props[propKey].map((item: any, index: number) => (
          <div key={index}>
            <fieldset>
              <legend>Item {index + 1}</legend>
              {Object.entries(spec.items.properties).map(([key, prop]) => (
                <PktPreviewPropEditor
                  key={key}
                  propKey={key}
                  props={item}
                  spec={prop}
                  handleChange={(key, value) => handleArrayChange(index, key, value)}
                ></PktPreviewPropEditor>
              ))}
              <PktButton onClick={() => removeObjectFromArray(index)}>Fjern denne</PktButton>
            </fieldset>
          </div>
        ))}
        <PktButton onClick={addObjectToArray}>Legg til ny</PktButton>
      </div>
    )
  }

  return (
    <PktTextinput
      id={propKey}
      label={spec.name || propKey}
      helptext={spec.description || null}
      type="text"
      value={props[propKey] || ''}
      onChange={(e) =>
        handleChange(propKey, spec.type === 'number' ? parseFloat(e.currentTarget.value) : e.currentTarget.value)
      }
      requiredTag={spec.required}
    />
  )
}
