'use client'

import { useState, useRef } from 'react'
import { trpc } from '@/lib/trpc/client'
import { toast } from 'sonner'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Skeleton } from '@/components/ui/skeleton'
import { Input } from '@/components/ui/input'
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/alert-dialog'
import { FileText, Upload, Download, Trash2, MessageSquare } from 'lucide-react'
import { formatDistanceToNow } from 'date-fns'

interface Props {
  /** Project the workspace belongs to — drives file list (project-scoped). */
  projectId: string
  /**
   * One MentorAssignment id on this project — needed only to mint upload tokens
   * (the token is signed against the assignment + project pair, but the file
   * itself is project-scoped so co-mentors see it).
   */
  mentorAssignmentId: string
  /** Set true on the applicant side to label uploads as "Team upload" — purely cosmetic. */
  asApplicant?: boolean
}

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

export function WorkspaceFilesPanel({ projectId, mentorAssignmentId, asApplicant }: Props) {
  const utils = trpc.useUtils()
  const inputRef = useRef<HTMLInputElement>(null)
  const [uploading, setUploading] = useState(false)
  const [description, setDescription] = useState('')

  const { data: files, isLoading } = trpc.mentor.workspaceGetFiles.useQuery(
    { projectId },
    { enabled: !!projectId }
  )

  const presign = trpc.mentor.workspaceGetUploadUrl.useMutation()
  const recordUpload = trpc.mentor.workspaceUploadFile.useMutation({
    onSuccess: () => {
      utils.mentor.workspaceGetFiles.invalidate({ projectId })
      setDescription('')
      toast.success('File uploaded')
    },
  })
  const downloadMutation = trpc.mentor.workspaceGetFileDownloadUrl.useMutation()
  const deleteMutation = trpc.mentor.workspaceDeleteFile.useMutation({
    onSuccess: () => {
      utils.mentor.workspaceGetFiles.invalidate({ projectId })
      toast.success('File deleted')
    },
    onError: (e) => toast.error(e.message),
  })

  const handleFileSelected = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file) return
    e.target.value = ''
    setUploading(true)
    try {
      const { uploadUrl, uploadToken } = await presign.mutateAsync({
        mentorAssignmentId,
        fileName: file.name,
        mimeType: file.type || 'application/octet-stream',
        size: file.size,
      })
      const putRes = await fetch(uploadUrl, {
        method: 'PUT',
        body: file,
        headers: { 'Content-Type': file.type || 'application/octet-stream' },
      })
      if (!putRes.ok) throw new Error(`Upload failed: HTTP ${putRes.status}`)
      await recordUpload.mutateAsync({ uploadToken, description: description || undefined })
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Upload failed')
    } finally {
      setUploading(false)
    }
  }

  const handleDownload = async (mentorFileId: string) => {
    try {
      const { url } = await downloadMutation.mutateAsync({ mentorFileId })
      window.open(url, '_blank')
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Download failed')
    }
  }

  if (isLoading) {
    return (
      <Card>
        <CardHeader><CardTitle>Workspace Files</CardTitle></CardHeader>
        <CardContent className="space-y-2">
          <Skeleton className="h-12 w-full" />
          <Skeleton className="h-12 w-full" />
        </CardContent>
      </Card>
    )
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle>Workspace Files</CardTitle>
        <CardDescription>
          {asApplicant
            ? 'Files shared with your mentor in this workspace.'
            : 'Files you and the team have shared in this workspace.'}
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="flex flex-col sm:flex-row gap-2">
          <Input
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            placeholder="Optional description for the next upload"
            className="flex-1"
          />
          <Button
            disabled={uploading}
            onClick={() => inputRef.current?.click()}
            className="shrink-0"
          >
            <Upload className="mr-2 h-4 w-4" />
            {uploading ? 'Uploading…' : 'Upload file'}
          </Button>
          <input ref={inputRef} type="file" hidden onChange={handleFileSelected} />
        </div>

        {files && files.length === 0 && (
          <div className="text-center py-8 text-sm text-muted-foreground">
            <FileText className="h-10 w-10 mx-auto mb-2 opacity-40" />
            No files in this workspace yet.
          </div>
        )}

        <ul className="divide-y">
          {(files ?? []).map((f) => (
            <li key={f.id} className="flex items-center gap-3 py-3">
              <FileText className="h-5 w-5 text-muted-foreground shrink-0" />
              <div className="flex-1 min-w-0">
                <div className="font-medium truncate">{f.fileName}</div>
                <div className="text-xs text-muted-foreground">
                  {f.uploadedBy.name ?? f.uploadedBy.email} · {formatSize(f.size)} ·{' '}
                  {formatDistanceToNow(new Date(f.createdAt), { addSuffix: true })}
                  {f._count.comments > 0 && (
                    <span className="ml-2 inline-flex items-center gap-1">
                      <MessageSquare className="h-3 w-3" />
                      {f._count.comments}
                    </span>
                  )}
                </div>
                {f.description && (
                  <div className="text-xs text-muted-foreground mt-1">{f.description}</div>
                )}
              </div>
              <Button variant="ghost" size="icon" onClick={() => handleDownload(f.id)}>
                <Download className="h-4 w-4" />
              </Button>
              <AlertDialog>
                <AlertDialogTrigger asChild>
                  <Button variant="ghost" size="icon" className="text-destructive hover:text-destructive">
                    <Trash2 className="h-4 w-4" />
                  </Button>
                </AlertDialogTrigger>
                <AlertDialogContent>
                  <AlertDialogHeader>
                    <AlertDialogTitle>Delete this file?</AlertDialogTitle>
                    <AlertDialogDescription>
                      This removes the file from MinIO and the workspace. Comments on the file are deleted with it.
                    </AlertDialogDescription>
                  </AlertDialogHeader>
                  <AlertDialogFooter>
                    <AlertDialogCancel>Cancel</AlertDialogCancel>
                    <AlertDialogAction onClick={() => deleteMutation.mutate({ mentorFileId: f.id })}>
                      Delete
                    </AlertDialogAction>
                  </AlertDialogFooter>
                </AlertDialogContent>
              </AlertDialog>
            </li>
          ))}
        </ul>
      </CardContent>
    </Card>
  )
}
