import { useCallback } from 'react';
import {
  fileConfig as defaultFileConfig,
  checkOpenAIStorage,
  mergeFileConfig,
  megabyte,
  isAssistantsEndpoint,
} from 'librechat-data-provider';
import type { Row } from '@tanstack/react-table';
import type { TFile } from 'librechat-data-provider';
import { useFileMapContext, useChatContext, useToastContext } from '~/Providers';
import ImagePreview from '~/components/Chat/Input/Files/ImagePreview';
import FilePreview from '~/components/Chat/Input/Files/FilePreview';
import { useUpdateFiles, useLocalize } from '~/hooks';
import { useGetFileConfig } from '~/data-provider';
import { getFileType } from '~/utils';

export default function PanelFileCell({ row }: { row: Row<TFile> }) {
  const localize = useLocalize();
  const fileMap = useFileMapContext();
  const { showToast } = useToastContext();
  const { setFiles, conversation } = useChatContext();
  const { data: fileConfig = defaultFileConfig } = useGetFileConfig({
    select: (data) => mergeFileConfig(data),
  });
  const { addFile } = useUpdateFiles(setFiles);

  const handleFileClick = useCallback(() => {
    const file = row.original;
    const endpoint = conversation?.endpoint;
    const fileData = fileMap?.[file.file_id];

    if (!fileData) {
      return;
    }

    if (!endpoint) {
      return showToast({ message: localize('com_ui_attach_error'), status: 'error' });
    }

    if (checkOpenAIStorage(fileData?.source ?? '') && !isAssistantsEndpoint(endpoint)) {
      return showToast({
        message: localize('com_ui_attach_error_openai'),
        status: 'error',
      });
    } else if (!checkOpenAIStorage(fileData?.source ?? '') && isAssistantsEndpoint(endpoint)) {
      showToast({
        message: localize('com_ui_attach_warn_endpoint'),
        status: 'warning',
      });
    }

    const { fileSizeLimit, supportedMimeTypes } =
      fileConfig.endpoints[endpoint] ?? fileConfig.endpoints.default;

    if (fileData.bytes > fileSizeLimit) {
      return showToast({
        message: `${localize('com_ui_attach_error_size')} ${
          fileSizeLimit / megabyte
        } MB (${endpoint})`,
        status: 'error',
      });
    }

    const isSupportedMimeType = defaultFileConfig.checkType(file.type, supportedMimeTypes);

    if (!isSupportedMimeType) {
      return showToast({
        message: `${localize('com_ui_attach_error_type')} ${file.type} (${endpoint})`,
        status: 'error',
      });
    }

    addFile({
      progress: 1,
      attached: true,
      file_id: fileData.file_id,
      filepath: fileData.filepath,
      preview: fileData.filepath,
      type: fileData.type,
      height: fileData.height,
      width: fileData.width,
      filename: fileData.filename,
      source: fileData.source,
      size: fileData.bytes,
    });
  }, [addFile, fileMap, row.original, conversation, localize, showToast, fileConfig.endpoints]);

  const file = row.original;
  if (file.type?.startsWith('image')) {
    return (
      <div
        onClick={handleFileClick}
        className="flex cursor-pointer gap-2 rounded-md dark:hover:bg-gray-700"
      >
        <ImagePreview
          url={file.filepath}
          className="relative h-10 w-10 shrink-0 overflow-hidden rounded-md"
          source={file.source}
        />
        <span className="self-center truncate text-xs">{file.filename}</span>
      </div>
    );
  }

  const fileType = getFileType(file.type);
  return (
    <div
      onClick={handleFileClick}
      className="flex cursor-pointer gap-2 rounded-md dark:hover:bg-gray-700"
    >
      {fileType && <FilePreview fileType={fileType} className="relative" file={file} />}
      <span className="self-center truncate">{file.filename}</span>
    </div>
  );
}
