import { Card, Flex, Typography, Button, Tag, Divider } from 'antd'
import PropTypes from 'prop-types'
import FileIcon from '../../Icons/FileIcon'
import BinIcon from '../../Icons/BinIcon'
import EyeIcon from '../../Icons/EyeIcon'
import DownloadIcon from '../../Icons/DownloadIcon'
import { useContext, useState } from 'react'
import { ApiServerContext } from '../context/ApiServerContext'
import FilePreview from './FilePreview'
import EyeSlashIcon from '../../Icons/EyeSlashIcon'
import { getModelByName } from '../../../database/ObjectModels'
import InfoCircleIcon from '../../Icons/InfoCircleIcon'
import { useNavigate } from 'react-router-dom'

const { Text } = Typography

const FileList = ({
  files,
  onChange,
  multiple = true,
  editing = false,
  showPreview = true,
  showInfo = true,
  showDownload = true,
  defaultPreviewOpen = false,
  minimal = false,
  card = true,
  maxWidth = '100%'
}) => {
  const { fetchFileContent, flushFile } = useContext(ApiServerContext)
  const navigate = useNavigate()
  const [previewOpen, setPreviewOpen] = useState(defaultPreviewOpen)
  const infoAction = getModelByName('file').actions.filter(
    (action) => action.name == 'info'
  )[0]
  // Check if there are no items in the list
  const hasNoItems = multiple
    ? !files || !Array.isArray(files) || files.length === 0
    : !files

  if (hasNoItems) {
    return null
  }

  const handleRemove = (fileToRemove) => {
    flushFile(fileToRemove._id)
    if (multiple) {
      const currentFiles = Array.isArray(files) ? files : []
      const updatedFiles = currentFiles.filter((file) => {
        const fileUid = file._id || file.id
        const removeUid = fileToRemove._id || fileToRemove.id
        return fileUid !== removeUid
      })
      onChange(updatedFiles)
    } else {
      onChange(null)
    }
  }

  const handleDownload = async (file) => {
    await fetchFileContent(file, true)
  }

  const filesToRender = multiple ? files : [files]

  const renderFileContent = (file) => (
    <Flex
      vertical
      gap='10px'
      style={{
        maxWidth: '100%',
        minWidth: 0,
        width: card ? '100%' : 'fit-content'
      }}
    >
      <Flex
        justify={card ? 'space-between' : 'start'}
        align='center'
        gap='small'
        wrap={false}
        style={{
          maxWidth: '100%',
          minWidth: 0,
          width: card ? '100%' : 'fit-content'
        }}
      >
        <Flex
          gap={'small'}
          align='center'
          style={{ minWidth: 0, flex: '0 1 auto', overflow: 'hidden' }}
        >
          <FileIcon
            style={{ margin: 0, fontSize: card == true ? '24px' : '16px' }}
          />

          <Text style={{ marginTop: '1px', minWidth: 0 }} ellipsis>
            {file.name || file.filename || 'Unknown file'}
          </Text>
          {file.extension && <Tag style={{ margin: 0 }}>{file.extension}</Tag>}
        </Flex>
        {!minimal && (
          <Flex gap={'small'} align='center'>
            {showDownload && (
              <Button
                icon={<DownloadIcon />}
                size='small'
                type='text'
                onClick={() => handleDownload(file)}
              />
            )}
            {showPreview && (
              <Button
                icon={previewOpen ? <EyeSlashIcon /> : <EyeIcon />}
                size='small'
                type='text'
                onClick={() => {
                  if (previewOpen == true) {
                    setPreviewOpen(false)
                  } else {
                    setPreviewOpen(true)
                  }
                }}
              />
            )}
            {showInfo && (
              <Button
                icon={<InfoCircleIcon />}
                size='small'
                type='text'
                onClick={() => {
                  navigate(infoAction.url(file._id))
                }}
              />
            )}
            {editing && (
              <Button
                icon={<BinIcon />}
                size='small'
                type='text'
                onClick={() => handleRemove(file)}
              />
            )}
          </Flex>
        )}
      </Flex>
      {previewOpen && !minimal ? (
        <>
          <Divider style={{ marginTop: 0, marginBottom: card ? 0 : '4px' }} />
          <FilePreview file={file} style={{ width: '100%' }} />
        </>
      ) : null}
    </Flex>
  )

  const rootStyle = {
    minWidth: 0,
    maxWidth,
    ...(card
      ? { width: '100%' }
      : { width: 'fit-content', alignSelf: 'flex-start' })
  }

  return (
    <div style={rootStyle}>
      {filesToRender.map((file, index) => {
        const key = file._id || file.id || index
        const style = {
          marginTop: index > 0 && multiple ? '4px' : undefined
        }

        if (card) {
          return (
            <Card
              styles={{ body: { padding: '10px' } }}
              key={key}
              style={style}
            >
              {renderFileContent(file)}
            </Card>
          )
        } else {
          return (
            <div
              key={key}
              style={{
                ...style
              }}
            >
              {index > 0 && <Divider />}
              {renderFileContent(file)}
            </div>
          )
        }
      })}
    </div>
  )
}

FileList.propTypes = {
  files: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
  onChange: PropTypes.func,
  multiple: PropTypes.bool,
  editing: PropTypes.bool,
  showPreview: PropTypes.string,
  showInfo: PropTypes.bool,
  showDownload: PropTypes.bool,
  defaultPreviewOpen: PropTypes.bool,
  card: PropTypes.bool,
  minimal: PropTypes.bool,
  maxWidth: PropTypes.string
}

export default FileList
