import { useState, useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
import api from "../api/client";
import { useAuth } from "../auth/AuthContext";
import ConfirmDialog from "../components/ConfirmDialog";
import SpeedCalculatorModal from "./SpeedCalculatorModal";
import PlaybackModal from "./PlaybackModal";
import BinaryTableModal from "./BinaryTableModal";

function fallbackCopy(text, onSuccess) {
  const ta = document.createElement("textarea");
  ta.value = text;
  ta.style.cssText = "position:fixed;top:0;left:0;opacity:0";
  document.body.appendChild(ta);
  ta.focus();
  ta.select();
  try { document.execCommand("copy"); onSuccess?.(); } catch (_) {}
  document.body.removeChild(ta);
}

function copyText(text, onSuccess) {
  if (navigator.clipboard) {
    navigator.clipboard.writeText(text).then(onSuccess).catch(() => fallbackCopy(text, onSuccess));
  } else {
    fallbackCopy(text, onSuccess);
  }
}
import {
  getLocalizedValue,
  getLanguageName,
  normalizeColor,
  formatDuration,
} from "./melodyUtils";

function formatBpm(ms) {
  const value = Number(ms);
  if (!value || value <= 0) return null;
  return Math.round(60000 / value);
}

function mapPercentageToStepDelay(percent, minSpeed, maxSpeed) {
  if (minSpeed == null || maxSpeed == null) return null;
  const p = Math.max(0, Math.min(100, Number(percent || 0)));
  const t = p / 100;
  const a = Number(minSpeed);
  const b = Number(maxSpeed);
  if (a <= 0 || b <= 0) return Math.round(a + (b - a) * t);
  return Math.round(a * Math.pow(b / a, t));
}

function normalizeFileUrl(url) {
  if (!url || typeof url !== "string") return null;
  if (url.startsWith("http") || url.startsWith("/api")) return url;
  if (url.startsWith("/")) return `/api${url}`;
  return `/api/${url}`;
}

function Field({ label, children }) {
  return (
    <div>
      <dt className="ui-field-label">{label}</dt>
      <dd className="mt-1 text-sm" style={{ color: "var(--text-primary)" }}>{children || "-"}</dd>
    </div>
  );
}

function UrlField({ label, value }) {
  const [copied, setCopied] = useState(false);
  return (
    <div>
      <dt className="ui-field-label mb-1">{label}</dt>
      <dd className="flex items-center gap-2">
        <span
          className="text-sm font-mono flex-1 min-w-0"
          style={{
            color: "var(--text-primary)",
            overflow: "hidden",
            textOverflow: "ellipsis",
            whiteSpace: "nowrap",
            display: "block",
            userSelect: "text",
          }}
          title={value}
        >
          {value}
        </span>
        <button
          onClick={() => copyText(value, () => { setCopied(true); setTimeout(() => setCopied(false), 2000); })}
          className="flex-shrink-0 px-2 py-0.5 text-xs rounded transition-colors"
          style={{
            backgroundColor: copied ? "var(--success-bg)" : "var(--bg-card-hover)",
            color: copied ? "var(--success-text)" : "var(--text-muted)",
            border: "1px solid var(--border-primary)",
          }}
        >
          {copied ? "Copied!" : "Copy"}
        </button>
      </dd>
    </div>
  );
}

export default function MelodyDetail() {
  const { id } = useParams();
  const navigate = useNavigate();
  const { hasPermission } = useAuth();
  const canEdit = hasPermission("melodies", "edit");

  const [melody, setMelody] = useState(null);
  const [files, setFiles] = useState({});
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");
  const [showDelete, setShowDelete] = useState(false);
  const [showUnpublish, setShowUnpublish] = useState(false);
  const [actionLoading, setActionLoading] = useState(false);
  const [displayLang, setDisplayLang] = useState("en");
  const [melodySettings, setMelodySettings] = useState(null);
  const [builtMelody, setBuiltMelody] = useState(null);
  const [codeCopied, setCodeCopied] = useState(false);
  const [showSpeedCalc, setShowSpeedCalc] = useState(false);
  const [showPlayback, setShowPlayback] = useState(false);
  const [showBinaryView, setShowBinaryView] = useState(false);

  useEffect(() => {
    api.get("/settings/melody").then((ms) => {
      setMelodySettings(ms);
      setDisplayLang(ms.primary_language || "en");
    });
  }, []);

  useEffect(() => {
    loadData();
  }, [id]);

  const loadData = async () => {
    setLoading(true);
    try {
      const [m, f] = await Promise.all([
        api.get(`/melodies/${id}`),
        api.get(`/melodies/${id}/files`),
      ]);
      setMelody(m);
      setFiles(f);
      // Load built melody assignment (non-fatal if it fails)
      try {
        const bm = await api.get(`/builder/melodies/for-melody/${id}`);
        setBuiltMelody(bm || null);
      } catch {
        setBuiltMelody(null);
      }
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  const handleDelete = async () => {
    try {
      await api.delete(`/melodies/${id}`);
      navigate("/melodies");
    } catch (err) {
      setError(err.message);
      setShowDelete(false);
    }
  };

  const handlePublish = async () => {
    setActionLoading(true);
    try {
      await api.post(`/melodies/${id}/publish`);
      await loadData();
    } catch (err) {
      setError(err.message);
    } finally {
      setActionLoading(false);
    }
  };

  const handleUnpublish = async () => {
    setActionLoading(true);
    try {
      await api.post(`/melodies/${id}/unpublish`);
      setShowUnpublish(false);
      await loadData();
    } catch (err) {
      setError(err.message);
      setShowUnpublish(false);
    } finally {
      setActionLoading(false);
    }
  };


  if (loading) {
    return <div className="text-center py-8" style={{ color: "var(--text-muted)" }}>Loading...</div>;
  }

  if (error) {
    return (
      <div
        className="text-sm rounded-md p-3 border"
        style={{
          backgroundColor: "var(--danger-bg)",
          borderColor: "var(--danger)",
          color: "var(--danger-text)",
        }}
      >
        {error}
      </div>
    );
  }

  if (!melody) return null;

  const info = melody.information || {};
  const settings = melody.default_settings || {};
  const speedMs = mapPercentageToStepDelay(settings.speed, info.minSpeed, info.maxSpeed);
  const speedBpm = formatBpm(speedMs);
  const minBpm = formatBpm(info.minSpeed);
  const maxBpm = formatBpm(info.maxSpeed);
  const missingArchetype = Boolean(melody.pid) && !builtMelody?.id;
  const languages = melodySettings?.available_languages || ["en"];
  const displayName = getLocalizedValue(info.name, displayLang, "Untitled Melody");

  const badgeStyle = (active) => ({
    backgroundColor: active ? "var(--success-bg)" : "var(--bg-card-hover)",
    color: active ? "var(--success-text)" : "var(--text-muted)",
  });

  return (
    <div>
      <div className="flex items-center justify-between mb-6">
        <div>
          <button
            onClick={() => navigate("/melodies")}
            className="text-sm mb-2 inline-block"
            style={{ color: "var(--accent)" }}
          >
            &larr; Back to Melodies
          </button>
          <div className="flex items-center gap-3">
            <h1 className="text-2xl font-bold" style={{ color: "var(--text-heading)" }}>{displayName}</h1>
            <span
              className="px-2.5 py-0.5 text-xs font-semibold rounded-full"
              style={melody.status === "published"
                ? { backgroundColor: "rgba(22,163,74,0.15)", color: "#22c55e" }
                : { backgroundColor: "rgba(156,163,175,0.15)", color: "#9ca3af" }
              }
            >
              {melody.status === "published" ? "LIVE" : "DRAFT"}
            </span>
            {languages.length > 1 && (
              <select
                value={displayLang}
                onChange={(e) => setDisplayLang(e.target.value)}
                className="text-xs px-2 py-1 rounded border"
              >
                {languages.map((l) => (
                  <option key={l} value={l}>
                    {getLanguageName(l)}
                  </option>
                ))}
              </select>
            )}
          </div>
        </div>
        {canEdit && (
          <div className="flex items-center gap-2">
            <button
              onClick={() => setShowPlayback(true)}
              className="px-4 py-2 text-sm rounded-md transition-colors"
              style={{ backgroundColor: "var(--btn-primary)", color: "var(--text-white)" }}
            >
              Playback
            </button>
            <button
              onClick={() => setShowSpeedCalc(true)}
              className="px-4 py-2 text-sm rounded-md transition-colors"
              style={{ backgroundColor: "var(--btn-neutral)", color: "var(--text-white)" }}
            >
              Speed Calculator
            </button>
            <div className="w-px h-6 mx-1" style={{ backgroundColor: "var(--border-primary)" }} />
            <button
              onClick={() => navigate(`/melodies/${id}/edit`)}
              className="px-4 py-2 text-sm rounded-md transition-colors"
              style={{ backgroundColor: "var(--text-link)", color: "var(--text-white)" }}
            >
              Edit
            </button>
            {melody.status === "draft" ? (
              <button
                onClick={handlePublish}
                disabled={actionLoading}
                className="px-4 py-2 text-sm rounded-md transition-colors disabled:opacity-50"
                style={{ backgroundColor: "var(--btn-primary)", color: "var(--text-white)" }}
              >
                {actionLoading ? "Publishing..." : "Publish"}
              </button>
            ) : (
              <button
                onClick={() => setShowUnpublish(true)}
                disabled={actionLoading}
                className="px-4 py-2 text-sm rounded-md transition-colors disabled:opacity-50"
                style={{ backgroundColor: "var(--danger-btn)", color: "var(--text-white)" }}
              >
                Unpublish
              </button>
            )}
            <button
              onClick={() => setShowDelete(true)}
              className="px-4 py-2 text-sm rounded-md transition-colors"
              style={{ backgroundColor: "var(--danger)", color: "var(--text-white)" }}
            >
              Delete
            </button>
          </div>
        )}
      </div>

      {info.outdated_archetype && (
        <div
          className="flex items-start gap-3 rounded-md px-4 py-3 text-sm border mb-6"
          style={{
            backgroundColor: "rgba(245,158,11,0.08)",
            borderColor: "rgba(245,158,11,0.35)",
            color: "#f59e0b",
          }}
        >
          <svg className="mt-0.5 shrink-0" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
            <line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>
          </svg>
          <span>
            <strong>Outdated Archetype</strong> — The archetype assigned to this melody has been changed or removed.
            Re-assign an archetype in the editor to update and clear this warning.
          </span>
        </div>
      )}

      <div className="grid grid-cols-1 xl:grid-cols-2 gap-6">
        {/* Left column */}
        <div className="space-y-6">
          {/* Melody Information */}
          <section
            className="ui-section-card"
          >
            <div className="ui-section-card__title-row">
              <h2 className="ui-section-card__title">Melody Information</h2>
            </div>
            <dl className="grid grid-cols-2 md:grid-cols-3 gap-4">
              <Field label="Color">
                {info.color ? (
                  <span className="inline-flex items-center gap-2">
                    <span
                      className="w-4 h-4 rounded inline-block border"
                      style={{ backgroundColor: normalizeColor(info.color), borderColor: "var(--border-primary)" }}
                    />
                    {info.color}
                  </span>
                ) : (
                  "-"
                )}
              </Field>
              <Field label="Tone">
                <span className="capitalize">{info.melodyTone}</span>
              </Field>
              <Field label="Steps">{info.steps}</Field>
              <Field label="Min Speed">
                {info.minSpeed ? (
                  <span>
                    {minBpm} bpm <span className="text-xs" style={{ color: "var(--text-muted)" }}>· {info.minSpeed} ms</span>
                  </span>
                ) : "-"}
              </Field>
              <Field label="Max Speed">
                {info.maxSpeed ? (
                  <span>
                    {maxBpm} bpm <span className="text-xs" style={{ color: "var(--text-muted)" }}>· {info.maxSpeed} ms</span>
                  </span>
                ) : "-"}
              </Field>
              <Field label="Unique Bells">{info.totalActiveBells ?? "-"}</Field>
              <div className="col-span-2 md:col-span-3">
                <Field label="Description">
                  {getLocalizedValue(info.description, displayLang)}
                </Field>
              </div>
              <div className="col-span-2 md:col-span-3">
                <Field label="Custom Tags">
                  {info.customTags?.length > 0 ? (
                    <div className="flex flex-wrap gap-1 mt-1">
                      {info.customTags.map((tag) => (
                        <span
                          key={tag}
                          className="px-2 py-0.5 text-xs rounded-full"
                          style={{ backgroundColor: "var(--badge-blue-bg)", color: "var(--badge-blue-text)" }}
                        >
                          {tag}
                        </span>
                      ))}
                    </div>
                  ) : (
                    "-"
                  )}
                </Field>
              </div>
            </dl>
          </section>

          {/* Identifiers */}
          <section
            className="ui-section-card"
          >
            <div className="ui-section-card__title-row">
              <h2 className="ui-section-card__title">Identifiers</h2>
            </div>
            <dl className="grid grid-cols-2 md:grid-cols-3 gap-4">
              <Field label="Document ID">{melody.id}</Field>
              <Field label="PID (Playback ID)">{melody.pid}</Field>
              {melody.url && (
                <div className="col-span-2 md:col-span-3">
                  <UrlField label="URL" value={melody.url} />
                </div>
              )}
            </dl>
          </section>
        </div>

        {/* Right column */}
        <div className="space-y-6">
          {/* Default Settings */}
          <section
            className="ui-section-card"
          >
            <div className="ui-section-card__title-row">
              <h2 className="ui-section-card__title">Default Settings</h2>
            </div>
            <dl className="grid grid-cols-2 md:grid-cols-3 gap-4">
              <Field label="Speed">
                {settings.speed != null ? (
                  <span>
                    {settings.speed}%{speedBpm ? <span className="text-xs" style={{ color: "var(--text-muted)" }}>{` · ${speedBpm} bpm`}</span> : ""}{speedMs ? <span className="text-xs" style={{ color: "var(--text-muted)" }}>{` · ${speedMs} ms`}</span> : ""}
                  </span>
                ) : "-"}
              </Field>
              <Field label="Duration">{formatDuration(settings.duration)}</Field>
              <Field label="Total Run Duration">{settings.totalRunDuration}</Field>
              <Field label="Pause Duration">{settings.pauseDuration}</Field>
              <Field label="Infinite Loop">
                <span className="px-2 py-0.5 text-xs rounded-full" style={badgeStyle(settings.infiniteLoop)}>
                  {settings.infiniteLoop ? "Yes" : "No"}
                </span>
              </Field>
              <div className="col-span-2 md:col-span-3">
                <Field label="Echo Ring">
                  {settings.echoRing?.length > 0
                    ? settings.echoRing.join(", ")
                    : "-"}
                </Field>
              </div>
              <div className="col-span-2 md:col-span-3">
                <dt className="ui-field-label mb-2">Note Assignments</dt>
                <dd>
                  {settings.noteAssignments?.length > 0 ? (
                    <div className="flex flex-wrap gap-1.5">
                      {settings.noteAssignments.map((assignedBell, noteIdx) => {
                        return (
                          <div
                            key={noteIdx}
                            className="flex flex-col items-center rounded-md border"
                            style={{
                              minWidth: "36px",
                              padding: "4px 6px",
                              backgroundColor: "var(--bg-card-hover)",
                              borderColor: "var(--border-primary)",
                            }}
                          >
                            <span className="text-xs font-bold leading-tight" style={{ color: "var(--text-secondary)" }}>
                              {String.fromCharCode(65 + noteIdx)}
                            </span>
                            <div className="w-full my-0.5" style={{ height: "1px", backgroundColor: "var(--border-primary)" }} />
                            <span className="text-xs leading-tight" style={{ color: "var(--text-muted)" }}>
                              {assignedBell > 0 ? assignedBell : "-"}
                            </span>
                          </div>
                        );
                      })}
                    </div>
                  ) : (
                    <span style={{ color: "var(--text-muted)" }}>-</span>
                  )}
                  <p className="text-xs mt-1" style={{ color: "var(--text-muted)" }}>Top = Note, Bottom = Assigned Bell</p>
                </dd>
              </div>
            </dl>
          </section>

          {/* Files */}
          <section
            className="ui-section-card"
          >
            <div className="ui-section-card__title-row">
              <h2 className="ui-section-card__title">Files</h2>
            </div>
            <dl className="space-y-4">
              <Field label="Binary File">
                {(() => {
                  // Common source of truth: assigned archetype binary first, then melody URL, then uploaded file URL.
                  const binaryUrl = normalizeFileUrl(
                    (builtMelody?.binary_url ? `/api${builtMelody.binary_url}` : null) ||
                    melody.url ||
                    files.binary_url ||
                    null
                  );
                  if (!binaryUrl) return <span style={{ color: "var(--text-muted)" }}>Not uploaded</span>;

                  const binaryPid = builtMelody?.pid || melody.pid || "binary";
                  const binaryFilename = `${binaryPid}.bsm`;

                  // Derive a display name: for firebase URLs extract the filename portion
                  let downloadName = binaryFilename;
                  if (!builtMelody?.binary_url && !files.binary_url && melody.url) {
                    try {
                      const urlPath = decodeURIComponent(new URL(melody.url).pathname);
                      const parts = urlPath.split("/");
                      downloadName = parts[parts.length - 1] || binaryFilename;
                    } catch { /* keep binaryFilename */ }
                  }

                  const handleDownload = async (e) => {
                    e.preventDefault();
                    const preferredUrl = melody?.id ? `/api/melodies/${melody.id}/download/binary` : binaryUrl;
                    try {
                      const token = localStorage.getItem("access_token");
                      let res = null;
                      try {
                        res = await fetch(preferredUrl, {
                          headers: token ? { Authorization: `Bearer ${token}` } : {},
                        });
                      } catch {
                        if (binaryUrl.startsWith("http")) {
                          res = await fetch(binaryUrl);
                        } else {
                          throw new Error("Download failed: network error");
                        }
                      }
                      if ((!res || !res.ok) && binaryUrl.startsWith("http")) {
                        res = await fetch(binaryUrl);
                      }
                      if (!res.ok) throw new Error(`Download failed: ${res.statusText}`);
                      const blob = await res.blob();
                      const objectUrl = URL.createObjectURL(blob);
                      const a = document.createElement("a");
                      a.href = objectUrl;
                      a.download = downloadName;
                      a.click();
                      URL.revokeObjectURL(objectUrl);
                    } catch (err) {
                      const a = document.createElement("a");
                      a.href = binaryUrl;
                      a.download = downloadName;
                      a.rel = "noopener noreferrer";
                      document.body.appendChild(a);
                      a.click();
                      document.body.removeChild(a);
                    }
                  };

                  return (
                    <span className="inline-flex flex-col gap-0.5">
                      <span className="inline-flex items-center gap-2">
                        {builtMelody?.name ? (
                          <strong style={{ color: "var(--text-heading)" }}>{builtMelody.name}</strong>
                        ) : (
                          <span className="text-sm" style={{ color: "var(--text-secondary)" }}>
                            {downloadName}
                          </span>
                        )}
                        {missingArchetype && (
                          <span
                            className="text-xs cursor-help"
                            style={{ color: "#f59e0b" }}
                            title="This binary does not exist in the Archetypes"
                          >
                            ⚠
                          </span>
                        )}
                        <button
                          type="button"
                          onClick={handleDownload}
                          className="px-2 py-0.5 text-xs rounded-full"
                          style={{ color: "var(--text-link)", backgroundColor: "rgba(88,156,250,0.14)" }}
                        >
                          Download
                        </button>
                        <button
                          type="button"
                          onClick={() => setShowBinaryView(true)}
                          className="px-2 py-0.5 text-xs rounded-full"
                          style={{ color: "var(--text-secondary)", backgroundColor: "var(--bg-card-hover)" }}
                        >
                          View
                        </button>
                        <span className="text-xs" style={{ color: "var(--text-muted)" }}>
                          {info.totalNotes ?? 0} active notes
                        </span>
                        {!files.binary_url && melody.url && (
                          <span className="text-xs px-1.5 py-0.5 rounded" style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-muted)" }}>
                            via URL
                          </span>
                        )}
                      </span>
                      {builtMelody?.name && (
                        <span className="text-xs" style={{ color: "var(--text-muted)" }}>
                          file:{" "}
                          <a
                            href={binaryUrl}
                            onClick={handleDownload}
                            className="underline font-mono"
                            style={{ color: "var(--accent)" }}
                          >
                            {downloadName}
                          </a>
                        </span>
                      )}
                    </span>
                  );
                })()}
              </Field>
              <Field label="Audio Preview">
                {normalizeFileUrl(files.preview_url) ? (
                  <div className="space-y-1">
                    <audio controls src={normalizeFileUrl(files.preview_url)} className="h-8" />
                    <a
                      href={normalizeFileUrl(files.preview_url)}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="underline text-xs"
                      style={{ color: "var(--accent)" }}
                    >
                      Download preview
                    </a>
                  </div>
                ) : (
                  <span style={{ color: "var(--text-muted)" }}>Not uploaded</span>
                )}
              </Field>
            </dl>
          </section>
        </div>
      </div>

      {/* Firmware Code section — only shown if a built melody with PROGMEM code is assigned */}
      {builtMelody?.progmem_code && (
        <section
          className="ui-section-card mt-6"
        >
          <div className="ui-section-card__title-row">
            <div>
              <h2 className="ui-section-card__title">Firmware Code</h2>
              <p className="text-xs mt-0.5" style={{ color: "var(--text-muted)" }}>
                PROGMEM code for built-in firmware playback &nbsp;·&nbsp; PID: <span className="font-mono">{builtMelody.pid}</span>
              </p>
            </div>
            <button
              onClick={() => copyText(builtMelody.progmem_code, () => { setCodeCopied(true); setTimeout(() => setCodeCopied(false), 2000); })}
              className="px-3 py-1.5 text-xs rounded transition-colors"
              style={{
                backgroundColor: codeCopied ? "var(--success-bg)" : "var(--bg-card-hover)",
                color: codeCopied ? "var(--success-text)" : "var(--text-secondary)",
                border: "1px solid var(--border-primary)",
              }}
            >
              {codeCopied ? "Copied!" : "Copy Code"}
            </button>
          </div>
          <pre
            className="p-4 text-xs overflow-x-auto rounded-lg"
            style={{
              backgroundColor: "var(--bg-primary)",
              color: "var(--text-primary)",
              fontFamily: "monospace",
              whiteSpace: "pre",
              maxHeight: "360px",
              overflowY: "auto",
              border: "1px solid var(--border-primary)",
            }}
          >
            {builtMelody.progmem_code}
          </pre>
        </section>
      )}

      {/* Metadata section */}
      {melody.metadata && (
        <section
          className="ui-section-card mt-6"
        >
          <div className="ui-section-card__title-row">
            <h2 className="ui-section-card__title">History</h2>
          </div>
          <dl className="grid grid-cols-2 md:grid-cols-4 gap-4">
            {melody.metadata.dateCreated && (
              <Field label="Date Created">
                {new Date(melody.metadata.dateCreated).toLocaleString()}
              </Field>
            )}
            {melody.metadata.createdBy && (
              <Field label="Created By">{melody.metadata.createdBy}</Field>
            )}
            {melody.metadata.dateEdited && (
              <Field label="Last Edited">
                {new Date(melody.metadata.dateEdited).toLocaleString()}
              </Field>
            )}
            {melody.metadata.lastEditedBy && (
              <Field label="Last Edited By">{melody.metadata.lastEditedBy}</Field>
            )}
          </dl>
        </section>
      )}

      {/* Admin Notes section */}
      <section
        className="ui-section-card mt-6"
      >
        <div className="ui-section-card__title-row">
          <h2 className="ui-section-card__title">Admin Notes</h2>
        </div>
        {(melody.metadata?.adminNotes?.length || 0) > 0 ? (
          <div className="space-y-2">
            {melody.metadata.adminNotes.map((note, i) => (
              <div
                key={i}
                className="rounded-lg p-3 border text-sm"
                style={{ borderColor: "var(--border-primary)", backgroundColor: "var(--bg-primary)", color: "var(--text-primary)" }}
              >
                {note}
              </div>
            ))}
          </div>
        ) : (
          <p className="text-sm" style={{ color: "var(--text-muted)" }}>No admin notes yet. Edit this melody to add notes.</p>
        )}
      </section>

      <PlaybackModal
        open={showPlayback}
        melody={melody}
        builtMelody={builtMelody}
        files={files}
        archetypeCsv={melody?.information?.archetype_csv || null}
        onClose={() => setShowPlayback(false)}
      />
      <BinaryTableModal
        open={showBinaryView}
        melody={melody}
        builtMelody={builtMelody}
        files={files}
        archetypeCsv={melody?.information?.archetype_csv || null}
        onClose={() => setShowBinaryView(false)}
      />

      <SpeedCalculatorModal
        open={showSpeedCalc}
        melody={melody}
        builtMelody={builtMelody}
        archetypeCsv={melody?.information?.archetype_csv || null}
        onClose={() => setShowSpeedCalc(false)}
        onSaved={() => {
          setShowSpeedCalc(false);
          loadData();
        }}
      />

      <ConfirmDialog
        open={showDelete}
        title="Delete Melody"
        message={`Are you sure you want to delete "${displayName}"? This will also delete any uploaded files. This action cannot be undone.`}
        onConfirm={handleDelete}
        onCancel={() => setShowDelete(false)}
      />

      <ConfirmDialog
        open={showUnpublish}
        title="Unpublish Melody"
        message={`This melody may be in use by devices. Unpublishing will remove it from Firestore and devices will no longer have access to "${displayName}". The melody will be kept as a draft. Continue?`}
        onConfirm={handleUnpublish}
        onCancel={() => setShowUnpublish(false)}
      />
    </div>
  );
}




