'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import Link from 'next/link';

type Mode = 'simple' | 'custom';
type FlowTab = 'story' | 'manual';
type StoryStage = 'input' | 'preview';

type SunoClip = {
  id: string;
  title?: string;
  audioUrl?: string;
  streamAudioUrl?: string;
  imageUrl?: string;
  tags?: string;
  duration?: number;
  prompt?: string;
};

type TaskState = {
  taskId: string;
  status: string;
  errorMessage?: string;
  clips: SunoClip[];
  updatedAt: number;
};

type TrackMeta = {
  title?: string;
  story?: string;
  lyrics?: string;
  style?: string;
};

type MusicStory = {
  title: string;
  lyrics: string;
  style: string;
  mood: string;
};

const MODELS = [
  { id: 'V4', label: 'V4 (기본)', desc: '안정적 고품질' },
  { id: 'V4_5', label: 'V4.5', desc: '최신 · 풍부한 디테일' },
  { id: 'V3_5', label: 'V3.5', desc: '빠른 생성' },
];

const TAG_PRESETS = [
  'k-pop', 'lo-fi', 'city pop', 'ballad', 'edm', 'trap',
  'rock', 'jazz', 'acoustic', 'cinematic', 'synthwave', 'ambient',
];

const LS_KEY = 'jsm_studio_task_ids_v2';
const LOGIN_HREF = '/login?next=/music/studio';

const isDone = (s: string) => s === 'SUCCESS' || s === 'FIRST_SUCCESS';
const isFailed = (s: string) => s.includes('FAILED') || s === 'SENSITIVE_WORD_ERROR';

const FIELD_INPUT =
  'w-full rounded-xl border border-[var(--jsm-line)] bg-white px-4 py-3 text-base text-[var(--jsm-ink)] outline-none transition focus:border-[var(--jsm-accent)]';

export default function StudioPage() {
  const [flowTab, setFlowTab] = useState<FlowTab>('story');
  const [mode, setMode] = useState<Mode>('simple');
  const [model, setModel] = useState('V4');
  const [prompt, setPrompt] = useState('');
  const [title, setTitle] = useState('');
  const [lyrics, setLyrics] = useState('');
  const [tags, setTags] = useState('');
  const [instrumental, setInstrumental] = useState(false);

  // 스토리 흐름 상태
  const [storyText, setStoryText] = useState('');
  const [storyStage, setStoryStage] = useState<StoryStage>('input');
  const [storyLoading, setStoryLoading] = useState(false);
  const [storyError, setStoryError] = useState<string | null>(null);
  const [storyAuthRequired, setStoryAuthRequired] = useState(false);
  const [mood, setMood] = useState('');

  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [authRequired, setAuthRequired] = useState(false);
  const [tasks, setTasks] = useState<TaskState[]>([]);
  const pollRef = useRef<number | null>(null);

  // 생성 요청 시점의 원본(스토리/가사/스타일)을 taskId에 매핑 — 완료 후 자동 저장에 사용
  const metaRef = useRef<Map<string, TrackMeta>>(new Map());
  // 자동 저장 완료(또는 시도) 표시 — 중복 저장 방지
  const savedRef = useRef<Set<string>>(new Set());
  // 이번 세션에서 새로 생성한 taskId만 자동 저장 대상으로 삼는다
  // (새로고침 시 localStorage에서 복원된 과거 완료 트랙까지 재저장하는 것 방지)
  const sessionTaskIdsRef = useRef<Set<string>>(new Set());

  const saveToLS = useCallback((ids: string[]) => {
    if (typeof window === 'undefined') return;
    try { localStorage.setItem(LS_KEY, JSON.stringify(ids.slice(0, 20))); } catch { /* noop */ }
  }, []);

  const fetchOne = useCallback(async (taskId: string) => {
    try {
      const res = await fetch(`/api/studio/status?taskId=${encodeURIComponent(taskId)}`);
      const json = await res.json();
      if (!json.ok) return null;
      const d = json.data?.data ?? json.data;
      const status: string = d?.status ?? 'PENDING';
      const errMsg: string | undefined = d?.errorMessage;
      const sunoData: SunoClip[] = d?.response?.sunoData ?? [];
      return { taskId, status, errorMessage: errMsg, clips: sunoData, updatedAt: Date.now() } as TaskState;
    } catch {
      return null;
    }
  }, []);

  const refreshAll = useCallback(async (ids: string[]) => {
    const results = await Promise.all(ids.map((id) => fetchOne(id)));
    setTasks((prev) => {
      const map = new Map(prev.map((t) => [t.taskId, t]));
      for (const r of results) if (r) map.set(r.taskId, r);
      return Array.from(map.values()).sort((a, b) => b.updatedAt - a.updatedAt);
    });
  }, [fetchOne]);

  useEffect(() => {
    if (typeof window === 'undefined') return;
    try {
      const raw = localStorage.getItem(LS_KEY);
      const ids = raw ? (JSON.parse(raw) as string[]) : [];
      if (ids.length) {
        setTasks(ids.map((id) => ({ taskId: id, status: 'PENDING', clips: [], updatedAt: Date.now() })));
        refreshAll(ids);
      }
    } catch { /* noop */ }
  }, [refreshAll]);

  useEffect(() => {
    if (pollRef.current) window.clearInterval(pollRef.current);
    const pending = tasks.filter((t) => !isDone(t.status) && !isFailed(t.status));
    if (pending.length) {
      pollRef.current = window.setInterval(() => {
        refreshAll(pending.map((t) => t.taskId));
      }, 8000);
    }
    return () => { if (pollRef.current) window.clearInterval(pollRef.current); };
  }, [tasks, refreshAll]);

  // 완료된 트랙 자동 저장 (best-effort) — 실패해도 재생에는 영향 없음
  useEffect(() => {
    tasks.forEach((task) => {
      if (!isDone(task.status)) return;
      if (!sessionTaskIdsRef.current.has(task.taskId)) return;
      if (savedRef.current.has(task.taskId)) return;
      const clip = task.clips.find((c) => c.audioUrl || c.streamAudioUrl);
      if (!clip) return;

      savedRef.current.add(task.taskId);
      const meta = metaRef.current.get(task.taskId);
      const audioUrl = clip.audioUrl || clip.streamAudioUrl || '';
      fetch('/api/studio/tracks', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          title: meta?.title || clip.title || null,
          story: meta?.story || null,
          lyrics: meta?.lyrics || null,
          style: meta?.style || clip.tags || null,
          audio_url: audioUrl,
          task_id: task.taskId,
        }),
      }).catch(() => { /* 비로그인·오류 등 — 무시(best-effort) */ });
    });
  }, [tasks]);

  const runGenerate = useCallback(async (forcedMode: Mode, meta: TrackMeta) => {
    setError(null);
    setAuthRequired(false);
    if (forcedMode === 'simple' && !prompt.trim()) { setError('프롬프트를 입력해주세요.'); return; }
    if (forcedMode === 'custom') {
      if (!title.trim()) { setError('트랙 제목을 입력해주세요.'); return; }
      if (!tags.trim()) { setError('스타일 태그를 입력해주세요.'); return; }
      if (!lyrics.trim() && !instrumental) { setError('가사를 입력하거나 Instrumental을 켜주세요.'); return; }
    }
    setSubmitting(true);
    try {
      const res = await fetch('/api/studio/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          mode: forcedMode, model,
          prompt: prompt.trim(),
          title: title.trim(),
          lyrics: lyrics.trim(),
          tags: tags.trim(),
          make_instrumental: instrumental,
        }),
      });
      const json = await res.json().catch(() => ({}));
      if (res.status === 401) {
        setAuthRequired(true);
        setError('로그인이 필요합니다.');
        return;
      }
      if (res.status === 429) {
        setError(typeof json.error === 'string' ? json.error : '오늘 생성 가능 횟수를 모두 사용했습니다.');
        return;
      }
      if (!res.ok || !json.ok) {
        setError(typeof json.error === 'string' ? json.error : '생성 실패');
        return;
      }
      const taskId: string | undefined = json.data?.data?.taskId ?? json.data?.taskId;
      if (!taskId) {
        setError('응답에서 taskId를 찾지 못했습니다.');
        return;
      }
      metaRef.current.set(taskId, meta);
      sessionTaskIdsRef.current.add(taskId);
      setTasks((prev) => {
        const next: TaskState[] = [
          { taskId, status: 'PENDING', clips: [], updatedAt: Date.now() },
          ...prev.filter((t) => t.taskId !== taskId),
        ];
        saveToLS(next.map((t) => t.taskId));
        return next;
      });
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setSubmitting(false);
    }
  }, [prompt, title, lyrics, tags, instrumental, model, saveToLS]);

  const onManualSubmit = () => {
    runGenerate(mode, {
      title: mode === 'custom' ? title.trim() : undefined,
      lyrics: mode === 'custom' ? lyrics.trim() : undefined,
      style: mode === 'custom' ? tags.trim() : undefined,
      story: mode === 'simple' ? prompt.trim() : undefined,
    });
  };

  const onStoryGenerate = () => {
    runGenerate('custom', {
      title: title.trim(),
      lyrics: lyrics.trim(),
      style: tags.trim(),
      story: storyText.trim(),
    });
  };

  const onMakeLyrics = async () => {
    setStoryError(null);
    setStoryAuthRequired(false);
    if (!storyText.trim()) {
      setStoryError('이야기를 먼저 입력해주세요.');
      return;
    }
    setStoryLoading(true);
    try {
      const res = await fetch('/api/studio/story', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ story: storyText.trim() }),
      });
      const json = await res.json().catch(() => ({}));
      if (res.status === 401) {
        setStoryAuthRequired(true);
        setStoryError('로그인이 필요합니다.');
        return;
      }
      if (res.status === 503 || res.status === 502) {
        setStoryError(typeof json.error === 'string' ? json.error : 'AI 서비스가 잠시 준비 중입니다. 잠시 후 다시 시도해주세요.');
        return;
      }
      if (!res.ok || !json.story) {
        setStoryError(typeof json.error === 'string' ? json.error : '가사 생성에 실패했습니다.');
        return;
      }
      const s = json.story as MusicStory;
      setTitle(s.title);
      setLyrics(s.lyrics);
      setTags(s.style);
      setMood(s.mood);
      setStoryStage('preview');
    } catch (e) {
      setStoryError(e instanceof Error ? e.message : String(e));
    } finally {
      setStoryLoading(false);
    }
  };

  const addTag = (t: string) => {
    const cur = tags.split(',').map((x) => x.trim()).filter(Boolean);
    if (cur.includes(t)) return;
    setTags([...cur, t].join(', '));
  };

  return (
    <div
      className="min-h-screen px-4 md:px-8 lg:px-12 py-10"
      style={{ background: 'var(--jsm-bg)', color: 'var(--jsm-ink)' }}
    >
      <div className="max-w-7xl mx-auto">
        <div className="flex items-end justify-between flex-wrap gap-4 mb-8">
          <div>
            <span className="kx-label">JAENGSEUNG STUDIO</span>
            <h1 className="kx-display text-3xl md:text-5xl font-extrabold mt-2" style={{ letterSpacing: '-0.02em' }}>
              나의 이야기를 음악으로
            </h1>
            <p className="mt-2 text-sm" style={{ color: 'var(--jsm-ink-soft)' }}>
              이야기를 들려주면 AI가 가사·스타일을 제안합니다. 직접 입력 모드로 세밀하게 조정할 수도 있어요.
            </p>
          </div>
          <div
            className="text-xs px-3 py-1.5 rounded-full font-semibold tracking-wide"
            style={{
              border: '1px solid var(--jsm-accent)',
              background: 'var(--jsm-accent-soft)',
              color: 'var(--jsm-accent)',
            }}
          >
            STUDIO · LIVE
          </div>
        </div>

        <div className="grid lg:grid-cols-[minmax(0,7fr)_minmax(0,5fr)] gap-6">
          {/* 좌측: 제어판 */}
          <div className="rounded-2xl p-6 md:p-8 bg-white border border-[var(--jsm-line)]">
            <div className="flex gap-1 p-1 rounded-full mb-6" style={{ background: 'var(--jsm-surface-alt)' }}>
              {(['story', 'manual'] as FlowTab[]).map((t) => (
                <button
                  key={t}
                  onClick={() => setFlowTab(t)}
                  className="flex-1 py-2.5 text-sm font-semibold rounded-full transition-all"
                  style={
                    flowTab === t
                      ? { background: 'var(--jsm-accent)', color: '#fff' }
                      : { color: 'var(--jsm-ink-soft)' }
                  }
                >
                  {t === 'story' ? '스토리로 만들기' : '직접 입력'}
                </button>
              ))}
            </div>

            {flowTab === 'story' ? (
              <div className="space-y-5">
                {storyStage === 'input' ? (
                  <>
                    <Field label="나의 이야기" hint="추억·순간·감정을 편하게 적어주세요">
                      <textarea
                        value={storyText}
                        onChange={(e) => setStoryText(e.target.value)}
                        rows={7}
                        placeholder="예: 대학 시절 자취방에서 혼자 라면을 끓여 먹으며 창밖 비 오는 거리를 보던 밤, 외로웠지만 이상하게 평온했던 기억"
                        className={`${FIELD_INPUT} resize-none`}
                      />
                    </Field>

                    <button
                      onClick={onMakeLyrics}
                      disabled={storyLoading}
                      className="w-full py-4 rounded-xl font-bold text-base transition disabled:opacity-60"
                      style={{ background: 'var(--jsm-accent)', color: '#fff' }}
                    >
                      {storyLoading ? '가사 만드는 중…' : '가사 만들기'}
                    </button>

                    {storyError && (
                      <div className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700">
                        {storyError}
                        {storyAuthRequired && (
                          <Link
                            href={LOGIN_HREF}
                            className="ml-2 font-semibold underline underline-offset-2"
                            style={{ color: 'var(--jsm-accent)' }}
                          >
                            로그인하러 가기
                          </Link>
                        )}
                      </div>
                    )}
                  </>
                ) : (
                  <>
                    <div className="flex items-center justify-between">
                      <span
                        className="text-xs px-3 py-1 rounded-full font-semibold"
                        style={{ background: 'var(--jsm-accent-soft)', color: 'var(--jsm-accent)' }}
                      >
                        무드 · {mood || '미정'}
                      </span>
                      <button
                        onClick={() => setStoryStage('input')}
                        className="text-xs underline underline-offset-4"
                        style={{ color: 'var(--jsm-ink-soft)' }}
                      >
                        이야기 다시 쓰기
                      </button>
                    </div>

                    <Field label="트랙 제목">
                      <input
                        value={title}
                        onChange={(e) => setTitle(e.target.value)}
                        placeholder="예: 새벽 세 시의 도시"
                        className={FIELD_INPUT}
                      />
                    </Field>
                    <Field label="가사" hint="AI가 제안한 가사입니다 — 자유롭게 수정 가능">
                      <textarea
                        value={lyrics}
                        onChange={(e) => setLyrics(e.target.value)}
                        rows={8}
                        className={`${FIELD_INPUT} resize-none font-mono text-sm leading-relaxed`}
                      />
                    </Field>
                    <Field label="스타일 태그" hint="쉼표로 구분 · 장르·무드·악기·보컬 톤">
                      <input
                        value={tags}
                        onChange={(e) => setTags(e.target.value)}
                        placeholder="city pop, female vocal, 120bpm, synth, nostalgic"
                        className={FIELD_INPUT}
                      />
                      <div className="flex flex-wrap gap-1.5 mt-3">
                        {TAG_PRESETS.map((t) => (
                          <button
                            key={t}
                            onClick={() => addTag(t)}
                            className="text-xs px-2.5 py-1 rounded-full transition"
                            style={{
                              background: 'var(--jsm-surface-alt)',
                              border: '1px solid var(--jsm-line)',
                              color: 'var(--jsm-ink-soft)',
                            }}
                          >
                            + {t}
                          </button>
                        ))}
                      </div>
                    </Field>

                    <div className="grid grid-cols-2 gap-4">
                      <Field label="모델">
                        <select
                          value={model}
                          onChange={(e) => setModel(e.target.value)}
                          className={`${FIELD_INPUT} text-sm`}
                        >
                          {MODELS.map((m) => (
                            <option key={m.id} value={m.id}>
                              {m.label} — {m.desc}
                            </option>
                          ))}
                        </select>
                      </Field>
                      <Field label="Instrumental (가사 없음)">
                        <ToggleSwitch checked={instrumental} onChange={setInstrumental} />
                      </Field>
                    </div>

                    <div className="flex gap-3">
                      <button
                        onClick={onMakeLyrics}
                        disabled={storyLoading}
                        className="flex-1 py-3.5 rounded-xl font-semibold text-sm transition disabled:opacity-60"
                        style={{
                          background: 'var(--jsm-surface-alt)',
                          border: '1px solid var(--jsm-line)',
                          color: 'var(--jsm-ink)',
                        }}
                      >
                        {storyLoading ? '다시 만드는 중…' : '가사 다시 만들기'}
                      </button>
                      <button
                        onClick={onStoryGenerate}
                        disabled={submitting}
                        className="flex-1 py-3.5 rounded-xl font-bold text-sm transition disabled:opacity-60"
                        style={{ background: 'var(--jsm-accent)', color: '#fff' }}
                      >
                        {submitting ? '생성 요청 중…' : '음악 만들기'}
                      </button>
                    </div>

                    {storyError && (
                      <div className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700">
                        {storyError}
                      </div>
                    )}
                    {error && (
                      <div className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700">
                        {error}
                        {authRequired && (
                          <Link
                            href={LOGIN_HREF}
                            className="ml-2 font-semibold underline underline-offset-2"
                            style={{ color: 'var(--jsm-accent)' }}
                          >
                            로그인하러 가기
                          </Link>
                        )}
                      </div>
                    )}
                    <p className="text-[11px] leading-relaxed" style={{ color: 'var(--jsm-ink-soft)' }}>
                      생성된 결과는 Suno 서비스 약관을 따릅니다. 상업 이용 전 플랜·저작권을 반드시 확인하세요.
                    </p>
                  </>
                )}
              </div>
            ) : (
              <>
                <div className="flex gap-1 p-1 rounded-full mb-6" style={{ background: 'var(--jsm-surface-alt)' }}>
                  {(['simple', 'custom'] as Mode[]).map((m) => (
                    <button
                      key={m}
                      onClick={() => setMode(m)}
                      className="flex-1 py-2 text-xs font-semibold rounded-full transition-all"
                      style={
                        mode === m
                          ? { background: 'var(--jsm-accent)', color: '#fff' }
                          : { color: 'var(--jsm-ink-soft)' }
                      }
                    >
                      {m === 'simple' ? '간단 모드' : 'Custom 모드'}
                    </button>
                  ))}
                </div>

                {mode === 'simple' ? (
                  <div className="space-y-5">
                    <Field label="프롬프트" hint="무드·장르·가사 아이디어를 한 줄로">
                      <textarea
                        value={prompt}
                        onChange={(e) => setPrompt(e.target.value)}
                        rows={5}
                        placeholder="예: 비 오는 서울 새벽, 감성 시티팝 with 여성 보컬, 2010년대 무드"
                        className={`${FIELD_INPUT} resize-none`}
                      />
                    </Field>
                  </div>
                ) : (
                  <div className="space-y-5">
                    <Field label="트랙 제목">
                      <input
                        value={title}
                        onChange={(e) => setTitle(e.target.value)}
                        placeholder="예: 새벽 세 시의 도시"
                        className={FIELD_INPUT}
                      />
                    </Field>
                    <Field label="가사" hint="Suno 포맷: [Verse] [Chorus] [Bridge] 등 태그 가능">
                      <textarea
                        value={lyrics}
                        onChange={(e) => setLyrics(e.target.value)}
                        rows={8}
                        placeholder={'[Verse]\n차가운 조명 아래 걷는 나\n새벽 세 시의 도시는 낯설어\n\n[Chorus]\n...'}
                        className={`${FIELD_INPUT} resize-none font-mono text-sm leading-relaxed`}
                      />
                    </Field>
                    <Field label="스타일 태그" hint="쉼표로 구분 · 장르·무드·악기·보컬 톤">
                      <input
                        value={tags}
                        onChange={(e) => setTags(e.target.value)}
                        placeholder="city pop, female vocal, 120bpm, synth, nostalgic"
                        className={FIELD_INPUT}
                      />
                      <div className="flex flex-wrap gap-1.5 mt-3">
                        {TAG_PRESETS.map((t) => (
                          <button
                            key={t}
                            onClick={() => addTag(t)}
                            className="text-xs px-2.5 py-1 rounded-full transition"
                            style={{
                              background: 'var(--jsm-surface-alt)',
                              border: '1px solid var(--jsm-line)',
                              color: 'var(--jsm-ink-soft)',
                            }}
                          >
                            + {t}
                          </button>
                        ))}
                      </div>
                    </Field>
                  </div>
                )}

                <div className="grid grid-cols-2 gap-4 mt-6">
                  <Field label="모델">
                    <select
                      value={model}
                      onChange={(e) => setModel(e.target.value)}
                      className={`${FIELD_INPUT} text-sm`}
                    >
                      {MODELS.map((m) => (
                        <option key={m.id} value={m.id}>
                          {m.label} — {m.desc}
                        </option>
                      ))}
                    </select>
                  </Field>
                  <Field label="Instrumental (가사 없음)">
                    <ToggleSwitch checked={instrumental} onChange={setInstrumental} />
                  </Field>
                </div>

                <div className="mt-8">
                  <button
                    onClick={onManualSubmit}
                    disabled={submitting}
                    className="w-full py-4 rounded-xl font-extrabold text-base transition-all disabled:opacity-60"
                    style={{ background: 'var(--jsm-accent)', color: '#fff' }}
                  >
                    {submitting ? '생성 요청 중…' : '트랙 생성하기'}
                  </button>
                  {error && (
                    <div className="mt-3 rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700">
                      {error}
                      {authRequired && (
                        <Link
                          href={LOGIN_HREF}
                          className="ml-2 font-semibold underline underline-offset-2"
                          style={{ color: 'var(--jsm-accent)' }}
                        >
                          로그인하러 가기
                        </Link>
                      )}
                    </div>
                  )}
                  <p className="mt-3 text-[11px] leading-relaxed" style={{ color: 'var(--jsm-ink-soft)' }}>
                    생성된 결과는 Suno 서비스 약관을 따릅니다. 상업 이용 전 플랜·저작권을 반드시 확인하세요.
                  </p>
                </div>
              </>
            )}
          </div>

          {/* 우측: 결과 */}
          <div className="rounded-2xl p-6 md:p-7 bg-white border border-[var(--jsm-line)]">
            <div className="flex items-center justify-between mb-4">
              <div>
                <span className="kx-label">RECENT TRACKS</span>
                <h2 className="kx-display text-xl font-bold mt-1">최근 생성 결과</h2>
              </div>
              {tasks.length > 0 && (
                <button
                  onClick={() => { setTasks([]); saveToLS([]); }}
                  className="text-[11px] underline underline-offset-4"
                  style={{ color: 'var(--jsm-ink-soft)' }}
                >
                  기록 지우기
                </button>
              )}
            </div>

            {tasks.length === 0 ? (
              <div
                className="rounded-xl p-8 text-center text-sm border border-dashed"
                style={{ borderColor: 'var(--jsm-line)', color: 'var(--jsm-ink-soft)' }}
              >
                아직 생성된 트랙이 없습니다.
                <br />왼쪽에서 이야기를 들려주거나 프롬프트를 입력해보세요.
              </div>
            ) : (
              <ul className="space-y-4 max-h-[640px] overflow-y-auto pr-1">
                {tasks.map((task) => (
                  <li
                    key={task.taskId}
                    className="rounded-xl p-4 border"
                    style={{ background: 'var(--jsm-surface-alt)', borderColor: 'var(--jsm-line)' }}
                  >
                    <div className="flex items-center justify-between gap-3 mb-3">
                      <span className="text-[11px] font-mono" style={{ color: 'var(--jsm-ink-faint)' }}>
                        task: {task.taskId.slice(0, 10)}…
                      </span>
                      <StatusBadge status={task.status} />
                    </div>

                    {task.clips.length === 0 ? (
                      <div
                        className="h-9 rounded-md flex items-center justify-center text-xs"
                        style={{ background: 'var(--jsm-surface)', color: 'var(--jsm-ink-soft)' }}
                      >
                        {isFailed(task.status)
                          ? (task.errorMessage ?? '생성 실패')
                          : '오디오 생성 중… (보통 1~3분)'}
                      </div>
                    ) : (
                      <div className="space-y-3">
                        {task.clips.map((c) => {
                          const src = c.audioUrl || c.streamAudioUrl;
                          return (
                            <div
                              key={c.id}
                              className="rounded-lg p-3 bg-white border"
                              style={{ borderColor: 'var(--jsm-line)' }}
                            >
                              <div className="flex items-center gap-3">
                                {c.imageUrl && (
                                  // eslint-disable-next-line @next/next/no-img-element
                                  <img
                                    src={c.imageUrl}
                                    alt=""
                                    className="w-12 h-12 rounded-md object-cover flex-shrink-0"
                                  />
                                )}
                                <div className="min-w-0 flex-1">
                                  <p className="font-semibold text-sm truncate" style={{ color: 'var(--jsm-ink)' }}>
                                    {c.title || '제목 없음'}
                                  </p>
                                  {c.tags && (
                                    <p className="text-[11px] truncate mt-0.5" style={{ color: 'var(--jsm-ink-soft)' }}>
                                      {c.tags}
                                    </p>
                                  )}
                                </div>
                                {c.duration && (
                                  <span className="text-[10px] font-mono" style={{ color: 'var(--jsm-ink-faint)' }}>
                                    {Math.round(c.duration)}s
                                  </span>
                                )}
                              </div>
                              {src ? (
                                <audio controls src={src} className="w-full mt-2" style={{ height: 36 }} />
                              ) : null}
                              {c.audioUrl && (
                                <div className="mt-1.5 text-[11px]" style={{ color: 'var(--jsm-ink-soft)' }}>
                                  <a
                                    href={c.audioUrl}
                                    download
                                    className="underline underline-offset-4"
                                    style={{ color: 'var(--jsm-accent)' }}
                                  >
                                    MP3 다운로드
                                  </a>
                                </div>
                              )}
                            </div>
                          );
                        })}
                      </div>
                    )}
                  </li>
                ))}
              </ul>
            )}
          </div>
        </div>

        <div className="mt-10 grid md:grid-cols-3 gap-4 text-xs" style={{ color: 'var(--jsm-ink-soft)' }}>
          <Tip title="① 스토리 모드" body="이야기를 적으면 AI가 제목·가사·스타일을 자동으로 제안합니다." />
          <Tip title="② 직접 입력 모드" body="가사·태그·보컬·악기까지 정밀 제어. 반복 생성에 유리." />
          <Tip title="③ 상업 이용" body="Suno Pro 이상 플랜에서 생성한 결과만 수익화 가능. 플랜 확인 필수." />
        </div>
      </div>
    </div>
  );
}

function Field({
  label,
  hint,
  children,
}: {
  label: string;
  hint?: string;
  children: React.ReactNode;
}) {
  return (
    <div>
      <div className="flex items-baseline justify-between mb-2">
        <span className="text-[11px] font-semibold tracking-widest uppercase" style={{ color: 'var(--jsm-accent)' }}>
          {label}
        </span>
        {hint && <span className="text-[10px]" style={{ color: 'var(--jsm-ink-soft)' }}>{hint}</span>}
      </div>
      {children}
    </div>
  );
}

function ToggleSwitch({ checked, onChange }: { checked: boolean; onChange: (v: boolean) => void }) {
  return (
    <label className="flex items-center gap-3 cursor-pointer">
      <span
        className="relative inline-block w-11 h-6 rounded-full transition"
        style={{ background: checked ? 'var(--jsm-accent)' : 'var(--jsm-line)' }}
      >
        <span
          className="absolute top-0.5 w-5 h-5 rounded-full bg-white transition-all"
          style={{ left: checked ? '22px' : '2px' }}
        />
      </span>
      <input
        type="checkbox"
        checked={checked}
        onChange={(e) => onChange(e.target.checked)}
        className="sr-only"
      />
      <span className="text-xs" style={{ color: 'var(--jsm-ink-soft)' }}>
        {checked ? 'ON' : 'OFF'}
      </span>
    </label>
  );
}

function StatusBadge({ status }: { status: string }) {
  const map: Record<string, { bg: string; fg: string; border: string; label: string }> = {
    SUCCESS: { bg: '#ecfdf5', fg: '#047857', border: '#a7f3d0', label: '완료' },
    FIRST_SUCCESS: { bg: 'var(--jsm-accent-soft)', fg: 'var(--jsm-accent)', border: 'var(--jsm-accent)', label: '첫 트랙 준비' },
    TEXT_SUCCESS: { bg: 'var(--jsm-accent-soft)', fg: 'var(--jsm-accent)', border: 'var(--jsm-accent)', label: '가사 완료' },
    PENDING: { bg: 'var(--jsm-surface-alt)', fg: 'var(--jsm-ink-soft)', border: 'var(--jsm-line)', label: '대기' },
  };
  let entry = map[status];
  if (!entry) {
    entry = isFailed(status)
      ? { bg: '#fef2f2', fg: '#b91c1c', border: '#fecaca', label: '실패' }
      : { bg: 'var(--jsm-surface-alt)', fg: 'var(--jsm-ink-soft)', border: 'var(--jsm-line)', label: status };
  }
  return (
    <span
      className="text-[10px] font-semibold px-2 py-0.5 rounded-full whitespace-nowrap border"
      style={{ background: entry.bg, color: entry.fg, borderColor: entry.border }}
    >
      {entry.label}
    </span>
  );
}

function Tip({ title, body }: { title: string; body: string }) {
  return (
    <div className="rounded-xl p-4 bg-white border" style={{ borderColor: 'var(--jsm-line)' }}>
      <p className="font-semibold mb-1" style={{ color: 'var(--jsm-ink)' }}>
        {title}
      </p>
      <p className="leading-relaxed">{body}</p>
    </div>
  );
}
