'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import Link from 'next/link';
import type { MediaAsset, AmsoilImage, MediaContext, MediaUsage } from '@/types/media';
import {
  isPdfMimeType,
  isImageMimeType,
  ALLOWED_IMAGE_TYPES,
  ALLOWED_PDF_TYPES,
  ACCEPTED_IMAGE_TYPES,
  ACCEPTED_PDF_TYPES,
  IMAGE_TYPES_LABEL,
  PDF_TYPES_LABEL,
  MAX_IMAGE_SIZE,
  MAX_PDF_SIZE,
} from '@/lib/media-utils';
import { uploadFile } from '@/lib/upload-file';
import styles from './media.module.css';

interface MediaLibraryData {
  myImages: MediaAsset[];
  amsoilImages: AmsoilImage[];
  imageUsage: MediaUsage;
  documentUsage: MediaUsage;
}

export default function MediaPage() {
  const [data, setData] = useState<MediaLibraryData | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [activeTab, setActiveTab] = useState<'my-images' | 'my-documents' | 'amsoil'>('my-images');
  const [categoryFilter, setCategoryFilter] = useState<string>('all');
  const [uploading, setUploading] = useState(false);
  const [isDragging, setIsDragging] = useState(false);
  const [copiedId, setCopiedId] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  const fetchMedia = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const response = await fetch('/api/media');
      const result = await response.json();
      if (!response.ok) {
        setError(result.error || 'Failed to load media library');
        return;
      }
      setData(result);
    } catch {
      setError('Failed to load media library');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchMedia();
  }, [fetchMedia]);

  const handleFileSelect = async (files: FileList | null) => {
    if (!files || files.length === 0 || !data) return;

    const file = files[0];
    const allowedTypes = activeTab === 'my-documents'
      ? (ALLOWED_PDF_TYPES as readonly string[])
      : (ALLOWED_IMAGE_TYPES as readonly string[]);
    const typeLabel = activeTab === 'my-documents' ? PDF_TYPES_LABEL : IMAGE_TYPES_LABEL;
    if (!allowedTypes.includes(file.type)) {
      setError(`Invalid file type. Only ${typeLabel} files are allowed.`);
      return;
    }

    // Client-side size check — prevents oversized uploads from hitting the server
    const maxSize = activeTab === 'my-documents' ? MAX_PDF_SIZE : MAX_IMAGE_SIZE;
    const maxLabel = activeTab === 'my-documents' ? '25MB' : '10MB';
    if (file.size > maxSize) {
      setError(`File too large. Maximum size is ${maxLabel}.`);
      return;
    }

    setUploading(true);
    setError(null);

    try {
      const response = await uploadFile({
        file,
        context: 'general' as MediaContext,
      });

      if (!response.ok) {
        const result = await response.json();
        throw new Error(result.error || 'Failed to upload file');
      }

      const result = await response.json();
      setData((prev) =>
        prev
          ? {
              ...prev,
              myImages: [result.asset, ...prev.myImages],
              ...(result.imageUsage && { imageUsage: result.imageUsage }),
              ...(result.documentUsage && { documentUsage: result.documentUsage }),
            }
          : null
      );
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to upload image');
    } finally {
      setUploading(false);
      if (fileInputRef.current) {
        fileInputRef.current.value = '';
      }
    }
  };

  const handleDelete = async (id: string) => {
    if (!confirm('Are you sure you want to delete this file?')) return;

    try {
      const response = await fetch(`/api/media/${id}`, {
        method: 'DELETE',
      });

      if (!response.ok) {
        const result = await response.json();
        throw new Error(result.error || 'Failed to delete image');
      }

      setData((prev) => {
        if (!prev) return null;
        const deleted = prev.myImages.find((img) => img.id === id);
        const isDoc = deleted ? isPdfMimeType(deleted.mimeType) : false;
        return {
          ...prev,
          myImages: prev.myImages.filter((img) => img.id !== id),
          imageUsage: isDoc ? prev.imageUsage : { ...prev.imageUsage, current: prev.imageUsage.current - 1 },
          documentUsage: isDoc ? { ...prev.documentUsage, current: prev.documentUsage.current - 1 } : prev.documentUsage,
        };
      });
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to delete image');
    }
  };

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

  const handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
    handleFileSelect(e.dataTransfer.files);
  };

  const handleCopyUrl = async (url: string, id: string) => {
    const fullUrl = `${window.location.origin}${url}`;
    try {
      await navigator.clipboard.writeText(fullUrl);
      setCopiedId(id);
      setTimeout(() => setCopiedId(null), 2000);
    } catch {
      setError('Could not copy to clipboard. Please copy the URL manually.');
    }
  };

  // Get unique categories from AMSOIL images
  const categories = data
    ? ['all', ...new Set(data.amsoilImages.map((img) => img.category))]
    : ['all'];

  // Filter AMSOIL images by category
  const filteredAmsoilImages = data
    ? categoryFilter === 'all'
      ? data.amsoilImages
      : data.amsoilImages.filter((img) => img.category === categoryFilter)
    : [];

  // Usage calculation — per active tab
  const activeUsage = data
    ? activeTab === 'my-documents' ? data.documentUsage : data.imageUsage
    : { current: 0, limit: 0 };
  const usagePercentage = activeUsage.limit > 0 ? (activeUsage.current / activeUsage.limit) * 100 : 0;
  const usageStatus = usagePercentage >= 100 ? 'full' : usagePercentage >= 80 ? 'warning' : '';

  // Filter assets by type
  const myImages = data?.myImages.filter((a) => isImageMimeType(a.mimeType)) ?? [];
  const myDocuments = data?.myImages.filter((a) => isPdfMimeType(a.mimeType)) ?? [];

  return (
    <div className={styles.container}>
      <div className={styles.header}>
        <Link href="/dashboard" className={styles.backLink}>
          &larr; Back to Dashboard
        </Link>
        <div className={styles.headerRow}>
          <div>
            <h1 className={styles.title}>Media Library</h1>
            <p className={styles.subtitle}>Manage and reuse files across your dealer site</p>
          </div>
        </div>
      </div>

      {loading ? (
        <div className={styles.loading}>
          <div className={styles.spinner} />
          <span>Loading media library...</span>
        </div>
      ) : error ? (
        <div className={styles.error}>
          <p>{error}</p>
          <button className={styles.retryButton} onClick={fetchMedia}>
            Try Again
          </button>
        </div>
      ) : (
        <>
          {/* Tabs */}
          <div className={styles.tabNav}>
            <button
              className={`${styles.tabButton} ${activeTab === 'my-images' ? styles.active : ''}`}
              onClick={() => setActiveTab('my-images')}
            >
              My Images
            </button>
            <button
              className={`${styles.tabButton} ${activeTab === 'my-documents' ? styles.active : ''}`}
              onClick={() => setActiveTab('my-documents')}
            >
              My Documents
            </button>
            <button
              className={`${styles.tabButton} ${activeTab === 'amsoil' ? styles.active : ''}`}
              onClick={() => setActiveTab('amsoil')}
            >
              AMSOIL Images
            </button>
          </div>

          {activeTab === 'my-images' || activeTab === 'my-documents' ? (
            <>
              {/* Usage bar */}
              {data && (
                <div className={styles.usageBar}>
                  <span className={styles.usageLabel}>Storage</span>
                  <div className={styles.usageProgress}>
                    <div
                      className={`${styles.usageProgressFill} ${usageStatus ? styles[usageStatus] : ''}`}
                      style={{ width: `${Math.min(usagePercentage, 100)}%` }}
                    />
                  </div>
                  <span className={styles.usageCount}>
                    {activeUsage.current} / {activeUsage.limit} {activeTab === 'my-documents' ? 'documents' : 'images'}
                  </span>
                </div>
              )}

              {/* Upload zone */}
              <div
                className={`${styles.uploadZone} ${isDragging ? styles.dragOver : ''}`}
                onDragOver={handleDragOver}
                onDragLeave={handleDragLeave}
                onDrop={handleDrop}
              >
                <svg
                  className={styles.uploadIcon}
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="1.5"
                >
                  <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>
                <p className={styles.uploadText}>
                  {activeTab === 'my-documents'
                    ? 'Drag and drop a document here, or click to browse'
                    : 'Drag and drop an image here, or click to browse'}
                </p>
                <p className={styles.uploadSubtext}>
                  {activeTab === 'my-documents' ? `${PDF_TYPES_LABEL} (max 25MB)` : `${IMAGE_TYPES_LABEL} (max 10MB)`}
                </p>
                <input
                  ref={fileInputRef}
                  type="file"
                  accept={activeTab === 'my-documents' ? ACCEPTED_PDF_TYPES : ACCEPTED_IMAGE_TYPES}
                  onChange={(e) => handleFileSelect(e.target.files)}
                  style={{ display: 'none' }}
                />
                <button
                  className={styles.uploadButton}
                  onClick={() => fileInputRef.current?.click()}
                  disabled={uploading || activeUsage.current >= activeUsage.limit}
                >
                  {uploading ? 'Uploading...' : 'Choose File'}
                </button>
              </div>

              {/* Grid for active tab */}
              {activeTab === 'my-images' ? (
                myImages.length === 0 ? (
                  <div className={styles.emptyState}>
                    <svg
                      className={styles.emptyIcon}
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="1.5"
                    >
                      <rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
                      <circle cx="8.5" cy="8.5" r="1.5" />
                      <polyline points="21 15 16 10 5 21" />
                    </svg>
                    <h2 className={styles.emptyTitle}>No images yet</h2>
                    <p className={styles.emptyText}>Upload your first image to get started</p>
                  </div>
                ) : (
                  <div className={styles.imageGrid}>
                    {myImages.map((image) => (
                      <div key={image.id} className={styles.imageCard}>
                        {/* eslint-disable-next-line @next/next/no-img-element */}
                        <img
                          src={image.url}
                          alt={image.alt || image.filename}
                          className={styles.imageCardImg}
                        />
                        <div className={styles.imageCardOverlay} />
                        <span className={styles.imageCardName}>{image.filename}</span>
                        <div className={styles.imageCardActions}>
                          <button
                            className={styles.deleteButton}
                            onClick={() => handleDelete(image.id)}
                            title="Delete image"
                          >
                            <svg
                              width="14"
                              height="14"
                              viewBox="0 0 24 24"
                              fill="none"
                              stroke="currentColor"
                              strokeWidth="2"
                            >
                              <path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
                            </svg>
                          </button>
                        </div>
                      </div>
                    ))}
                  </div>
                )
              ) : (
                myDocuments.length === 0 ? (
                  <div className={styles.emptyState}>
                    <svg
                      className={styles.emptyIcon}
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="1.5"
                    >
                      <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
                      <polyline points="14 2 14 8 20 8" />
                      <line x1="16" y1="13" x2="8" y2="13" />
                      <line x1="16" y1="17" x2="8" y2="17" />
                    </svg>
                    <h2 className={styles.emptyTitle}>No documents yet</h2>
                    <p className={styles.emptyText}>Upload your first PDF to get started</p>
                  </div>
                ) : (
                  <div className={styles.imageGrid}>
                    {myDocuments.map((doc) => (
                      <div key={doc.id} className={styles.imageCard}>
                        <div className={styles.pdfThumbnail}>
                          <svg className={styles.pdfIcon} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
                            <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
                            <polyline points="14 2 14 8 20 8" />
                            <line x1="16" y1="13" x2="8" y2="13" />
                            <line x1="16" y1="17" x2="8" y2="17" />
                          </svg>
                          <span className={styles.pdfFilename}>{doc.filename}</span>
                          <span className={styles.pdfBadge}>PDF</span>
                        </div>
                        <div className={styles.pdfActions}>
                          <a
                            className={styles.actionButton}
                            href={`/api/documents/${doc.id}`}
                            target="_blank"
                            rel="noopener noreferrer"
                            title="Open PDF"
                          >
                            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                              <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
                              <polyline points="15 3 21 3 21 9" />
                              <line x1="10" y1="14" x2="21" y2="3" />
                            </svg>
                          </a>
                          <button
                            className={styles.actionButton}
                            onClick={() => handleCopyUrl(`/api/documents/${doc.id}`, doc.id)}
                            title={copiedId === doc.id ? 'Copied!' : 'Copy URL'}
                          >
                            {copiedId === doc.id ? (
                              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                                <polyline points="20 6 9 17 4 12" />
                              </svg>
                            ) : (
                              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                                <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
                                <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
                              </svg>
                            )}
                          </button>
                        </div>
                        <div className={styles.imageCardActions}>
                          <button
                            className={styles.deleteButton}
                            onClick={() => handleDelete(doc.id)}
                            title="Delete document"
                          >
                            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                              <path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
                            </svg>
                          </button>
                        </div>
                      </div>
                    ))}
                  </div>
                )
              )}
            </>
          ) : (
            <>
              {/* Category filter */}
              {categories.length > 1 && (
                <div className={styles.categoryFilter}>
                  {categories.map((category) => (
                    <button
                      key={category}
                      className={`${styles.categoryButton} ${categoryFilter === category ? styles.active : ''}`}
                      onClick={() => setCategoryFilter(category)}
                    >
                      {category === 'all'
                        ? 'All'
                        : category.charAt(0).toUpperCase() + category.slice(1)}
                    </button>
                  ))}
                </div>
              )}

              {/* AMSOIL Images grid */}
              {filteredAmsoilImages.length === 0 ? (
                <div className={styles.emptyState}>
                  <svg
                    className={styles.emptyIcon}
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="1.5"
                  >
                    <rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
                    <circle cx="8.5" cy="8.5" r="1.5" />
                    <polyline points="21 15 16 10 5 21" />
                  </svg>
                  <h2 className={styles.emptyTitle}>No AMSOIL images available</h2>
                  <p className={styles.emptyText}>
                    Check back later for branded images from AMSOIL
                  </p>
                </div>
              ) : (
                <div className={styles.imageGrid}>
                  {filteredAmsoilImages.map((image) => (
                    <div key={image.id} className={styles.imageCard}>
                      {/* eslint-disable-next-line @next/next/no-img-element */}
                      <img src={image.url} alt={image.name} className={styles.imageCardImg} />
                      <div className={styles.imageCardOverlay} />
                      <span className={styles.imageCardName}>{image.name}</span>
                    </div>
                  ))}
                </div>
              )}
            </>
          )}
        </>
      )}
    </div>
  );
}
