/**
 * Media Upload Modal
 * Multimodal file upload with preview support for documents, images, videos, and audio
 */

"use client";

import { useState, useCallback, useEffect, useRef } from "react";
import type { Lang } from "@/lib/config";
import { getCSRFTokenAsync } from "@/lib/csrf-client";
import {
  Upload,
  CheckCircle,
  AlertCircle,
  FileText,
  Image as ImageIcon,
  Video,
  Music,
} from "lucide-react";
import {
  DOCUMENT_CATEGORIES,
  ALLOWED_MEDIA_TYPES,
  MAX_MEDIA_SIZE,
  MEDIA_FILE_TYPE_LABELS,
  MEDIA_TYPE_LABELS,
  getMediaType,
} from "@/lib/types/knowledge-base.types";
import type { KBMediaType } from "@/lib/types/knowledge-base.types";
import { BaseModal, ModalFooter, ModalButton } from "@/components/ui/BaseModal";

interface MediaUploadModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSuccess: () => void;
  lang: Lang;
}

/** Badge colors per media type */
const MEDIA_TYPE_BADGE_COLORS: Record<KBMediaType, string> = {
  document: "bg-blue-100 text-blue-700",
  image: "bg-purple-100 text-purple-700",
  video: "bg-amber-100 text-amber-700",
  audio: "bg-teal-100 text-teal-700",
};

/** Icon component per media type */
function MediaTypeIcon({
  mediaType,
  className,
}: {
  mediaType: KBMediaType;
  className?: string;
}) {
  switch (mediaType) {
    case "image":
      return <ImageIcon className={className} />;
    case "video":
      return <Video className={className} />;
    case "audio":
      return <Music className={className} />;
    default:
      return <FileText className={className} />;
  }
}

export default function MediaUploadModal({
  isOpen,
  onClose,
  onSuccess,
  lang,
}: MediaUploadModalProps) {
  const isAr = lang === "ar";

  const [file, setFile] = useState<File | null>(null);
  const [title, setTitle] = useState("");
  const [description, setDescription] = useState("");
  const [category, setCategory] = useState("general");
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [dragActive, setDragActive] = useState(false);
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);

  const previewUrlRef = useRef<string | null>(null);

  // Clean up object URL on unmount or when file changes
  useEffect(() => {
    return () => {
      if (previewUrlRef.current) {
        URL.revokeObjectURL(previewUrlRef.current);
        previewUrlRef.current = null;
      }
    };
  }, []);

  const createPreviewUrl = useCallback((f: File): string | null => {
    const type = getMediaType(f.type);
    if (type === "image" || type === "video" || type === "audio") {
      // Revoke previous URL
      if (previewUrlRef.current) {
        URL.revokeObjectURL(previewUrlRef.current);
      }
      const url = URL.createObjectURL(f);
      previewUrlRef.current = url;
      return url;
    }
    return null;
  }, []);

  // Reset form
  const resetForm = useCallback(() => {
    if (previewUrlRef.current) {
      URL.revokeObjectURL(previewUrlRef.current);
      previewUrlRef.current = null;
    }
    setFile(null);
    setPreviewUrl(null);
    setTitle("");
    setDescription("");
    setCategory("general");
    setError(null);
  }, []);

  // Handle file drop/select
  const handleFile = useCallback(
    (selectedFile: File) => {
      setError(null);

      // Validate file type
      if (
        !ALLOWED_MEDIA_TYPES.includes(
          selectedFile.type as (typeof ALLOWED_MEDIA_TYPES)[number],
        )
      ) {
        setError(
          isAr
            ? "نوع الملف غير مدعوم. يرجى رفع مستند أو صورة أو فيديو أو ملف صوتي"
            : "Unsupported file type. Please upload a document, image, video, or audio file",
        );
        return;
      }

      // Validate file size
      if (selectedFile.size > MAX_MEDIA_SIZE) {
        setError(
          isAr
            ? "حجم الملف يتجاوز الحد الأقصى 50 ميغابايت"
            : "File size exceeds maximum of 50MB",
        );
        return;
      }

      setFile(selectedFile);
      setPreviewUrl(createPreviewUrl(selectedFile));

      // Auto-fill title from filename if empty
      if (!title) {
        const nameWithoutExt = selectedFile.name.replace(/\.[^/.]+$/, "");
        setTitle(nameWithoutExt);
      }
    },
    [isAr, title, createPreviewUrl],
  );

  // Handle drag events
  const handleDrag = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    if (e.type === "dragenter" || e.type === "dragover") {
      setDragActive(true);
    } else if (e.type === "dragleave") {
      setDragActive(false);
    }
  }, []);

  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      e.stopPropagation();
      setDragActive(false);

      if (e.dataTransfer.files && e.dataTransfer.files[0]) {
        handleFile(e.dataTransfer.files[0]);
      }
    },
    [handleFile],
  );

  // Handle file input change
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files[0]) {
      handleFile(e.target.files[0]);
    }
  };

  // Format file size for display
  const formatFileSize = (bytes: number): string => {
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  };

  // Handle upload
  const handleUpload = async () => {
    if (!file) return;

    setUploading(true);
    setError(null);

    try {
      // Get CSRF token (use getCSRFTokenAsync for FormData uploads - can't use fetchWithCSRF
      // because FormData requires browser to set Content-Type with boundary automatically)
      const csrfToken = await getCSRFTokenAsync();
      if (!csrfToken) {
        throw new Error(
          isAr
            ? "خطأ في الجلسة. يرجى تحديث الصفحة."
            : "Session error. Please refresh the page.",
        );
      }

      const formData = new FormData();
      formData.append("file", file);
      if (title) formData.append("title", title);
      if (description) formData.append("description", description);
      formData.append("category", category);

      const response = await fetch("/api/dashboard/knowledge-base/documents", {
        method: "POST",
        headers: {
          "x-csrf-token": csrfToken,
        },
        body: formData,
        credentials: "include",
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.error || "Upload failed");
      }

      resetForm();
      onSuccess();
    } catch (err: unknown) {
      const message =
        err instanceof Error
          ? err.message
          : isAr
            ? "فشل رفع الملف"
            : "Failed to upload file";
      setError(message);
    } finally {
      setUploading(false);
    }
  };

  const handleClose = () => {
    if (!uploading) {
      resetForm();
      onClose();
    }
  };

  // Determine current media type
  const currentMediaType: KBMediaType | null = file
    ? getMediaType(file.type)
    : null;

  // Render file preview based on media type
  const renderFilePreview = () => {
    if (!file || !currentMediaType) return null;

    switch (currentMediaType) {
      case "image":
        return previewUrl ? (
          <img
            src={previewUrl}
            alt={file.name}
            className="max-h-[200px] w-auto rounded-lg object-contain"
          />
        ) : null;

      case "video":
        return previewUrl ? (
          <video
            src={previewUrl}
            controls
            className="max-h-[200px] w-auto rounded-lg"
          >
            <track kind="captions" />
          </video>
        ) : null;

      case "audio":
        return previewUrl ? (
          <audio src={previewUrl} controls className="w-full max-w-xs">
            <track kind="captions" />
          </audio>
        ) : null;

      default:
        return (
          <div className="flex h-12 w-12 items-center justify-center rounded-full bg-emerald-100 text-emerald-600">
            <CheckCircle className="h-6 w-6" />
          </div>
        );
    }
  };

  const footer = (
    <ModalFooter align="end">
      <ModalButton onClick={handleClose} disabled={uploading}>
        {isAr ? "إلغاء" : "Cancel"}
      </ModalButton>
      <ModalButton
        variant="primary"
        onClick={handleUpload}
        disabled={!file || uploading}
        loading={uploading}
        icon={!uploading ? <Upload className="h-4 w-4" /> : undefined}
      >
        {uploading
          ? isAr
            ? "جاري الرفع..."
            : "Uploading..."
          : isAr
            ? "رفع"
            : "Upload"}
      </ModalButton>
    </ModalFooter>
  );

  return (
    <BaseModal
      isOpen={isOpen}
      onClose={handleClose}
      title={isAr ? "رفع ملف" : "Upload Media"}
      size="md"
      dir={isAr ? "rtl" : "ltr"}
      footer={footer}
      loading={uploading}
    >
      <div className="space-y-4">
        {/* Drop zone */}
        <div
          onDragEnter={handleDrag}
          onDragLeave={handleDrag}
          onDragOver={handleDrag}
          onDrop={handleDrop}
          className={`relative rounded-xl border-2 border-dashed p-8 text-center transition-all ${
            dragActive
              ? "border-brand-green bg-brand-green/5"
              : file
                ? "border-emerald-300 bg-emerald-50"
                : "border-slate-200 hover:border-slate-300"
          }`}
        >
          <input
            type="file"
            accept={ALLOWED_MEDIA_TYPES.join(",")}
            onChange={handleInputChange}
            className="absolute inset-0 h-full w-full cursor-pointer opacity-0"
            disabled={uploading}
          />

          {file && currentMediaType ? (
            <div className="flex flex-col items-center gap-3">
              {/* Media preview */}
              {renderFilePreview()}

              {/* File info */}
              <p className="font-medium text-slate-900">{file.name}</p>

              <div className="flex items-center gap-2">
                {/* Media type badge */}
                <span
                  className={`inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-medium ${MEDIA_TYPE_BADGE_COLORS[currentMediaType]}`}
                >
                  <MediaTypeIcon
                    mediaType={currentMediaType}
                    className="h-3 w-3"
                  />
                  {isAr
                    ? MEDIA_TYPE_LABELS[currentMediaType].ar
                    : MEDIA_TYPE_LABELS[currentMediaType].en}
                </span>

                <span className="text-sm text-slate-500">
                  {MEDIA_FILE_TYPE_LABELS[file.type] || file.type} -{" "}
                  {formatFileSize(file.size)}
                </span>
              </div>

              <button
                type="button"
                onClick={(e) => {
                  e.stopPropagation();
                  if (previewUrlRef.current) {
                    URL.revokeObjectURL(previewUrlRef.current);
                    previewUrlRef.current = null;
                  }
                  setFile(null);
                  setPreviewUrl(null);
                }}
                className="mt-1 text-sm text-red-600 hover:text-red-700"
              >
                {isAr ? "إزالة" : "Remove"}
              </button>
            </div>
          ) : (
            <div className="flex flex-col items-center">
              <div className="flex h-12 w-12 items-center justify-center rounded-full bg-slate-100 text-slate-400 mb-3">
                <Upload className="h-6 w-6" />
              </div>
              <p className="font-medium text-slate-700">
                {isAr ? "اسحب وأفلت الملف هنا" : "Drag and drop file here"}
              </p>
              <p className="text-sm text-slate-500 mt-1">
                {isAr ? "أو انقر لاختيار ملف" : "or click to select file"}
              </p>
              <p className="text-xs text-slate-400 mt-2">
                {isAr
                  ? "مستندات، صور، فيديو، صوت (الحد الأقصى 50 ميغابايت)"
                  : "Documents, Images, Video, Audio (Max 50MB)"}
              </p>
            </div>
          )}
        </div>

        {/* Title */}
        <div>
          <label className="block text-sm font-medium text-slate-700 mb-1">
            {isAr ? "العنوان (اختياري)" : "Title (optional)"}
          </label>
          <input
            type="text"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            placeholder={isAr ? "اسم الملف" : "File name"}
            className="w-full rounded-lg border border-slate-200 px-3 py-2 text-sm placeholder-slate-400 focus:border-brand-green focus:ring-2 focus:ring-brand-green/20 focus:outline-none"
            disabled={uploading}
          />
        </div>

        {/* Description */}
        <div>
          <label className="block text-sm font-medium text-slate-700 mb-1">
            {isAr ? "الوصف (اختياري)" : "Description (optional)"}
          </label>
          <textarea
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            placeholder={
              isAr ? "وصف موجز للملف" : "Brief description of the file"
            }
            rows={2}
            className="w-full rounded-lg border border-slate-200 px-3 py-2 text-sm placeholder-slate-400 focus:border-brand-green focus:ring-2 focus:ring-brand-green/20 focus:outline-none resize-none"
            disabled={uploading}
          />
        </div>

        {/* Category */}
        <div>
          <label className="block text-sm font-medium text-slate-700 mb-1">
            {isAr ? "الفئة" : "Category"}
          </label>
          <select
            value={category}
            onChange={(e) => setCategory(e.target.value)}
            className="w-full rounded-lg border border-slate-200 px-3 py-2 text-sm focus:border-brand-green focus:ring-2 focus:ring-brand-green/20 focus:outline-none"
            disabled={uploading}
          >
            {DOCUMENT_CATEGORIES.map((cat) => (
              <option key={cat.value} value={cat.value}>
                {isAr ? cat.labelAr : cat.labelEn}
              </option>
            ))}
          </select>
        </div>

        {/* Error */}
        {error && (
          <div className="flex items-center gap-2 rounded-lg bg-red-50 px-4 py-3 text-sm text-red-600">
            <AlertCircle className="h-4 w-4 flex-shrink-0" />
            <span>{error}</span>
          </div>
        )}
      </div>
    </BaseModal>
  );
}
