import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
import './VoiceCards.css';

const API_URL = 'https://back.hack.kinsle.ru/process-audio';

// Примеры — какой текст синтезируется вашим голосом
const EXAMPLES = [
  {
    scenario: 'Начнем с начала',
    text: 'Здравствуй! Сейчас ты увидишь, что мошейнники могут сделать, получив твой голос.',
	exaggeration: "0.6",
	cfg_weight:   "0.5",
	temperature:  "0.4",
  },
  {
    scenario: '📞 Мошенник — родственнику',
    text: 'Мам, я попал в аварию. Мне срочно нужны деньги, пожалуйста переведи на карту, я потом всё объясню.',
	exaggeration: "0.6",
	cfg_weight:   "0.65",
	temperature:  "0.35",  
  },
  {
    scenario: '🏦 Фейковый звонок из банка',
    text: 'Здравствуйте, я сотрудник службы безопасности банка. По вашей карте зафиксирована подозрительная операция. Назовите код из смс.',
  },
  {
    scenario: '💼 Давление на коллегу',
    text: 'Это директор. Переведи сто тысяч на реквизиты, которые я пришлю в чат. Никому не говори — это конфиденциально.',
  },
];

// Генерирует случайные высоты баров волны (стабильны для одного экземпляра)
function makeWaveBars(count = 40) {
  return Array.from({ length: count }, () => 20 + Math.random() * 80);
}

const fmt = (s: number) =>
  `${Math.floor(s / 60)}:${String(Math.floor(s % 60)).padStart(2, '0')}`;

/* ────────────────────────── VoiceCard ────────────────────────── */

interface VoiceCardProps {
  scenario: string;
  text: string;
  voiceBlob: Blob;

  exaggeration: string;
  temperature: string;
  cfg_weight: string;
}

const VoiceCard = ({ scenario, text, voiceBlob, exaggeration, temperature, cfg_weight }: VoiceCardProps) => {
  type Status = 'loading' | 'ready' | 'error';

  const [status, setStatus] = useState<Status>('loading');
  const [audioUrl, setAudioUrl] = useState('');
  const [isPlaying, setIsPlaying] = useState(false);
  const [elapsed, setElapsed] = useState(0);
  const [total, setTotal] = useState(0);

  const audioRef = useRef<HTMLAudioElement>(null);
  const bars = useMemo(() => makeWaveBars(), []);
  const playedCount = total > 0 ? Math.round((elapsed / total) * bars.length) : 0;

  const generate = useCallback(async () => {
    setStatus('loading');
    setAudioUrl('');
    setElapsed(0);
    setTotal(0);
    setIsPlaying(false);

    try {
      const fd = new FormData();
      fd.append('audio_file', voiceBlob, 'voice_recording.wav');
      fd.append('text', text);
      fd.append('language_id', 'ru');
      fd.append('exaggeration', exaggeration ?? '0.5');
      fd.append('temperature', temperature ?? '0.8');
      fd.append('seed_num', String(Math.floor(Math.random() * 10000)));
      fd.append('cfg_weight', cfg_weight ?? '0.5');

      const res = await fetch(API_URL, { method: 'POST', body: fd });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);

      const blob = await res.blob();
      setAudioUrl(URL.createObjectURL(blob));
      setStatus('ready');
    } catch {
      setStatus('error');
    }
  }, [voiceBlob, text]);

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

  const togglePlay = () => {
    const a = audioRef.current;
    if (!a) return;
    isPlaying ? a.pause() : a.play();
  };

  const seekTo = (e: React.MouseEvent<HTMLDivElement>) => {
    const a = audioRef.current;
    if (!a || !total) return;
    const rect = e.currentTarget.getBoundingClientRect();
    a.currentTime = ((e.clientX - rect.left) / rect.width) * total;
  };

  return (
    <div className="voice-card">
      <div className="voice-card-scenario">{scenario}</div>
      <p className="voice-card-quote">"{text}"</p>

      <div className="audio-msg">
        {/* Play / pause / loading */}
        <button
          className={`audio-msg-btn${status === 'loading' ? ' loading' : ''}`}
          onClick={status === 'ready' ? togglePlay : undefined}
          disabled={status !== 'ready'}
          title={isPlaying ? 'Пауза' : 'Воспроизвести'}
        >
          {status === 'loading' && <span className="audio-spinner" />}
          {status === 'error'   && '⚠'}
          {status === 'ready'   && (isPlaying ? '⏸' : '▶')}
        </button>

        {/* Волна + время */}
        <div className="audio-msg-wave">
          <div className="waveform" onClick={seekTo}>
            {bars.map((h, i) => (
              <div
                key={i}
                className={`waveform-bar${i < playedCount ? ' played' : ''}`}
                style={{ height: `${h}%` }}
              />
            ))}
          </div>
          <div className="audio-msg-time">
            {status === 'loading' && 'генерация...'}
            {status === 'error'   && 'ошибка'}
            {status === 'ready'   && `${fmt(elapsed)} / ${fmt(total)}`}
          </div>
        </div>
      </div>

      {status === 'ready' && (
        <audio
          ref={audioRef}
          src={audioUrl}
          onPlay={() => setIsPlaying(true)}
          onPause={() => setIsPlaying(false)}
          onEnded={() => { setIsPlaying(false); setElapsed(0); }}
          onTimeUpdate={() => setElapsed(audioRef.current?.currentTime ?? 0)}
          onLoadedMetadata={() => setTotal(audioRef.current?.duration ?? 0)}
        />
      )}

      <button
        className="regen-btn"
        onClick={generate}
        disabled={status === 'loading'}
        title="Перегенерировать"
      >
        🔄 Перегенерировать
      </button>
    </div>
  );
};

/* ────────────────────────── VoiceCards ────────────────────────── */

interface VoiceCardsProps {
  voiceBlob: Blob;
}

const VoiceCards = ({ voiceBlob }: VoiceCardsProps) => (
  <div className="voice-cards">
    {EXAMPLES.map((ex) => (
		// @ts-ignore
		<VoiceCard key={ex.scenario} voiceBlob={voiceBlob} {...ex} />
    ))}
  </div>
);

export default VoiceCards;
