'use client';

import { useRef, useState } from 'react';
import { Upload, X, Link as LinkIcon, Play, Film } from 'lucide-react';
import toast from 'react-hot-toast';
import api from '@/lib/api';
import { MediaItem } from '@/types';

const API_BASE = (process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5000/api').replace('/api', '');

function resolveUrl(url: string): string {
  if (!url) return '';
  if (url.startsWith('http://') || url.startsWith('https://')) return url;
  return `${API_BASE}${url}`;
}

function detectMediaType(file: File): 'image' | 'video' {
  return file.type.startsWith('video/') ? 'video' : 'image';
}

function detectUrlType(url: string): 'image' | 'video' {
  const lower = url.toLowerCase();
  if (lower.match(/\.(mp4|webm|mov|avi|mkv)(\?|$)/)) return 'video';
  return 'image';
}

interface MediaUploaderProps {
  label?: string;
  value: MediaItem | null;
  onChange: (item: MediaItem | null) => void;
  hint?: string;
  previewHeight?: string;
}

export default function MediaUploader({
  label,
  value,
  onChange,
  hint,
  previewHeight = 'h-36',
}: MediaUploaderProps) {
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [isUploading, setIsUploading] = useState(false);
  const [dragOver, setDragOver] = useState(false);
  const [showUrlInput, setShowUrlInput] = useState(false);

  const handleFiles = async (files: FileList | File[]) => {
    const file = Array.from(files)[0];
    if (!file) return;

    if (!file.type.startsWith('image/') && !file.type.startsWith('video/')) {
      toast.error('Please select an image or video file');
      return;
    }

    setIsUploading(true);
    try {
      const formData = new FormData();
      formData.append('file', file);
      const media = await api.uploadMedia(formData);
      const mediaType = detectMediaType(file);
      onChange({ url: resolveUrl(media.url), type: mediaType });
    } catch {
      toast.error('Upload failed');
    } finally {
      setIsUploading(false);
    }
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setDragOver(false);
    if (e.dataTransfer.files) handleFiles(e.dataTransfer.files);
  };

  const handleFileInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      handleFiles(e.target.files);
      e.target.value = '';
    }
  };

  const displayUrl = value ? resolveUrl(value.url) : '';
  const isVideo = value?.type === 'video';

  return (
    <div className="space-y-1.5">
      {label && (
        <label className="block text-sm font-medium text-gray-700">{label}</label>
      )}

      {displayUrl ? (
        <div className="relative group rounded-lg overflow-hidden border border-gray-200">
          {isVideo ? (
            <div className={`relative w-full ${previewHeight} bg-gray-900 flex items-center justify-center`}>
              <video
                src={displayUrl}
                className={`w-full ${previewHeight} object-cover`}
                muted
                preload="metadata"
              />
              <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
                <div className="w-10 h-10 bg-black/60 rounded-full flex items-center justify-center">
                  <Play size={18} className="text-white ml-0.5" />
                </div>
              </div>
              <span className="absolute top-2 left-2 px-1.5 py-0.5 bg-black/70 text-white text-[10px] font-semibold rounded flex items-center gap-1">
                <Film size={10} /> VIDEO
              </span>
            </div>
          ) : (
            /* eslint-disable-next-line @next/next/no-img-element */
            <img
              src={displayUrl}
              alt={label || 'Uploaded media'}
              className={`w-full ${previewHeight} object-cover`}
            />
          )}
          <div className="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-2">
            <button
              type="button"
              onClick={() => fileInputRef.current?.click()}
              className="px-3 py-1.5 bg-white text-gray-700 text-xs font-medium rounded-lg hover:bg-gray-100"
            >
              Replace
            </button>
            <button
              type="button"
              onClick={() => onChange(null)}
              className="p-1.5 bg-white text-red-600 rounded-lg hover:bg-red-50"
            >
              <X size={14} />
            </button>
          </div>
        </div>
      ) : (
        <div
          onDrop={handleDrop}
          onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
          onDragLeave={() => setDragOver(false)}
          onClick={() => fileInputRef.current?.click()}
          className={`border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-colors ${
            dragOver
              ? 'border-blue-400 bg-blue-50'
              : 'border-gray-200 hover:border-gray-300 hover:bg-gray-50'
          }`}
        >
          {isUploading ? (
            <div className="flex flex-col items-center gap-2">
              <div className="w-6 h-6 border-2 border-blue-600 border-t-transparent rounded-full animate-spin" />
              <p className="text-xs text-gray-500">Uploading...</p>
            </div>
          ) : (
            <>
              <Upload size={20} className="mx-auto text-gray-400 mb-1.5" />
              <p className="text-xs text-gray-500">
                Drop an image/video or <span className="text-blue-600">click to upload</span>
              </p>
            </>
          )}
        </div>
      )}

      <input
        ref={fileInputRef}
        type="file"
        className="hidden"
        accept="image/*,video/*"
        onChange={handleFileInput}
      />

      <div>
        <button
          type="button"
          onClick={() => setShowUrlInput(!showUrlInput)}
          className="inline-flex items-center gap-1 text-xs text-gray-400 hover:text-gray-600"
        >
          <LinkIcon size={12} />
          {showUrlInput ? 'Hide URL input' : 'Or paste URL'}
        </button>
        {showUrlInput && (
          <input
            type="url"
            value={value?.url ?? ''}
            onChange={(e) => {
              const url = e.target.value;
              if (!url) { onChange(null); return; }
              onChange({ url, type: detectUrlType(url) });
            }}
            placeholder="https://..."
            className="mt-1 w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
          />
        )}
      </div>

      {hint && <p className="text-xs text-gray-500">{hint}</p>}
    </div>
  );
}
