import { Fragment, useState } from 'react'
import { Fields, ItemActions, Select } from '../../utils/common.js'
import { Menu } from '../Menu/index.js'
import { Text } from '../Text/index.js'
import { IconButton } from '../IconButton/index.js'
import { CheckboxInput } from '../CheckboxInput/index.js'
import { colors } from '../../utils/colors.js'
import { radius } from '../../utils/radius.js'
import { styled } from 'inlines'
import { Icon, IconProps } from '../Icon/index.js'

type ListProps = {
  data: any[]
  fields: Fields
  title?: string
  select?: Select
  onSelectChange?: (select?: Select) => void
  collapsible?: boolean
  onItemClick?: (item: any) => void
  itemActions?: ItemActions
  placeholder?: string
  placeholderIcon?: IconProps['variant']
  disabled?: boolean
  error?: boolean
}

function List({
  title,
  collapsible,
  onSelectChange,
  data,
  select,
  fields,
  onItemClick,
  itemActions,
  placeholder,
  placeholderIcon,
  error,
  disabled,
}: ListProps) {
  const [collapsed, setCollapsed] = useState(false)
  const [forceHover, setForceHover] = useState<string>()

  return (
    <div
      style={{
        width: '100%',
        height: '100%',
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      {title && (
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            minHeight: 44,
            padding: '0 16px',
            gap: 8,
            border: `1px solid ${colors.neutral20Adjusted}`,
            background: colors.neutral5,
            borderTopLeftRadius: radius[8],
            borderTopRightRadius: radius[8],
            ...(collapsed && {
              borderBottomLeftRadius: radius[8],
              borderBottomRightRadius: radius[8],
            }),
          }}
        >
          {onSelectChange && (
            <CheckboxInput
              value={data.length && data.every((e) => select?.includes(e.id))}
              onChange={() => {
                if (!select) {
                  onSelectChange(data.map((e) => e.id))
                  return
                }

                if (data.every((e) => select.includes(e.id))) {
                  onSelectChange([])
                  return
                }

                onSelectChange(data.map((e) => e.id))
              }}
            />
          )}
          <Text variant="display-medium" color="neutral80">
            {title}
          </Text>
          {collapsible && (
            <div
              style={{
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center',
                marginLeft: 'auto',
              }}
            >
              <IconButton
                size="small"
                icon={collapsed ? 'chevron-left' : 'chevron-down'}
                onClick={() => {
                  setCollapsed((p) => !p)
                }}
              />
            </div>
          )}
        </div>
      )}
      {!collapsed && (
        <div
          style={{
            height: '100%',
            padding: 8,
            overflowY: 'auto',
            overflowX: 'hidden',
            borderLeft: `1px solid ${colors.neutral20Adjusted}`,
            borderRight: `1px solid ${colors.neutral20Adjusted}`,
            borderBottom: `1px solid ${colors.neutral20Adjusted}`,
            borderBottomLeftRadius: radius[8],
            borderBottomRightRadius: radius[8],
            ...(!title && {
              borderTop: `1px solid ${colors.neutral20Adjusted}`,
              borderTopLeftRadius: radius[8],
              borderTopRightRadius: radius[8],
            }),
            display: 'flex',
            flexDirection: 'column',
            gap: 2,
            ...(error && {
              borderLeft: `1px solid ${colors.red80}`,
              borderRight: `1px solid ${colors.red80}`,
              borderBottom: `1px solid ${colors.red80}`,
              ...(!title && {
                borderTop: `1px solid ${colors.red80}`,
              }),
            }),
            ...(disabled && {
              cursor: 'not-allowed',
              color: colors.neutral20,
              background: colors.neutral5,
              borderLeft: `1px solid transparent`,
              borderRight: `1px solid transparent`,
              borderBottom: `1px solid transparent`,
              ...(!title && {
                borderTop: `1px solid transparent`,
              }),
            }),
          }}
        >
          {data?.length ? (
            data.map((item) => (
              <styled.div
                key={item.id}
                onClick={() => {
                  onItemClick?.(item)
                }}
                data-hover={[forceHover, ...(select ?? [])].includes(item.id)}
                style={{
                  flexShrink: 0,
                  maxWidth: '100%',
                  borderRadius: radius[8],
                  position: 'relative',
                  padding: itemActions
                    ? '0 calc(8px + 8px + 24px) 0 8px'
                    : '0 8px',
                  '&:hover, &[data-hover=true]': {
                    background: colors.neutral10Adjusted,
                  },
                }}
              >
                <div
                  style={{
                    display: 'flex',
                    alignItems: 'center',
                    gap: 8,
                    width: '100%',
                    height: 44,
                    overflow: 'hidden',
                  }}
                >
                  {onSelectChange && (
                    <div
                      onClick={(e) => {
                        e.stopPropagation()
                      }}
                      style={{
                        display: 'flex',
                        justifyContent: 'center',
                        alignItems: 'center',
                      }}
                    >
                      <CheckboxInput
                        value={select?.includes(item.id)}
                        onChange={() => {
                          if (!select) {
                            onSelectChange([item.id])
                            return
                          }

                          if (select.includes(item.id)) {
                            onSelectChange(select.filter((e) => e !== item.id))
                            return
                          }

                          onSelectChange([...select, item.id])
                        }}
                      />
                    </div>
                  )}
                  {Object.values(fields).map((field, index) => {
                    const hasContent = Boolean(
                      field.render
                        ? field.render(
                            field.renderAccessorFn
                              ? field.renderAccessorFn(item)
                              : item,
                            'table',
                          )
                        : item[field.key],
                    )

                    if (!hasContent) return null

                    return (
                      <Fragment key={field.key}>
                        {index !== 0 && (
                          <div
                            style={{
                              flexShrink: 0,
                              height: 2,
                              width: 2,
                              borderRadius: radius.full,
                              background: colors.neutral60,
                            }}
                          />
                        )}

                        <div
                          style={{
                            display: 'flex',
                            justifyContent: 'center',
                            alignItems: 'center',
                          }}
                        >
                          {field.render ? (
                            field.render(
                              field.renderAccessorFn
                                ? field.renderAccessorFn(item)
                                : item,
                              'table',
                            )
                          ) : (
                            <Text
                              singleLine
                              variant="display-medium"
                              color="neutral80"
                            >
                              {item[field.key]}
                            </Text>
                          )}
                        </div>
                      </Fragment>
                    )
                  })}
                  {itemActions && (
                    <Menu
                      onOpenChange={(open) => {
                        setForceHover(open ? item.id : undefined)
                      }}
                    >
                      <Menu.Trigger>
                        {({ open }) => (
                          <div
                            onClick={(e) => {
                              e.stopPropagation()
                            }}
                            style={{
                              display: 'flex',
                              position: 'absolute',
                              justifyContent: 'center',
                              alignItems: 'center',
                              right: 8,
                              top: 0,
                              bottom: 0,
                            }}
                          >
                            <IconButton
                              icon="more-vertical"
                              size="small"
                              forceHover={open}
                            />
                          </div>
                        )}
                      </Menu.Trigger>
                      <Menu.Items>
                        {itemActions.map((action) => (
                          <Menu.Item
                            key={action.label}
                            leadIcon={action.icon}
                            onClick={() => {
                              action?.onClick(item)
                            }}
                            color={action.color}
                          >
                            {action.label}
                          </Menu.Item>
                        ))}
                      </Menu.Items>
                    </Menu>
                  )}
                </div>
              </styled.div>
            ))
          ) : (
            <div
              style={{
                width: '100%',
                height: '100%',
                justifyContent: 'center',
                alignItems: 'center',
                display: 'flex',
                flexDirection: 'column',
                gap: 4,
                color: colors.neutral60,
              }}
            >
              {placeholderIcon && <Icon variant={placeholderIcon} />}
              {placeholder && (
                <Text variant="subtext-medium" color="inherit">
                  {placeholder}
                </Text>
              )}
            </div>
          )}
        </div>
      )}
    </div>
  )
}

export { List }
export type { ListProps }
