import moment from 'moment'
import { useState, useEffect } from 'react'
import { DatePicker, Button, Input } from 'antd'

import { FileService } from '@api'
import { hasPermission } from '@utils/permissions'
import LoaderPortal from '@components/LoaderPortal'
import { UploadForm } from '@components/UploadForm'
import { CompanyView, UserView } from  '@components/views'
import { EditableTable, makePaginationObject } from '@components/Table'
import { invokeWebApiWrapperAsync, downloadFile, formatBytes } from '@components/factory'

const pageSize = 12
const { RangePicker } = DatePicker
const { Search } = Input

const columns = [
  {
    title: 'Документ',
    key: 'document',
    dataIndex: 'name',
    render: (name, row) => (
      <Button type={'link'} onClick={() => downloadFile(row)} download={name}>
        {name}
      </Button>
    ),
  }, {
    title: 'Дата загрузки',
    key: 'uploadDate',
    dataIndex: 'uploadDate',
    render: item => moment.utc(item).local().format('DD MMM YYYY, HH:mm:ss'),
  }, {
    title: 'Размер',
    key: 'size',
    dataIndex: 'size',
    render: item => formatBytes(item)
  }, {
    title: 'Автор',
    key: 'author',
    dataIndex: 'author',
    render: item => <UserView user={item}/>
  }, {
    title: 'Компания',
    key: 'company',
    render: (_, record) => <CompanyView company={record?.author?.company}/>
  }
]

export const DocumentsTemplate = ({ idCategory, idWell, accept, headerChild, customColumns, beforeTable, onChange}) => {
  const [page, setPage] = useState(1)
  const [filterDataRange, setFilterDataRange] = useState([])
  const [filterCompanyName, setFilterCompanyName] = useState([])
  const [filterFileName, setFilterFileName] = useState('')
  const [pagination, setPagination] = useState(null)
  const [files, setFiles] = useState([])
  const [showLoader, setShowLoader] = useState(false)

  const uploadUrl = `/api/well/${idWell}/files/?idCategory=${idCategory}`

  const handleUploadComplete = () => update()

  const handleFileDelete = async (file) => {
    await FileService.delete(idWell, file.id)
    update()
  }

  const hanleCompanySearch = (value, _) => setFilterCompanyName(value)
  const hanleFileNameSearch = (value, _) => setFilterFileName(value)

  const mergedColumns = [...columns, ...(customColumns ?? [])]

  const update = () => {
    let begin = null
    let end = null
    if (filterDataRange?.length > 1) {
      begin = filterDataRange[0].toISOString()
      end = filterDataRange[1].toISOString()
    }

    invokeWebApiWrapperAsync(
      async () => {
        const paginatedFiles = await FileService.getFilesInfo(
          idWell,
          idCategory,
          filterCompanyName,
          filterFileName,
          begin,
          end,
          (page - 1) * pageSize,
          pageSize,
        )

        if (!paginatedFiles) return

        const filesInfos = paginatedFiles.items ?? []
        setFiles(filesInfos)
        const newPagination = makePaginationObject(paginatedFiles)
        setPagination(newPagination)
      },
      setShowLoader,
      `Не удалось загрузить файлы по скважине "${idWell}"`,
      'Загрузка файла по скважине'
    )
  }

  useEffect(update, [idWell, idCategory, page, filterDataRange, filterCompanyName, filterFileName])
  useEffect(() => onChange?.(files), [files, onChange])

  const companies = [...new Set(files.map(file => file.company))].filter(company => company)
  const filenames = [...new Set(files.map(file => file.name))].filter(name => name)

  return (
    <LoaderPortal show={showLoader}>
      <div style={{ margin: 16, display: 'flex' }}>
        <div>
          <span>Фильтр по дате</span>
          <div>
            <RangePicker showTime onChange={setFilterDataRange} />
          </div>
        </div>
        &nbsp;
        <div>
          <span>Фильтр по компании</span>
          <Search
            list={'listCompanies'}
            placeholder={'Фильтр по компании'}
            onSearch={hanleCompanySearch}
          />
          <datalist id={'listCompanies'}>
            {companies.map((company) => (
              <option key={company} value={company}>{company}</option>
            ))}
          </datalist>
        </div>
        &nbsp;
        <div>
          <span>Фильтр по имени файла</span>
          <Search
            list={'listFileNames'}
            placeholder={'Фильтр по имени файла'}
            onSearch={hanleFileNameSearch}
          />
          <datalist id={'listFileNames'}>
            {filenames.map((name) => (
              <option key={name} value={name}>{name}</option>
            ))}
          </datalist>
        </div>
        &nbsp;&nbsp;
        {hasPermission(`File.edit${idCategory}`) && (
          <div>
            <span>Загрузка</span>
            <UploadForm
              url={uploadUrl}
              accept={accept}
              onUploadStart={() => setShowLoader(true)}
              onUploadComplete={handleUploadComplete}
            />
          </div>
        )}
        &nbsp;&nbsp;
        {headerChild}
      </div>
      {beforeTable}
      <EditableTable
        columns={mergedColumns}
        dataSource={files}
        size={'small'}
        pagination={{
          ...pagination,
          showSizeChanger: false,
          onChange: (page) => setPage(page),
        }}
        onRowDelete={hasPermission(`File.edit${idCategory}`) && handleFileDelete}
        rowKey={(record) => record.id}
      />
    </LoaderPortal>
  )
}

export default DocumentsTemplate
