/* ============================================================
   ui.jsx — переиспользуемые компоненты
   ============================================================ */

const { useState, useEffect, useRef } = React;

/* ─── Logo ─── */
function Logo({ size = 18 }) {
  return (
    <span className="logo" style={{ fontSize: size }}>
      <span className="logo-mark">✨</span>
      <span className="logo-text">AI Media Studio</span>
    </span>
  );
}

/* ─── Spinner ─── */
function Spinner({ sm }) {
  return <div className={`spinner${sm ? ' spinner-sm' : ''}`} />;
}

/* ─── Toast system ─── */
const ToastContext = React.createContext(null);

function ToastProvider({ children }) {
  const [toasts, setToasts] = useState([]);

  function addToast(msg, type = 'ok') {
    const id = Date.now() + Math.random();
    setToasts(t => [...t, { id, msg, type }]);
    setTimeout(() => setToasts(t => t.filter(x => x.id !== id)), 3200);
  }

  return (
    <ToastContext.Provider value={addToast}>
      {children}
      <div className="toast-wrap">
        {toasts.map(t => (
          <div key={t.id} className={`toast toast-${t.type}`}>
            <span className="toast-ic">
              {t.type === 'ok' ? '✓' : t.type === 'pay' ? '💎' : '⚠'}
            </span>
            {t.msg}
          </div>
        ))}
      </div>
    </ToastContext.Provider>
  );
}

function useToast() {
  return React.useContext(ToastContext);
}

/* ─── Ambient blobs ─── */
function Blobs() {
  return (
    <div className="blobs">
      <div className="blob blob-p" />
      <div className="blob blob-c" />
      <div className="blob blob-k" />
    </div>
  );
}

/* ─── Reveal on scroll ─── */
function useReveal(ref) {
  useEffect(() => {
    if (!ref.current) return;
    const els = ref.current.querySelectorAll('.reveal');
    const obs = new IntersectionObserver(
      entries => entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('in'); }),
      { threshold: 0.12 }
    );
    els.forEach(el => obs.observe(el));
    return () => obs.disconnect();
  }, []);
}

/* ─── Tab switcher ─── */
function Tabs({ items, active, onChange, centered }) {
  return (
    <div className={`tabs${centered ? '' : ' tabs-left'}`}>
      {items.map(item => (
        <button
          key={item.id}
          className={`tab${active === item.id ? ' on' : ''}`}
          onClick={() => onChange(item.id)}
        >
          {item.label}
          {item.count != null && <span className="tab-count">{item.count}</span>}
          <span className="tab-underline" />
        </button>
      ))}
    </div>
  );
}

/* ─── Segmented buttons ─── */
function Seg({ items, value, onChange }) {
  return (
    <div className="seg">
      {items.map(item => (
        <button
          key={item.value}
          className={`seg-btn${value === item.value ? ' on' : ''}`}
          onClick={() => onChange(item.value)}
        >
          {item.label}
        </button>
      ))}
    </div>
  );
}

/* ─── Toggle ─── */
function Toggle({ label, value, onChange }) {
  return (
    <button className={`toggle${value ? ' on' : ''}`} onClick={() => onChange(!value)}>
      <span className="toggle-sw" />
      {label}
    </button>
  );
}

/* ─── Placeholder art ─── */
function PlaceholderArt({ type = 'img', label, style }) {
  return (
    <div
      className={`ph ph-grad ph-${type}`}
      data-label={label || (type === 'img' ? 'Image' : type === 'vid' ? 'Video' : 'Audio')}
      style={style}
    />
  );
}

/* ─── Upload zone ─── */
function UploadZone({ label, accept, file, onFile, onClear }) {
  const [drag, setDrag] = useState(false);
  const inputRef = useRef(null);

  function handleDrop(e) {
    e.preventDefault();
    setDrag(false);
    const f = e.dataTransfer.files[0];
    if (f) onFile(f);
  }

  if (file) {
    return (
      <div className="upload has">
        <div className="upload-has">
          <span style={{ fontSize: 20 }}>📎</span>
          <span className="upload-name">{file.name}</span>
          <button className="upload-x" onClick={onClear}>✕</button>
        </div>
      </div>
    );
  }

  return (
    <div
      className={`upload${drag ? ' drag' : ''}`}
      onClick={() => inputRef.current?.click()}
      onDragOver={e => { e.preventDefault(); setDrag(true); }}
      onDragLeave={() => setDrag(false)}
      onDrop={handleDrop}
    >
      <input ref={inputRef} type="file" accept={accept} style={{ display: 'none' }}
        onChange={e => e.target.files[0] && onFile(e.target.files[0])} />
      <span className="upload-ic">📁</span>
      <span className="upload-hint">{label || 'Перетащи файл или нажми для выбора'}</span>
    </div>
  );
}

/* ─── Pill tier badge ─── */
function TierBadge({ tier }) {
  if (tier === 'free') return <span className="pill pill-free">Free</span>;
  return <span className="pill pill-pro">Pro+</span>;
}

/* ─── Audio player ─── */
function AudioPlayer({ src, compact }) {
  const [playing, setPlaying] = useState(false);
  const [progress, setProgress] = useState(0);
  const [duration, setDuration] = useState(0);
  const audioRef = useRef(null);

  useEffect(() => {
    const audio = audioRef.current;
    if (!audio) return;
    function onTime() { setProgress(audio.currentTime); }
    function onDur() { setDuration(audio.duration); }
    function onEnd() { setPlaying(false); setProgress(0); }
    audio.addEventListener('timeupdate', onTime);
    audio.addEventListener('loadedmetadata', onDur);
    audio.addEventListener('ended', onEnd);
    return () => {
      audio.removeEventListener('timeupdate', onTime);
      audio.removeEventListener('loadedmetadata', onDur);
      audio.removeEventListener('ended', onEnd);
    };
  }, [src]);

  function toggle() {
    const audio = audioRef.current;
    if (!audio) return;
    if (playing) { audio.pause(); setPlaying(false); }
    else { audio.play(); setPlaying(true); }
  }

  function fmt(s) {
    if (!s || isNaN(s)) return '0:00';
    const m = Math.floor(s / 60);
    const sec = Math.floor(s % 60);
    return `${m}:${sec.toString().padStart(2, '0')}`;
  }

  const bars = Array.from({ length: 32 }, (_, i) => {
    const pct = duration > 0 ? progress / duration : 0;
    const active = i / 32 < pct;
    return (
      <span
        key={i}
        style={{
          background: active
            ? 'linear-gradient(135deg, #22d3ee, #3b82f6)'
            : 'rgba(255,255,255,0.12)',
          height: `${20 + Math.sin(i * 0.7) * 14 + Math.cos(i * 1.3) * 8}px`,
        }}
      />
    );
  });

  return (
    <div className={`audio-player${compact ? ' compact' : ''}`}>
      <audio ref={audioRef} src={src} preload="metadata" />
      <button className="audio-play" onClick={toggle}>{playing ? '⏸' : '▶'}</button>
      <div className="audio-wave">{bars}</div>
      <span className="audio-time">{fmt(progress)} / {fmt(duration)}</span>
    </div>
  );
}

/* ─── Video player ─── */
function VideoPlayer({ src }) {
  const [playing, setPlaying] = useState(false);
  const videoRef = useRef(null);

  function toggle() {
    const v = videoRef.current;
    if (!v) return;
    if (playing) { v.pause(); setPlaying(false); }
    else { v.play(); setPlaying(true); }
  }

  return (
    <div className="video-player" style={{ aspectRatio: '16/9', cursor: 'pointer' }} onClick={toggle}>
      <video
        ref={videoRef}
        src={src}
        style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover' }}
        loop
        playsInline
      />
      {!playing && <button className="play-btn">▶</button>}
    </div>
  );
}

/* ─── Progress bar ─── */
function ProgressBar({ pct }) {
  return (
    <div className="progress">
      <div className="progress-bar" style={{ width: `${Math.min(100, pct)}%` }} />
    </div>
  );
}

/* ─── Empty state ─── */
function EmptyState({ icon, title, sub }) {
  return (
    <div className="result-empty">
      <span className="result-empty-ic">{icon}</span>
      <strong>{title}</strong>
      {sub && <span className="muted" style={{ fontSize: 14 }}>{sub}</span>}
    </div>
  );
}

/* ─── Prompt ideas ─── */
function PromptIdeas({ ideas, onPick }) {
  return (
    <div className="prompt-ideas">
      {ideas.map((idea, i) => (
        <button key={i} className="idea-chip" onClick={() => onPick(idea)}>
          {idea}
        </button>
      ))}
    </div>
  );
}
