import { useParams } from 'common'
import { AlertCircle, LoaderCircle, X } from 'lucide-react'
import SVG from 'react-inlinesvg'
import { Button } from 'ui'

import { StorageItemWithColumn } from '../Storage.types'
import { useFetchFileUrlQuery } from '../StorageExplorer/useFetchFileUrlQuery'
import { useBucketFilePickerStateSnapshot } from './BucketFilePickerState'
import { BASE_PATH } from '@/lib/constants'
import { formatBytes } from '@/lib/helpers'

const PREVIEW_SIZE_LIMIT = 10 * 1024 * 1024 // 10MB

const PreviewFile = ({ item }: { item: StorageItemWithColumn }) => {
  const { ref: projectRef } = useParams()
  const { bucket, columns } = useBucketFilePickerStateSnapshot()
  const path = columns.slice(0, item.columnIndex).concat(item.name).join('/')

  const { data: previewUrl, isPending: isLoading } = useFetchFileUrlQuery({
    path,
    projectRef: projectRef!,
    bucket,
  })

  // if the size is not available, we set it to be greater than the max size
  const size = +(item.metadata?.size ?? PREVIEW_SIZE_LIMIT + 1)
  const mimeType = item.metadata?.mimetype

  const isSkipped = !!mimeType && !!size && size > PREVIEW_SIZE_LIMIT

  if (isLoading) {
    return (
      <div className="flex h-full w-full items-center justify-center text-foreground-lighter">
        <LoaderCircle size={14} strokeWidth={2} className="animate-spin text-foreground-lighter" />
      </div>
    )
  }
  if (isSkipped) {
    return (
      <div className="flex h-full w-full flex-col items-center justify-center">
        <SVG
          src={`${BASE_PATH}/img/file-filled.svg`}
          preProcessor={(code) =>
            code.replace(/svg/, 'svg class="mx-auto w-32 h-32 text-color-inherit opacity-75"')
          }
        />
        <p className="mt-2 w-2/5 text-center text-sm">
          File size is too large to preview in the explorer
        </p>
      </div>
    )
  }
  if (!mimeType || !previewUrl) {
    return (
      <SVG
        src={`${BASE_PATH}/img/file-filled.svg`}
        preProcessor={(code) =>
          code.replace(/svg/, 'svg class="mx-auto w-32 h-32 text-color-inherit opacity-75"')
        }
      />
    )
  }

  if (mimeType.includes('image')) {
    return (
      <div
        className="flex h-full w-full items-center justify-center bg-contain bg-center bg-no-repeat"
        style={{ backgroundImage: `url('${previewUrl}')` }}
      />
    )
  }
  if (mimeType.includes('audio')) {
    return (
      <div className="flex h-full w-full items-center justify-center px-10">
        <audio key={previewUrl} controls style={{ width: 'inherit' }}>
          <source src={previewUrl} type="audio/mpeg" />
          <p className="text-sm text-foreground-light">
            Your browser does not support the audio element.
          </p>
        </audio>
      </div>
    )
  }
  if (mimeType.includes('video')) {
    return (
      <div className="flex h-full w-full items-center justify-center">
        <video key={previewUrl} controls style={{ maxHeight: '100%' }}>
          <source src={previewUrl} type="video/mp4" />
          <p className="text-sm text-foreground-light">
            Your browser does not support the video tag.
          </p>
        </video>
      </div>
    )
  }
  return (
    <SVG
      src={`${BASE_PATH}/img/file-filled.svg`}
      preProcessor={(code) =>
        code.replace(/svg/, 'svg class="mx-auto w-32 h-32 text-color-inherit opacity-75"')
      }
    />
  )
}

export const PreviewPane = ({ onSelect }: { onSelect: (url: string) => void }) => {
  const { ref: projectRef } = useParams()
  const {
    selectedFilePreview: file,
    setSelectedFilePreview,
    bucket,
    columns,
  } = useBucketFilePickerStateSnapshot()

  const path = file ? columns.slice(0, file.columnIndex).concat(file.name).join('/') : ''
  const { data: previewUrl, isLoading } = useFetchFileUrlQuery(
    { path, projectRef: projectRef!, bucket },
    { enabled: !!file }
  )

  if (!file) return null

  const size = file.metadata ? formatBytes(file.metadata.size) : null
  const mimeType = file.metadata ? file.metadata.mimetype : undefined
  const createdAt = file.created_at ? new Date(file.created_at).toLocaleString() : 'Unknown'
  const updatedAt = file.updated_at ? new Date(file.updated_at).toLocaleString() : 'Unknown'

  return (
    <div className="h-full border-l border-overlay bg-surface-100 overflow-y-auto w-[450px] pb-4">
      {/* Preview Header */}
      <div className="flex w-full justify-end items-center gap-2 sticky top-0 bg-surface-100 p-4 border-b">
        <Button
          size="tiny"
          onClick={() => onSelect(previewUrl!)}
          disabled={!previewUrl}
          loading={isLoading}
        >
          Select
        </Button>
        <div className="text-foreground-lighter transition-colors hover:text-foreground">
          <X
            className="cursor-pointer"
            size={14}
            strokeWidth={2}
            onClick={() => setSelectedFilePreview(undefined)}
          />
        </div>
      </div>

      {/* Preview Thumbnail*/}
      <div className="my-4 border border-overlay mx-4">
        <div className="flex h-56 w-full items-center 2xl:h-72">
          <PreviewFile item={file} />
        </div>
      </div>

      <div className="w-full space-y-6 px-4">
        {/* Preview Information */}
        <div className="space-y-1">
          <h5 className="wrap-break-word text-base text-foreground">{file.name}</h5>
          {file.isCorrupted && (
            <div className="flex items-center space-x-2">
              <AlertCircle size={14} strokeWidth={2} className="text-foreground-light" />
              <p className="text-sm text-foreground-light">
                File is corrupted, please delete and reupload this file again
              </p>
            </div>
          )}
          {mimeType && (
            <p className="text-sm text-foreground-light">
              {mimeType}
              {size && <span> - {size}</span>}
            </p>
          )}
        </div>

        {/* Preview Metadata */}
        <div className="space-y-2">
          <div>
            <label className="mb-1 text-xs text-foreground-lighter">Added on</label>
            <p className="text-sm text-foreground-light">{createdAt}</p>
          </div>
          <div>
            <label className="mb-1 text-xs text-foreground-lighter">Last modified</label>
            <p className="text-sm text-foreground-light">{updatedAt}</p>
          </div>
        </div>
      </div>
    </div>
  )
}
