"use client"

import type React from "react"
import { useState, useRef } from "react"
import Link from "next/link"
import {
  ChevronRight,
  File,
  Folder,
  Upload,
  Trash2,
  Move,
  MoreHorizontal,
  Edit,
  Link as LinkIcon,
  Info,
  FolderPlus,
} from "lucide-react"
import { Button } from "@/components/ui/button"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
  DropdownMenuSeparator,
} from "@/components/ui/dropdown-menu"
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Checkbox } from "@/components/ui/checkbox"
import { toast } from "@/hooks/use-toast"
import { DriveLsEntry } from "@/lib/drive_types"
import { UPLOAD_MAX_FILE_SIZE, UPLOAD_MAX_FILES } from "@/lib/constants"
import { formatFileSize } from "@/lib/utils"
import { DriveMoveDialog } from "./DriveMoveDialog"
import { StorageUsage } from "./StorageUsage"
import type { StorageData } from "@/lib/storage"
import type { UserAuth } from "@/lib/auth_types"

function formatDate(timestamp: number): string {
  return new Date(timestamp * 1000).toISOString().split('T')[0]
}

function formatDateTime(timestamp: number): string {
  const date = new Date(timestamp * 1000)
  const dateStr = date.toISOString().split('T')[0]
  const timeStr = date.toLocaleTimeString('en-US', {
    hour12: false,
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
  return `${dateStr} at ${timeStr}`
}

interface Breadcrumb {
  name: string
  path: string
}


interface DriveDirectoryClientProps {
  path: string
  files: DriveLsEntry[]
  breadcrumbs: Breadcrumb[]
  storageData: StorageData
  userAuth: UserAuth
}

export function DriveDirectoryClient({ path, files, breadcrumbs, storageData, userAuth }: DriveDirectoryClientProps) {
  const [selectedFiles, setSelectedFiles] = useState<Set<string>>(new Set())
  const [renameDialogOpen, setRenameDialogOpen] = useState(false)
  const [infoDialogOpen, setInfoDialogOpen] = useState(false)
  const [moveDialogOpen, setMoveDialogOpen] = useState(false)
  const [createFolderDialogOpen, setCreateFolderDialogOpen] = useState(false)
  const [currentItem, setCurrentItem] = useState<DriveLsEntry | null>(null)
  const [newName, setNewName] = useState("")
  const [newFolderName, setNewFolderName] = useState("")
  const fileInputRef = useRef<HTMLInputElement>(null)
  const [uploading, setUploading] = useState(false)


  const toggleFileSelection = (filePath: string) => {
    const newSelected = new Set(selectedFiles)
    if (newSelected.has(filePath)) {
      newSelected.delete(filePath)
    } else {
      newSelected.add(filePath)
    }
    setSelectedFiles(newSelected)
  }

  const deselectAll = () => {
    setSelectedFiles(new Set())
  }

  const openRenameDialog = (item: DriveLsEntry) => {
    setCurrentItem(item)
    setNewName(item.path.split('/').pop() || '')
    setRenameDialogOpen(true)
  }

  const openInfoDialog = (item: DriveLsEntry) => {
    setCurrentItem(item)
    setInfoDialogOpen(true)
  }

  const openMoveDialog = () => {
    setMoveDialogOpen(true)
  }

  const copyPermalink = (item: DriveLsEntry) => {
    if (!item.blob) {
      toast({
        title: "Cannot copy permalink",
        description: "This item does not have a blob ID",
        variant: "destructive"
      })
      return
    }

    const filename = item.path.split('/').pop() || 'download'
    const permalink = `${window.location.origin}/blob/${item.blob}?filename=${encodeURIComponent(filename)}`
    navigator.clipboard.writeText(permalink).then(() => {
      toast({
        title: "Permalink copied!",
        description: "Permanent blob link has been copied to clipboard",
      })
    })
  }

  const handleRename = async () => {
    if (!currentItem || !newName.trim()) return

    try {
      // Calculate the new full path by replacing the filename
      const pathParts = currentItem.path.split('/')
      pathParts[pathParts.length - 1] = newName.trim()
      const newPath = pathParts.join('/')

      const response = await fetch('/api/rename', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          oldPath: currentItem.path,
          newPath: newPath
        })
      })

      const result = await response.json()

      if (response.ok) {
        setRenameDialogOpen(false)
        setCurrentItem(null)
        setNewName("")
        toast({
          title: "Renamed successfully",
          description: result.message,
        })

        window.location.reload()
      } else {
        throw new Error(result.error || `Rename failed with status ${response.status}`)
      }
    } catch (error) {
      console.error('Rename error:', error)
      toast({
        title: "Rename failed",
        description: error instanceof Error ? error.message : 'Unknown error occurred',
        variant: "destructive"
      })
    }
  }

  const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const uploadedFiles = event.target.files
    if (!uploadedFiles || uploadedFiles.length === 0) return

    // Validate file count
    if (uploadedFiles.length > UPLOAD_MAX_FILES) {
      toast({
        title: "Too many files",
        description: `You can only upload up to ${UPLOAD_MAX_FILES} files at once`,
        variant: "destructive"
      })
      return
    }

    // Validate file sizes
    const oversizedFiles = Array.from(uploadedFiles).filter(file => file.size > UPLOAD_MAX_FILE_SIZE)
    if (oversizedFiles.length > 0) {
      toast({
        title: "Files too large",
        description: `Maximum file size is ${formatFileSize(UPLOAD_MAX_FILE_SIZE)}. Found ${oversizedFiles.length} oversized file(s)`,
        variant: "destructive"
      })
      return
    }

    setUploading(true)
    let successCount = 0
    let errorCount = 0

    try {
      // Upload files sequentially to the current directory
      for (const file of Array.from(uploadedFiles)) {
        try {
          const formData = new FormData()
          formData.append('file', file)

          // Use the new simple upload endpoint with path as query parameter
          const response = await fetch(`/api/upload?path=${encodeURIComponent(path)}`, {
            method: 'POST',
            body: formData
          })

          if (!response.ok) {
            const error = await response.json()
            throw new Error(error.error || `Upload failed with status ${response.status}`)
          }

          successCount++
        } catch (error) {
          console.error(`Failed to upload ${file.name}:`, error)
          errorCount++
        }
      }

      // Show results
      if (successCount > 0) {
        toast({
          title: "Upload successful",
          description: `${successCount} file(s) uploaded successfully${errorCount > 0 ? `, ${errorCount} failed` : ''}`
        })

        window.location.reload()
      }

      if (errorCount > 0 && successCount === 0) {
        toast({
          title: "Upload failed",
          description: `All ${errorCount} file(s) failed to upload`,
          variant: "destructive"
        })
      }

    } catch (error) {
      console.error('Upload error:', error)
      toast({
        title: "Upload failed",
        description: error instanceof Error ? error.message : 'Unknown error occurred',
        variant: "destructive"
      })
    } finally {
      setUploading(false)
      // Reset the input
      event.target.value = ''
    }
  }

  const handleDelete = async (itemPaths: string[]) => {
    try {
      const response = await fetch('/api/delete', {
        method: 'DELETE',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ paths: itemPaths })
      })

      const result = await response.json()

      if (response.ok) {
        setSelectedFiles(new Set())
        toast({
          title: "Deleted successfully",
          description: result.message,
        })

        window.location.reload()
      } else {
        throw new Error(result.error || `Delete failed with status ${response.status}`)
      }
    } catch (error) {
      console.error('Delete error:', error)
      toast({
        title: "Delete failed",
        description: error instanceof Error ? error.message : 'Unknown error occurred',
        variant: "destructive"
      })
    }
  }


  const handleMove = async (destinationPath: string) => {
    const filesToMove = Array.from(selectedFiles)
    let successCount = 0
    let errorCount = 0
    const errors: string[] = []

    try {
      // Move files sequentially using the rename API
      for (const filePath of filesToMove) {
        try {
          // Extract filename from the full path
          const fileName = filePath.split('/').pop() || ''
          // Construct new path: destination + filename
          const newPath = destinationPath.endsWith('/')
            ? `${destinationPath}${fileName}`
            : `${destinationPath}/${fileName}`

          const response = await fetch('/api/rename', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              oldPath: filePath,
              newPath: newPath
            })
          })

          if (!response.ok) {
            const result = await response.json()
            throw new Error(result.error || `Move failed with status ${response.status}`)
          }

          successCount++
        } catch (error) {
          console.error(`Failed to move ${filePath}:`, error)
          errorCount++
          errors.push(`${filePath}: ${error instanceof Error ? error.message : 'Unknown error'}`)
        }
      }

      // Clear selection and close dialog
      setSelectedFiles(new Set())
      setMoveDialogOpen(false)

      // Show results
      if (successCount > 0) {
        toast({
          title: "Move completed",
          description: `${successCount} item(s) moved successfully${errorCount > 0 ? `, ${errorCount} failed` : ''}`,
        })

        window.location.reload()
      }

      if (errorCount > 0 && successCount === 0) {
        toast({
          title: "Move failed",
          description: `All ${errorCount} item(s) failed to move. ${errors[0] || ''}`,
          variant: "destructive"
        })
      } else if (errorCount > 0) {
        toast({
          title: "Partial move failure",
          description: `${errorCount} item(s) failed to move. Check console for details.`,
          variant: "destructive"
        })
        console.error('Move errors:', errors)
      }

    } catch (error) {
      console.error('Move error:', error)
      setSelectedFiles(new Set())
      setMoveDialogOpen(false)
      toast({
        title: "Move failed",
        description: error instanceof Error ? error.message : 'Unknown error occurred',
        variant: "destructive"
      })
    }
  }

  const handleCreateFolder = async () => {
    if (!newFolderName.trim()) return

    try {
      const response = await fetch('/api/mkdir', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          path: path,
          name: newFolderName.trim()
        })
      })

      const result = await response.json()

      if (response.ok) {
        setCreateFolderDialogOpen(false)
        setNewFolderName("")
        toast({
          title: "Folder created",
          description: result.message,
        })

        window.location.reload()
      } else {
        throw new Error(result.error || `Failed to create folder`)
      }
    } catch (error) {
      console.error('Create folder error:', error)
      toast({
        title: "Failed to create folder",
        description: error instanceof Error ? error.message : 'Unknown error occurred',
        variant: "destructive"
      })
    }
  }

  const handleUploadButtonClick = () => {
    if (!userAuth.isLoggedIn) {
      toast({
        title: "Authentication required",
        description: "User is not authenticated. Please log in to upload files.",
        variant: "destructive"
      })
      return
    }

    fileInputRef.current?.click()
  }

  const handleCreateFolderButtonClick = () => {
    if (!userAuth.isLoggedIn) {
      toast({
        title: "Authentication required",
        description: "User is not authenticated. Please log in to create folders.",
        variant: "destructive"
      })
      return
    }

    setCreateFolderDialogOpen(true)
  }

  return (
    <div className="space-y-6">
      {/* Storage Info */}
      <StorageUsage data={storageData} />

      {/* Navigation and Actions */}
      <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
        {/* Breadcrumbs */}
        <nav className="flex items-center gap-1 text-sm text-muted-foreground">
          {breadcrumbs.map((crumb, index) => (
            <div key={crumb.path} className="flex items-center gap-1">
              {index > 0 && <ChevronRight className="h-3 w-3" />}
              {index === breadcrumbs.length - 1 ? (
                <span className="text-foreground font-medium">{crumb.name}</span>
              ) : (
                <Link
                  href={crumb.path}
                  className="hover:text-foreground transition-colors"
                >
                  {crumb.name}
                </Link>
              )}
            </div>
          ))}
        </nav>

        <div className="flex items-center gap-2 sm:gap-2">
          <Button
            variant="secondary"
            onClick={handleCreateFolderButtonClick}
            className="flex-1 sm:flex-none"
          >
            <FolderPlus className="mr-2 h-4 w-4" />
            Create Folder
          </Button>
          <Button
            onClick={handleUploadButtonClick}
            disabled={uploading}
            className="flex-1 sm:flex-none"
          >
            <Upload className="mr-2 h-4 w-4" />
            {uploading ? "Uploading..." : "Upload Files"}
          </Button>
        </div>
      </div>

      {/* Bulk Actions */}
      {selectedFiles.size > 0 && (
        <div className="bg-blue-50 border border-blue-200 rounded-lg p-4 flex items-center justify-between">
          <div className="flex items-center gap-4">
            <span className="text-sm font-medium text-blue-900">
              {selectedFiles.size} item{selectedFiles.size !== 1 ? "s" : ""} selected
            </span>
            <Button variant="outline" size="sm" onClick={deselectAll}>
              Deselect All
            </Button>
          </div>
          <div className="flex items-center gap-2">
            <Button
              variant="outline"
              size="sm"
              onClick={openMoveDialog}
            >
              <Move className="mr-2 h-4 w-4" />
              Move Selected
            </Button>
            <Button
              variant="outline"
              size="sm"
              onClick={() => handleDelete(Array.from(selectedFiles))}
              className="text-red-600 hover:text-red-700"
            >
              <Trash2 className="mr-2 h-4 w-4" />
              Delete Selected
            </Button>
          </div>
        </div>
      )}

      {/* File Table */}
      <div className="border rounded-lg">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead className="w-[40px]"></TableHead>
              <TableHead>Name</TableHead>
              <TableHead>Size</TableHead>
              <TableHead>Modified</TableHead>
              <TableHead className="w-[50px]">Actions</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {files.length === 0 ? (
              <TableRow>
                <TableCell colSpan={5} className="text-center py-8 text-muted-foreground">
                  This directory is empty
                </TableCell>
              </TableRow>
            ) : (
              files.map((file) => {
                const isSelected = selectedFiles.has(file.path)
                const fileName = file.path.split('/').pop() || file.path

                return (
                  <TableRow
                    key={file.path}
                    className={`hover:bg-muted/50 ${isSelected ? "bg-muted/30" : ""}`}
                  >
                    <TableCell className="w-[40px]" onClick={(e) => e.stopPropagation()}>
                      <Checkbox
                        checked={isSelected}
                        onCheckedChange={() => toggleFileSelection(file.path)}
                      />
                    </TableCell>
                    <TableCell className="font-medium">
                      <div className="flex items-center gap-2 min-w-0">
                        {file.type === "dir" ? (
                          <>
                            <Folder className="h-4 w-4 text-blue-500 flex-shrink-0" />
                            <div className="min-w-0 max-w-[60vw]">
                              <Link
                                href={`/drive${file.path}`}
                                className="text-blue-600 hover:text-blue-800 hover:underline cursor-pointer block truncate"
                                title={fileName}
                              >
                                {fileName}
                              </Link>
                            </div>
                          </>
                        ) : (
                          <>
                            <File className="h-4 w-4 text-gray-500 flex-shrink-0" />
                            <div className="min-w-0 max-w-[60vw]">
                              {file.blob ? (
                                <a
                                  href={`/download${file.path}`}
                                  className="text-blue-600 hover:text-blue-800 hover:underline cursor-pointer block truncate"
                                  target="_blank"
                                  rel="noopener noreferrer"
                                  title={fileName}
                                >
                                  {fileName}
                                </a>
                              ) : (
                                <span className="block truncate" title={fileName}>{fileName}</span>
                              )}
                            </div>
                          </>
                        )}
                      </div>
                    </TableCell>
                    <TableCell>{formatFileSize(file.size || 0)}</TableCell>
                    <TableCell>{formatDate(file.lastmod)}</TableCell>
                    <TableCell onClick={(e) => e.stopPropagation()}>
                      <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                          <Button variant="ghost" size="sm" className="h-8 w-8 p-0">
                            <MoreHorizontal className="h-4 w-4" />
                          </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                          <DropdownMenuItem onClick={() => openRenameDialog(file)}>
                            <Edit className="mr-2 h-4 w-4" />
                            Rename
                          </DropdownMenuItem>
                          <DropdownMenuItem onClick={() => copyPermalink(file)}>
                            <LinkIcon className="mr-2 h-4 w-4" />
                            Copy Permalink
                          </DropdownMenuItem>
                          <DropdownMenuItem onClick={() => openInfoDialog(file)}>
                            <Info className="mr-2 h-4 w-4" />
                            Info
                          </DropdownMenuItem>
                          <DropdownMenuSeparator />
                          <DropdownMenuItem
                            onClick={() => handleDelete([file.path])}
                            className="text-red-600"
                          >
                            <Trash2 className="mr-2 h-4 w-4" />
                            Delete
                          </DropdownMenuItem>
                        </DropdownMenuContent>
                      </DropdownMenu>
                    </TableCell>
                  </TableRow>
                )
              })
            )}
          </TableBody>
        </Table>
      </div>

      {/* Rename Dialog */}
      <Dialog open={renameDialogOpen} onOpenChange={setRenameDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Rename {currentItem?.type === "dir" ? "Folder" : "File"}</DialogTitle>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <Label htmlFor="newName">New Name</Label>
              <Input
                id="newName"
                value={newName}
                onChange={(e) => setNewName(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter") {
                    handleRename()
                  }
                }}
                placeholder="Enter new name"
              />
            </div>
            <div className="flex justify-end gap-2">
              <Button variant="outline" onClick={() => setRenameDialogOpen(false)}>
                Cancel
              </Button>
              <Button onClick={handleRename} disabled={!newName.trim()}>
                Rename
              </Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>

      {/* Info Dialog */}
      <Dialog open={infoDialogOpen} onOpenChange={setInfoDialogOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              {currentItem?.type === "dir" ? (
                <Folder className="h-5 w-5 text-blue-500" />
              ) : (
                <File className="h-5 w-5 text-gray-500" />
              )}
              {currentItem?.type === "dir" ? "Folder" : "File"} Information
            </DialogTitle>
          </DialogHeader>
          {currentItem && (
            <div className="space-y-4">
              <div className="space-y-3">
                <div>
                  <Label className="text-sm font-medium text-muted-foreground">Name</Label>
                  <p className="text-sm break-words">{currentItem.path.split('/').pop()}</p>
                </div>
                <div>
                  <Label className="text-sm font-medium text-muted-foreground">Size</Label>
                  <p className="text-sm">{formatFileSize(currentItem.size || 0)}</p>
                </div>
                <div>
                  <Label className="text-sm font-medium text-muted-foreground">Modified</Label>
                  <p className="text-sm">{formatDateTime(currentItem.lastmod)}</p>
                </div>
                <div>
                  <Label className="text-sm font-medium text-muted-foreground">Modified By</Label>
                  <p className="text-sm">{currentItem.author}</p>
                </div>
                <div>
                  <Label className="text-sm font-medium text-muted-foreground">Type</Label>
                  <p className="text-sm capitalize">{currentItem.type}</p>
                </div>
                <div>
                  <Label className="text-sm font-medium text-muted-foreground">Path</Label>
                  <p className="font-mono text-xs">{currentItem.path}</p>
                </div>
              </div>
              <div className="flex justify-end">
                <Button variant="outline" onClick={() => setInfoDialogOpen(false)}>
                  Close
                </Button>
              </div>
            </div>
          )}
        </DialogContent>
      </Dialog>

      {/* Move Dialog */}
      <DriveMoveDialog
        open={moveDialogOpen}
        onOpenChange={setMoveDialogOpen}
        selectedCount={selectedFiles.size}
        onMove={handleMove}
      />

      {/* Create Folder Dialog */}
      <Dialog open={createFolderDialogOpen} onOpenChange={setCreateFolderDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Create New Folder</DialogTitle>
          </DialogHeader>
          <div className="space-y-4 pt-2">
            <div className="space-y-2">
              <Label htmlFor="folderName">Folder Name</Label>
              <Input
                id="folderName"
                value={newFolderName}
                onChange={(e) => setNewFolderName(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter") {
                    handleCreateFolder()
                  }
                }}
                placeholder="Enter folder name"
              />
            </div>
            <div className="flex justify-end gap-2">
              <Button variant="outline" onClick={() => setCreateFolderDialogOpen(false)}>
                Cancel
              </Button>
              <Button onClick={handleCreateFolder} disabled={!newFolderName.trim()}>
                Create Folder
              </Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>

      <input
        ref={fileInputRef}
        type="file"
        multiple
        className="hidden"
        onChange={handleFileUpload}
      />
    </div>
  )
}
