import React from "react"
import { useState } from "react"
import { useContextMenu } from "react-contexify"
import uploadFile from "../functions/uploadFile"
import { useCopyMutation, useDeleteFileMutation, useOpenDirQuery } from "../generated/graphql"
import Breadcrum from "./Breadcrum"
import DragAndDrop from "./DragAndDrop"
import FileBrowserContextMenu, { Action, CONTEXT_MENU_DIR, CONTEXT_MENU_FILE } from "./FileBrowserContextMenu"
import FileBrowserElement from "./FileBrowserElement"
import FileOpen from "./FileOpen"
import FileUploadButton from "./FileUploadButton"

const FileBrowser: React.FC = () => {
	const [path,setPath] = useState("/")
	const [openFileId, setOpenFileId] = useState("")
	const [showFile, setShowFile] = useState(false)

	const [srcID,setSrcID] = useState("")

	const [deleteMutation] = useDeleteFileMutation()
	const [copyMutation] = useCopyMutation()

	const { show: showFileContext } = useContextMenu({
		id: CONTEXT_MENU_FILE,
	})

	const { show: showDirContext } = useContextMenu({
		id: CONTEXT_MENU_DIR,
	})

	const { data, loading } = useOpenDirQuery({
		variables:{
			path
		}
	})

	async function handleDrop(files:FileList) {
		const wait: Promise<boolean>[] = []
		for (let i = 0; i < files.length; i++) {
			const file = files[i]
			wait.push(uploadFile(file, path + file.name))
		}

		await Promise.all(wait)
	}

	function openFileContextMenu(e: React.MouseEvent, id: string) {
		e.preventDefault()
		showFileContext(e,{
			props:{
				id
			}
		})
	}

	function openDirContextMenu(e: React.MouseEvent, id: string) {
		e.preventDefault()
		showDirContext(e,{
			props:{
				id
			}
		})
	}

	function onContextSelect(action:Action, id: string) {
		switch (action) {
		case Action.FileDelete:
			deleteMutation({variables:{id}})
			break
		case Action.FileCopy:
			setSrcID(id)
			break
		case Action.FilePaste:
			copyMutation({variables:{src:srcID,dest:path}})
			break
		default:
			break
		}
	}

	return (
		<div>
			<FileBrowserContextMenu
				onSelect={onContextSelect}
				pasteActive={!!srcID}
			/>
			<DragAndDrop
				handleDrop={async (files)=>{
					await handleDrop(files)
				}}
			>
				<FileUploadButton 
					onUpload={(files)=>handleDrop(files)}
				/>
				<Breadcrum path={path} onDirClick={(newPath)=>{
					setPath(newPath)
				}}/>
				<div>
					{loading && 
						<div className="loading loading-lg"></div> // TODO: center
					}
					<table className="table table-striped table-hover">
						<thead>
							<tr>
								<th>Name</th>
								<th>Last Modified</th>
								<th>Size</th>
							</tr>
						</thead>
						<tbody>

							{ data?.directorys.map(v => (<FileBrowserElement
								key={v?.id}
								dir={v}
								onClick={(dir)=>{
									setPath(dir.id)
								}}
								onContextMenu={(e)=>{
									openDirContextMenu(e,v.id)
								}}
							/>))}
								
							{ data?.files.map(v => (<FileBrowserElement 
								key={v?.id}
								file={v}
								onClick={(file)=>{
									setOpenFileId(file.id)
									setShowFile(true)
								}}
								onContextMenu={(e)=>{
									openFileContextMenu(e,v.id)
								}}
							/>))}
						</tbody>
					</table>
				</div>
				{<FileOpen id={openFileId} show={showFile} onCloseClick={()=>{
					setShowFile(false)
				}} />}
			</DragAndDrop>
		</div>
	)
}

export default FileBrowser
