import { useQuery } from '@based/react'
import { Schema, SchemaTypeName } from '@based/schema'
import { Modal } from '../Modal/index.js'
import { useContext, useMemo, useState } from 'react'
import { BasedFinder, BasedFinderRootProps } from '../BasedFinder/index.js'
import { IconButton } from '../IconButton/index.js'
import { colors } from '../../utils/colors.js'
import { Button } from '../Button/index.js'
import { List } from '../List/index.js'
import { generateFinderProps } from '../../utils/heuristics.js'
import { BasedForm } from '../BasedForm/index.js'
import { FormContext } from '../Form/Form.js'
import { Menu } from '../Menu/index.js'
import { IconProps } from '../Icon/index.js'

type ReferenceInputProps = {
  type: SchemaTypeName
  endpoints?: {
    query?: string
    totalQuery?: string
    schema?: string
  }
  placeholder?: string
  placeholderIcon?: IconProps['variant']
  disabled?: boolean
  error?: boolean
} & (
  | {
      variant: 'single'
      value?: string
      onChange: (value: string) => void
    }
  | {
      variant: 'multiple'
      value?: string[]
      onChange: (value: string[]) => void
    }
)
function ReferenceInput({
  endpoints,
  type,
  value,
  onChange,
  variant,
  placeholder,
  placeholderIcon,
  disabled,
  error,
}: ReferenceInputProps) {
  const ctx = useContext(FormContext)

  if (!ctx) {
    throw new Error('missing form context')
  }

  const [modal, setModal] = useState<'add' | 'select'>()
  const { data: schema } = useQuery(endpoints?.schema ?? 'db:schema') as {
    data?: Schema
  }
  const { data: itemsData } = useQuery(
    value ? (endpoints.query ?? 'db') : undefined,
    variant === 'single'
      ? { $id: value }
      : {
          $ids: value,
        },
  )

  const finderProps = useMemo(() => {
    if (variant === 'single')
      return {
        onItemClick: (item) => {
          onChange(item.id)
          setModal(undefined)
        },
      } satisfies Pick<BasedFinderRootProps, 'onItemClick'>

    return {
      select: value,
      onSelectChange: onChange,
    } satisfies Pick<BasedFinderRootProps, 'select' | 'onSelectChange'>
  }, [variant, value, onChange])

  return (
    <>
      <div
        style={{
          display: 'flex',
          flexDirection: 'column',
          width: '100%',
          gap: 8,
        }}
      >
        <div
          style={{
            height: variant === 'single' && value ? 44 + 2 * 8 + 2 : 120,
          }}
        >
          <List
            data={
              itemsData ? (variant === 'single' ? [itemsData] : itemsData) : []
            }
            fields={schema ? generateFinderProps(type, schema).fields : {}}
            itemActions={
              variant === 'single'
                ? undefined
                : [
                    {
                      label: 'Clear',
                      icon: 'close',
                      color: 'red',
                      onClick: (item) => {
                        onChange((value ?? []).filter((e) => e !== item.id))
                      },
                    },
                  ]
            }
            placeholder={placeholder}
            placeholderIcon={placeholderIcon}
            disabled={disabled}
            error={error}
          />
        </div>

        <div style={{ display: 'flex', gap: 8 }}>
          <Menu>
            <Menu.Trigger>
              {({ open }) => (
                <Button
                  variant="border"
                  leadIcon="add"
                  forceHover={open}
                  disabled={disabled}
                >
                  Add {type}
                </Button>
              )}
            </Menu.Trigger>
            <Menu.Items>
              <Menu.Item
                leadIcon="add"
                onClick={() => {
                  setModal('add')
                }}
              >
                Create
              </Menu.Item>
              <Menu.Item
                leadIcon="image"
                onClick={() => {
                  setModal('select')
                }}
              >
                Select from existing
              </Menu.Item>
            </Menu.Items>
          </Menu>
          {Boolean(
            (variant === 'single' && value) ||
              (variant === 'multiple' && value?.length),
          ) && (
            <Button
              variant="border"
              onClick={() => {
                onChange(undefined)
              }}
              leadIcon="close"
              disabled={disabled}
            >
              {variant === 'single' ? 'Clear' : 'Clear all'}
            </Button>
          )}
        </div>
      </div>
      {modal === 'add' && (
        <Modal
          open
          onOpenChange={() => {
            setModal(undefined)
          }}
        >
          <BasedForm
            endpoints={ctx.endpoints}
            validate={ctx.validate}
            onSubmit={async (...args) => {
              await ctx.onSubmit(...args)
              setModal(undefined)
            }}
            type={type}
          >
            {({ submitForm }) => (
              <>
                <Modal.Header title={`New ${type}`} />
                <Modal.Body>
                  <BasedForm.Fields />
                </Modal.Body>
                <Modal.Actions>
                  {({ close }) => (
                    <>
                      <Button keyHint="Esc" variant="border" onClick={close}>
                        Cancel
                      </Button>
                      <Button keyHint="Enter" onClick={() => submitForm(type)}>
                        Save
                      </Button>
                    </>
                  )}
                </Modal.Actions>
              </>
            )}
          </BasedForm>
        </Modal>
      )}
      {modal === 'select' && (
        <Modal
          open
          onOpenChange={() => {
            setModal(undefined)
          }}
          size="large"
        >
          <BasedFinder type={type} endpoints={endpoints} {...finderProps}>
            {({ view }) => (
              <>
                <Modal.Header>
                  <BasedFinder.Header
                    title={`Select ${type}`}
                    trailButton={
                      <IconButton
                        icon="close"
                        onClick={() => {
                          setModal(undefined)
                        }}
                      />
                    }
                  />
                </Modal.Header>
                <Modal.Body>
                  <div
                    style={{
                      height: 'calc(100svh - 2*24px - 2*84px)',
                      borderRadius: 16,
                      ...(view !== 'calendar' && {
                        border: `1px solid ${colors.neutral20Adjusted}`,
                        overflow: 'hidden',
                      }),
                    }}
                  >
                    <BasedFinder.Body
                      tableHeaderTransparentBackground={false}
                      calendarPadding={false}
                    />
                  </div>
                </Modal.Body>
                <Modal.Actions>
                  {variant === 'multiple' && (
                    <Button
                      keyHint="Enter"
                      onClick={() => {
                        setModal(undefined)
                      }}
                    >
                      Done
                    </Button>
                  )}
                </Modal.Actions>
              </>
            )}
          </BasedFinder>
        </Modal>
      )}
    </>
  )
}

export { ReferenceInput }
export type { ReferenceInputProps }
