'use client';

import React, { useState, useRef, useCallback } from 'react';
import { upload } from '@vercel/blob/client';

interface MediaUploadFieldProps {
  value: string;
  onChange: (value: string) => void;
  accept?: 'image' | 'video' | 'both';
}

/**
 * Custom Puck field for uploading images/videos via Vercel Blob client upload.
 * Shows URL input + drag-and-drop upload zone + preview.
 * Uses client-side upload to bypass the 4.5MB serverless function limit.
 */
export function MediaUploadField({
  value,
  onChange,
  accept = 'both',
}: MediaUploadFieldProps) {
  const [uploading, setUploading] = useState(false);
  const [progress, setProgress] = useState(0);
  const [error, setError] = useState('');
  const [dragOver, setDragOver] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // Get token from URL
  const getToken = () => {
    if (typeof window === 'undefined') return '';
    const params = new URLSearchParams(window.location.search);
    return params.get('token') || '';
  };

  const acceptTypes = accept === 'image'
    ? 'image/jpeg,image/png,image/webp,image/gif,image/svg+xml,image/avif'
    : accept === 'video'
    ? 'video/mp4,video/webm,video/ogg,video/quicktime'
    : 'image/jpeg,image/png,image/webp,image/gif,image/svg+xml,image/avif,video/mp4,video/webm,video/ogg,video/quicktime';

  // Client-side size validation
  const MAX_IMAGE_SIZE = 10 * 1024 * 1024;  // 10MB
  const MAX_VIDEO_SIZE = 100 * 1024 * 1024; // 100MB

  const uploadFile = useCallback(async (file: File) => {
    setError('');

    // Type check
    const isImage = file.type.startsWith('image/');
    const isVideo = file.type.startsWith('video/');

    if (accept === 'image' && !isImage) {
      setError('Please select an image file.');
      return;
    }
    if (accept === 'video' && !isVideo) {
      setError('Please select a video file.');
      return;
    }
    if (!isImage && !isVideo) {
      setError(`Unsupported file type: ${file.type}`);
      return;
    }

    // Size check
    const maxSize = isImage ? MAX_IMAGE_SIZE : MAX_VIDEO_SIZE;
    if (file.size > maxSize) {
      setError(`File too large. Max ${isImage ? '10' : '100'}MB.`);
      return;
    }

    setUploading(true);
    setProgress(0);

    try {
      const token = getToken();

      // Generate a clean path
      const ext = file.name.split('.').pop() || 'bin';
      const timestamp = new Date().toISOString().replace(/[:.]/g, '').slice(0, 15);
      const cleanName = file.name
        .replace(/\.[^.]+$/, '')
        .replace(/[^a-zA-Z0-9_-]/g, '_')
        .slice(0, 50);
      const pathname = `websites/editor/${isImage ? 'images' : 'videos'}/${cleanName}_${timestamp}.${ext}`;

      // Client-side upload — bypasses 4.5MB serverless limit
      const blob = await upload(pathname, file, {
        access: 'public',
        handleUploadUrl: '/api/editor/upload',
        clientPayload: JSON.stringify({ token }),
      });

      onChange(blob.url);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Upload failed');
    } finally {
      setUploading(false);
      setProgress(0);
    }
  }, [onChange, accept]);

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) uploadFile(file);
    if (fileInputRef.current) fileInputRef.current.value = '';
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setDragOver(false);
    const file = e.dataTransfer.files?.[0];
    if (file) uploadFile(file);
  };

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
    setDragOver(true);
  };

  const handleDragLeave = () => setDragOver(false);

  const isImage = value && /\.(jpg|jpeg|png|webp|gif|svg|avif)(\?|$)/i.test(value);
  const isVideo = value && /\.(mp4|webm|ogg|mov)(\?|$)/i.test(value);

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
      {/* URL Input */}
      <div style={{ display: 'flex', gap: '6px' }}>
        <input
          type="text"
          value={value || ''}
          onChange={(e) => onChange(e.target.value)}
          placeholder={accept === 'image' ? 'Paste URL or upload...' : accept === 'video' ? 'Paste URL or upload...' : 'Paste URL or upload...'}
          style={{
            flex: 1,
            padding: '6px 10px',
            fontSize: '13px',
            border: '1px solid #d1d5db',
            borderRadius: '6px',
            background: '#fff',
            color: '#1f2937',
            outline: 'none',
          }}
        />
        {value && (
          <button
            onClick={() => onChange('')}
            title="Clear"
            style={{
              padding: '4px 8px',
              fontSize: '12px',
              color: '#ef4444',
              background: '#fef2f2',
              border: '1px solid #fecaca',
              borderRadius: '6px',
              cursor: 'pointer',
            }}
          >
            ✕
          </button>
        )}
      </div>

      {/* Drop Zone / Upload Button */}
      <div
        onDrop={handleDrop}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onClick={() => !uploading && fileInputRef.current?.click()}
        style={{
          border: `2px dashed ${dragOver ? '#2563eb' : '#d1d5db'}`,
          borderRadius: '8px',
          padding: '16px',
          textAlign: 'center',
          cursor: uploading ? 'wait' : 'pointer',
          background: dragOver ? '#eff6ff' : uploading ? '#f9fafb' : '#fff',
          transition: 'all 0.15s',
          position: 'relative',
          overflow: 'hidden',
        }}
      >
        <input
          ref={fileInputRef}
          type="file"
          accept={acceptTypes}
          onChange={handleFileSelect}
          style={{ display: 'none' }}
        />

        {uploading ? (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '6px' }}>
            <svg style={{ animation: 'spin 1s linear infinite' }} width="20" height="20" viewBox="0 0 24 24" fill="none">
              <circle cx="12" cy="12" r="10" stroke="#94a3b8" strokeWidth="3" opacity="0.3" />
              <path d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" fill="#2563eb" />
            </svg>
            <span style={{ fontSize: '12px', color: '#64748b' }}>Uploading...</span>
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '4px' }}>
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#94a3b8" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
              <polyline points="17 8 12 3 7 8" />
              <line x1="12" y1="3" x2="12" y2="15" />
            </svg>
            <span style={{ fontSize: '12px', color: '#64748b' }}>
              Drop file here or <span style={{ color: '#2563eb', fontWeight: 500 }}>browse</span>
            </span>
            <span style={{ fontSize: '10px', color: '#94a3b8' }}>
              {accept === 'image' ? 'JPG, PNG, WebP, GIF, SVG (max 10MB)' :
               accept === 'video' ? 'MP4, WebM, OGG, MOV (max 100MB)' :
               'Images (10MB) / Videos (100MB)'}
            </span>
          </div>
        )}
      </div>

      {/* Error */}
      {error && (
        <div style={{
          padding: '6px 10px',
          fontSize: '12px',
          color: '#ef4444',
          background: '#fef2f2',
          borderRadius: '6px',
          border: '1px solid #fecaca',
        }}>
          {error}
        </div>
      )}

      {/* Preview */}
      {value && isImage && (
        <div style={{ borderRadius: '6px', overflow: 'hidden', border: '1px solid #e5e7eb' }}>
          <img
            src={value}
            alt="Preview"
            style={{ width: '100%', maxHeight: '160px', objectFit: 'cover', display: 'block' }}
          />
        </div>
      )}
      {value && isVideo && (
        <div style={{ borderRadius: '6px', overflow: 'hidden', border: '1px solid #e5e7eb' }}>
          <video
            src={value}
            controls
            muted
            style={{ width: '100%', maxHeight: '160px', display: 'block' }}
          />
        </div>
      )}
    </div>
  );
}
