import { useEffect, useMemo, useState } from 'react';
import { Box, Button, Stack, Typography, Paper, TextField, MenuItem } from '@mui/material';

type MediaItem = {
  key: string;
  size: number;
  lastModified: string | null;
};

export default function MediaLibrary({ onInsert, onSetFeature, showSetFeature }: { onInsert: (url: string) => void; onSetFeature?: (url: string) => void; showSetFeature?: boolean }) {
  const [items, setItems] = useState<MediaItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const [query, setQuery] = useState('');
  const [sortBy, setSortBy] = useState<'date_desc' | 'date_asc' | 'name_asc' | 'size_desc'>('date_desc');

  const load = async () => {
    try {
      setLoading(true);
      setError('');
      const res = await fetch('/api/media/list?prefix=images/');
      if (!res.ok) throw new Error(await res.text());
      const data = await res.json();
      setItems(Array.isArray(data.items) ? data.items : []);
    } catch (e: any) {
      setError(e?.message || 'Failed to load media');
    } finally {
      setLoading(false);
    }
  };

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

  const del = async (key: string) => {
    try {
      setError('');
      const res = await fetch('/api/media/obj', {
        method: 'DELETE',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ key }),
      });
      if (!res.ok) throw new Error(await res.text());
      await load();
    } catch (e: any) {
      setError(e?.message || 'Delete failed');
    }
  };

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    let arr = items.filter(it => it.key.toLowerCase().includes(q));
    arr.sort((a, b) => {
      if (sortBy === 'date_desc') return (new Date(b.lastModified || 0).getTime()) - (new Date(a.lastModified || 0).getTime());
      if (sortBy === 'date_asc') return (new Date(a.lastModified || 0).getTime()) - (new Date(b.lastModified || 0).getTime());
      if (sortBy === 'size_desc') return (b.size - a.size);
      // name_asc
      const an = a.key.split('/').slice(-1)[0].toLowerCase();
      const bn = b.key.split('/').slice(-1)[0].toLowerCase();
      return an.localeCompare(bn);
    });
    return arr;
  }, [items, query, sortBy]);

  const fmtSize = (n: number) => {
    if (n >= 1024 * 1024) return (n / (1024 * 1024)).toFixed(1) + ' MB';
    if (n >= 1024) return (n / 1024).toFixed(1) + ' KB';
    return n + ' B';
  };

  const fmtDate = (s: string | null) => s ? new Date(s).toLocaleString() : '';

  const copyUrl = async (url: string) => {
    try {
      await navigator.clipboard.writeText(url);
    } catch {}
  };

  return (
    <Paper sx={{ p: 2 }}>
      <Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ mb: 2 }}>
        <Typography variant="h6">Media Library</Typography>
        <Stack direction="row" spacing={1}>
          <TextField
            size="small"
            placeholder="Search by name…"
            value={query}
            onChange={e => setQuery(e.target.value)}
          />
          <TextField size="small" select value={sortBy} onChange={e => setSortBy(e.target.value as any)}>
            <MenuItem value="date_desc">Newest</MenuItem>
            <MenuItem value="date_asc">Oldest</MenuItem>
            <MenuItem value="name_asc">Name</MenuItem>
            <MenuItem value="size_desc">Largest</MenuItem>
          </TextField>
          <Button size="small" onClick={load} disabled={loading}>Refresh</Button>
        </Stack>
      </Stack>
      {error && <Typography color="error" sx={{ mb: 1 }}>{error}</Typography>}
      <Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))', gap: 1.5 }}>
        {filtered.map((it) => {
          const url = `/api/media/obj?key=${encodeURIComponent(it.key)}`;
          const name = it.key.split('/').slice(-1)[0];
          return (
            <Paper key={it.key} sx={{ p: 1.25, display: 'flex', flexDirection: 'column', height: 260 }}>
              <Box sx={{ width: '100%', flex: '0 0 140px', display: 'flex', alignItems: 'center', justifyContent: 'center', mb: 1, overflow: 'hidden', background: '#fafafa', borderRadius: 1 }}>
                <a href={url} target="_blank" rel="noreferrer">
                  <img src={url} alt={name} style={{ maxWidth: '100%', maxHeight: '140px', objectFit: 'contain', display: 'block' }} />
                </a>
              </Box>
              <Typography variant="caption" noWrap sx={{ display: 'block' }} title={name}>{name}</Typography>
              <Typography variant="caption" sx={{ display: 'block', color: 'text.secondary' }}>{fmtSize(it.size)} · {fmtDate(it.lastModified)}</Typography>
              <Box sx={{ flexGrow: 1 }} />
              <Stack direction="row" spacing={1} sx={{ mt: 1, flexWrap: 'wrap' }}>
                <Button size="small" variant="outlined" sx={{ flex: '1 1 48%' }} onClick={() => onInsert(url)}>Insert</Button>
                {showSetFeature && onSetFeature && (
                  <Button size="small" variant="outlined" sx={{ flex: '1 1 48%' }} onClick={() => onSetFeature(url)}>Set Feature</Button>
                )}
                <Button size="small" variant="text" sx={{ flex: '1 1 48%' }} onClick={() => copyUrl(url)}>Copy URL</Button>
                <Button size="small" color="error" variant="text" sx={{ flex: '1 1 48%' }} onClick={() => { if (confirm('Delete this image?')) del(it.key) }}>Delete</Button>
              </Stack>
            </Paper>
          );
        })}
        {filtered.length === 0 && !loading && (
          <Typography variant="body2">No images found.</Typography>
        )}
      </Box>
    </Paper>
  );
}
