'use client'

import { useState } from 'react'
import { trpc } from '@/lib/trpc/client'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Skeleton } from '@/components/ui/skeleton'
import {
  FileText,
  Video,
  File,
  Download,
  ExternalLink,
  Play,
  FileImage,
  Loader2,
  AlertCircle,
  X,
} from 'lucide-react'
import { cn } from '@/lib/utils'

interface ProjectFile {
  id: string
  fileType: 'EXEC_SUMMARY' | 'PRESENTATION' | 'VIDEO' | 'OTHER' | 'BUSINESS_PLAN' | 'VIDEO_PITCH' | 'SUPPORTING_DOC'
  fileName: string
  mimeType: string
  size: number
  bucket: string
  objectKey: string
}

interface FileViewerProps {
  files: ProjectFile[]
  className?: string
}

function formatFileSize(bytes: number): string {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

function getFileIcon(fileType: string, mimeType: string) {
  if (mimeType.startsWith('video/')) return Video
  if (mimeType.startsWith('image/')) return FileImage
  if (mimeType === 'application/pdf') return FileText
  if (fileType === 'EXEC_SUMMARY' || fileType === 'PRESENTATION') return FileText
  if (fileType === 'VIDEO') return Video
  return File
}

function getFileTypeLabel(fileType: string) {
  switch (fileType) {
    case 'EXEC_SUMMARY':
      return 'Executive Summary'
    case 'PRESENTATION':
      return 'Presentation'
    case 'VIDEO':
      return 'Video'
    case 'BUSINESS_PLAN':
      return 'Business Plan'
    case 'VIDEO_PITCH':
      return 'Video Pitch'
    case 'SUPPORTING_DOC':
      return 'Supporting Document'
    default:
      return 'Attachment'
  }
}

export function FileViewer({ files, className }: FileViewerProps) {
  if (files.length === 0) {
    return (
      <Card className={className}>
        <CardContent className="flex flex-col items-center justify-center py-8 text-center">
          <File className="h-12 w-12 text-muted-foreground/50" />
          <p className="mt-2 font-medium">No files attached</p>
          <p className="text-sm text-muted-foreground">
            This project has no files uploaded yet
          </p>
        </CardContent>
      </Card>
    )
  }

  // Sort files by type order
  const sortOrder = ['EXEC_SUMMARY', 'BUSINESS_PLAN', 'PRESENTATION', 'VIDEO', 'VIDEO_PITCH', 'SUPPORTING_DOC', 'OTHER']
  const sortedFiles = [...files].sort(
    (a, b) => sortOrder.indexOf(a.fileType) - sortOrder.indexOf(b.fileType)
  )

  return (
    <Card className={className}>
      <CardHeader>
        <CardTitle className="text-lg">Project Files</CardTitle>
      </CardHeader>
      <CardContent className="space-y-3">
        {sortedFiles.map((file) => (
          <FileItem key={file.id} file={file} />
        ))}
      </CardContent>
    </Card>
  )
}

function FileItem({ file }: { file: ProjectFile }) {
  const [showPreview, setShowPreview] = useState(false)
  const Icon = getFileIcon(file.fileType, file.mimeType)

  const { data: urlData, isLoading: isLoadingUrl } = trpc.file.getDownloadUrl.useQuery(
    { bucket: file.bucket, objectKey: file.objectKey },
    { enabled: showPreview }
  )

  const canPreview = file.mimeType.startsWith('video/') || file.mimeType === 'application/pdf'

  return (
    <div className="space-y-2">
      <div className="flex items-center gap-3 rounded-lg border p-3">
        <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-muted">
          <Icon className="h-5 w-5 text-muted-foreground" />
        </div>

        <div className="flex-1 min-w-0">
          <p className="font-medium truncate">{file.fileName}</p>
          <div className="flex items-center gap-2 text-sm text-muted-foreground">
            <Badge variant="secondary" className="text-xs">
              {getFileTypeLabel(file.fileType)}
            </Badge>
            <span>{formatFileSize(file.size)}</span>
          </div>
        </div>

        <div className="flex items-center gap-2">
          {canPreview && (
            <Button
              variant="outline"
              size="sm"
              onClick={() => setShowPreview(!showPreview)}
            >
              {showPreview ? (
                <>
                  <X className="mr-2 h-4 w-4" />
                  Close
                </>
              ) : (
                <>
                  <Play className="mr-2 h-4 w-4" />
                  Preview
                </>
              )}
            </Button>
          )}
          <FileDownloadButton file={file} />
        </div>
      </div>

      {/* Preview area */}
      {showPreview && (
        <div className="rounded-lg border bg-muted/50 overflow-hidden">
          {isLoadingUrl ? (
            <div className="flex items-center justify-center py-8">
              <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
            </div>
          ) : urlData?.url ? (
            <FilePreview file={file} url={urlData.url} />
          ) : (
            <div className="flex items-center justify-center py-8 text-muted-foreground">
              <AlertCircle className="mr-2 h-4 w-4" />
              Failed to load preview
            </div>
          )}
        </div>
      )}
    </div>
  )
}

function FileDownloadButton({ file }: { file: ProjectFile }) {
  const [downloading, setDownloading] = useState(false)

  const { refetch } = trpc.file.getDownloadUrl.useQuery(
    { bucket: file.bucket, objectKey: file.objectKey },
    { enabled: false }
  )

  const handleDownload = async () => {
    setDownloading(true)
    try {
      const result = await refetch()
      if (result.data?.url) {
        // Open in new tab for download
        window.open(result.data.url, '_blank')
      }
    } catch (error) {
      console.error('Failed to get download URL:', error)
    } finally {
      setDownloading(false)
    }
  }

  return (
    <Button
      variant="outline"
      size="sm"
      onClick={handleDownload}
      disabled={downloading}
      aria-label="Download file"
    >
      {downloading ? (
        <Loader2 className="h-4 w-4 animate-spin" />
      ) : (
        <Download className="h-4 w-4" />
      )}
    </Button>
  )
}

function FilePreview({ file, url }: { file: ProjectFile; url: string }) {
  if (file.mimeType.startsWith('video/')) {
    return (
      <video
        src={url}
        controls
        className="w-full max-h-[500px]"
        preload="metadata"
      >
        Your browser does not support the video tag.
      </video>
    )
  }

  if (file.mimeType === 'application/pdf') {
    return (
      <div className="relative">
        <iframe
          src={`${url}#toolbar=0`}
          className="w-full h-[600px]"
          title={file.fileName}
        />
        <Button
          variant="secondary"
          size="sm"
          className="absolute top-2 right-2"
          asChild
        >
          <a href={url} target="_blank" rel="noopener noreferrer">
            <ExternalLink className="mr-2 h-4 w-4" />
            Open in new tab
          </a>
        </Button>
      </div>
    )
  }

  return (
    <div className="flex items-center justify-center py-8 text-muted-foreground">
      Preview not available for this file type
    </div>
  )
}

// Compact file list for smaller views
export function FileList({ files, className }: FileViewerProps) {
  if (files.length === 0) return null

  return (
    <div className={cn('space-y-2', className)}>
      {files.map((file) => {
        const Icon = getFileIcon(file.fileType, file.mimeType)
        return (
          <CompactFileItem key={file.id} file={file} />
        )
      })}
    </div>
  )
}

function CompactFileItem({ file }: { file: ProjectFile }) {
  const [loading, setLoading] = useState(false)
  const Icon = getFileIcon(file.fileType, file.mimeType)

  const { refetch } = trpc.file.getDownloadUrl.useQuery(
    { bucket: file.bucket, objectKey: file.objectKey },
    { enabled: false }
  )

  const handleClick = async () => {
    setLoading(true)
    try {
      const result = await refetch()
      if (result.data?.url) {
        window.open(result.data.url, '_blank')
      }
    } catch (error) {
      console.error('Failed to get download URL:', error)
    } finally {
      setLoading(false)
    }
  }

  return (
    <button
      onClick={handleClick}
      disabled={loading}
      className="flex w-full items-center gap-2 rounded-md border p-2 text-left hover:bg-muted transition-colors disabled:opacity-50"
    >
      {loading ? (
        <Loader2 className="h-4 w-4 animate-spin shrink-0" />
      ) : (
        <Icon className="h-4 w-4 shrink-0 text-muted-foreground" />
      )}
      <span className="flex-1 truncate text-sm">{file.fileName}</span>
      <span className="text-xs text-muted-foreground shrink-0">
        {formatFileSize(file.size)}
      </span>
    </button>
  )
}

export function FileViewerSkeleton() {
  return (
    <Card>
      <CardHeader>
        <Skeleton className="h-5 w-28" />
      </CardHeader>
      <CardContent className="space-y-3">
        {[1, 2, 3].map((i) => (
          <div key={i} className="flex items-center gap-3 rounded-lg border p-3">
            <Skeleton className="h-10 w-10 rounded-lg" />
            <div className="flex-1 space-y-2">
              <Skeleton className="h-4 w-48" />
              <Skeleton className="h-3 w-24" />
            </div>
            <Skeleton className="h-9 w-20" />
          </div>
        ))}
      </CardContent>
    </Card>
  )
}
