"use client"

import * as React from "react"
import { useEffect, useState } from "react"

import { MediaPreview } from "@/components/markatty/media-preview"
import {
  FormControl,
  FormDescription,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { cn } from "@/lib/utils"

type MediaPreviewKind = "image" | "video"

export function MediaFileField({
  label,
  accept,
  helperText,
  currentText,
  className,
  name,
  onBlur,
  onChange,
  inputRef,
  previewUrl,
  selectedPreviewLabel,
  currentPreviewLabel,
  previewClassName,
  previewKind,
}: {
  label: string
  accept: string
  helperText?: string
  currentText?: string
  className?: string
  name?: string
  onBlur?: React.FocusEventHandler<HTMLInputElement>
  onChange: (file: File | null) => void
  inputRef?: React.Ref<HTMLInputElement>
  /** Existing remote media URL shown until a new file is selected. */
  previewUrl?: string | null
  selectedPreviewLabel?: string
  currentPreviewLabel?: string
  previewClassName?: string
  previewKind?: MediaPreviewKind
}) {
  const [selectedPreviewUrl, setSelectedPreviewUrl] = useState<string | null>(null)
  const previewEnabled =
    selectedPreviewLabel != null ||
    currentPreviewLabel != null ||
    Boolean(previewUrl?.trim())

  useEffect(() => {
    return () => {
      if (selectedPreviewUrl) URL.revokeObjectURL(selectedPreviewUrl)
    }
  }, [selectedPreviewUrl])

  const kind: MediaPreviewKind =
    previewKind ?? (accept.startsWith("video/") ? "video" : "image")
  const previewSrc = selectedPreviewUrl ?? previewUrl?.trim() ?? null
  const previewLabel = selectedPreviewUrl
    ? (selectedPreviewLabel ?? label)
    : (currentPreviewLabel ?? label)

  function handleChange(file: File | null) {
    if (previewEnabled) {
      setSelectedPreviewUrl(file instanceof File ? URL.createObjectURL(file) : null)
    }
    onChange(file)
  }

  return (
    <FormItem className={className}>
      <FormLabel>{label}</FormLabel>
      <FormControl>
        <Input
          ref={inputRef}
          type="file"
          accept={accept}
          name={name}
          onBlur={onBlur}
          onChange={(event) => handleChange(event.target.files?.[0] ?? null)}
        />
      </FormControl>
      {helperText ? <FormDescription>{helperText}</FormDescription> : null}
      {currentText ? <FormDescription>{currentText}</FormDescription> : null}
      <FormMessage />
      {previewEnabled && previewSrc ? (
        <div className="mt-3">
          {kind === "video" ? (
            <video
              src={previewSrc}
              controls
              preload="metadata"
              aria-label={previewLabel}
              className={cn(
                "aspect-video w-full max-w-xl rounded-md border bg-muted",
                previewClassName
              )}
            />
          ) : (
            <MediaPreview
              src={previewSrc}
              label={previewLabel}
              className={cn("size-20", previewClassName)}
            />
          )}
        </div>
      ) : null}
    </FormItem>
  )
}
