import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import api from "../api/client";

const MAX_NOTES = 16;
const NOTE_LABELS = "ABCDEFGHIJKLMNOP";

function bellFrequency(bellNumber) {
  // One octave every 8 notes.
  return 880 * Math.pow(2, -((bellNumber - 1) / 8));
}

function stepToNotation(stepValue) {
  if (!stepValue) return "0";
  const active = [];
  for (let bit = 0; bit < 16; bit++) {
    if (stepValue & (1 << bit)) active.push(bit + 1);
  }
  return active.join("+");
}

function stepToHex(stepValue) {
  return `0x${(stepValue >>> 0).toString(16).toUpperCase().padStart(4, "0")}`;
}

function msToBpm(ms) {
  return Math.max(1, Math.round(60000 / Math.max(1, Number(ms) || 1)));
}

function bpmToMs(bpm) {
  return Math.max(20, Math.round(60000 / Math.max(1, Number(bpm) || 1)));
}

function interpolateHue(t) {
  const stops = [
    [0.0, 190],
    [0.24, 140],
    [0.5, 56],
    [0.82, 30],
    [1.0, 0],
  ];
  for (let i = 0; i < stops.length - 1; i++) {
    const [aPos, aHue] = stops[i];
    const [bPos, bHue] = stops[i + 1];
    if (t >= aPos && t <= bPos) {
      const local = (t - aPos) / (bPos - aPos || 1);
      return aHue + (bHue - aHue) * local;
    }
  }
  return stops[stops.length - 1][1];
}

function noteDotColor(noteNumber) {
  const n = Number(noteNumber || 1);
  const t = Math.min(1, Math.max(0, (n - 1) / 15));
  const hue = interpolateHue(t);
  return `hsl(${hue}, 78%, 68%)`;
}

function noteDotGlow(noteNumber) {
  const n = Number(noteNumber || 1);
  const t = Math.min(1, Math.max(0, (n - 1) / 15));
  const hue = interpolateHue(t);
  return `hsla(${hue}, 78%, 56%, 0.45)`;
}

function noteDotColorFromSettings(noteNumber, colorPalette) {
  const n = Number(noteNumber || 1);
  const custom = colorPalette?.[n - 1];
  return custom || noteDotColor(n);
}

function noteDotGlowFromSettings(noteNumber, colorPalette) {
  const n = Number(noteNumber || 1);
  const custom = colorPalette?.[n - 1];
  return custom ? `${custom}66` : noteDotGlow(n);
}

function playStep(audioCtx, stepValue, noteDurationMs) {
  if (!audioCtx) return;

  const now = audioCtx.currentTime;
  const duration = Math.max(10, noteDurationMs) / 1000;
  const fadeIn = 0.005;
  const fadeOut = Math.min(0.03, duration / 2);

  for (let bit = 0; bit < 16; bit++) {
    if (stepValue & (1 << bit)) {
      const freq = bellFrequency(bit + 1);
      const osc = audioCtx.createOscillator();
      const gain = audioCtx.createGain();

      osc.type = "sine";
      osc.frequency.setValueAtTime(freq, now);
      gain.gain.setValueAtTime(0, now);
      gain.gain.linearRampToValueAtTime(0.3, now + fadeIn);
      gain.gain.setValueAtTime(0.3, now + Math.max(duration - fadeOut, fadeIn + 0.001));
      gain.gain.linearRampToValueAtTime(0, now + duration);

      osc.connect(gain);
      gain.connect(audioCtx.destination);

      osc.start(now);
      osc.stop(now + duration);
    }
  }
}

function csvToSteps(csv) {
  if (!csv || !csv.trim()) return null;
  return csv.trim().split(",").map((token) => {
    const parts = token.split("+");
    let val = 0;
    for (const p of parts) {
      const n = parseInt(p.trim(), 10);
      if (!isNaN(n) && n >= 1 && n <= 16) val |= (1 << (n - 1));
    }
    return val;
  });
}

export default function MelodyComposer() {
  const navigate = useNavigate();
  const { state: routeState } = useLocation();
  const loadedArchetype = routeState?.archetype || null;

  const initialSteps = () => {
    if (loadedArchetype?.steps) {
      const parsed = csvToSteps(loadedArchetype.steps);
      if (parsed?.length) return parsed;
    }
    return Array.from({ length: 16 }, () => 0);
  };

  const [steps, setSteps] = useState(initialSteps);
  const [noteCount, setNoteCount] = useState(() => {
    if (loadedArchetype?.steps) {
      const parsed = csvToSteps(loadedArchetype.steps);
      if (parsed?.length) {
        let maxBit = 0;
        for (const v of parsed) {
          for (let b = 15; b >= 0; b--) {
            if (v & (1 << b)) { maxBit = Math.max(maxBit, b + 1); break; }
          }
        }
        return Math.max(8, maxBit);
      }
    }
    return 8;
  });
  const [stepDelayMs, setStepDelayMs] = useState(280);
  const [noteDurationMs, setNoteDurationMs] = useState(110);
  const [measureEvery, setMeasureEvery] = useState(4);
  const [loopEnabled, setLoopEnabled] = useState(true);
  const [isPlaying, setIsPlaying] = useState(false);
  const [currentStep, setCurrentStep] = useState(-1);
  const [error, setError] = useState("");
  const [successMsg, setSuccessMsg] = useState("");
  const [showDeployModal, setShowDeployModal] = useState(false);
  const [deployName, setDeployName] = useState("");
  const [deployPid, setDeployPid] = useState("");
  const [deployError, setDeployError] = useState("");
  const [deploying, setDeploying] = useState(false);
  const [deployMode, setDeployMode] = useState("new"); // "new" | "update"
  const [noteColors, setNoteColors] = useState([]);
  const [stepMenuIndex, setStepMenuIndex] = useState(null);

  const audioCtxRef = useRef(null);
  const playbackRef = useRef(null);
  const stepsRef = useRef(steps);
  const stepDelayRef = useRef(stepDelayMs);
  const noteDurationRef = useRef(noteDurationMs);
  const loopEnabledRef = useRef(loopEnabled);
  const stepMenuRef = useRef(null);

  useEffect(() => {
    stepsRef.current = steps;
  }, [steps]);

  useEffect(() => {
    stepDelayRef.current = stepDelayMs;
  }, [stepDelayMs]);

  useEffect(() => {
    noteDurationRef.current = noteDurationMs;
  }, [noteDurationMs]);

  useEffect(() => {
    loopEnabledRef.current = loopEnabled;
  }, [loopEnabled]);
  useEffect(() => {
    if (stepMenuIndex == null) return undefined;
    const onDocClick = (e) => {
      if (stepMenuRef.current && !stepMenuRef.current.contains(e.target)) {
        setStepMenuIndex(null);
      }
    };
    document.addEventListener("mousedown", onDocClick);
    return () => document.removeEventListener("mousedown", onDocClick);
  }, [stepMenuIndex]);

  const ensureAudioContext = useCallback(() => {
    if (!audioCtxRef.current || audioCtxRef.current.state === "closed") {
      audioCtxRef.current = new (window.AudioContext || window.webkitAudioContext)();
    }
    if (audioCtxRef.current.state === "suspended") {
      audioCtxRef.current.resume();
    }
    return audioCtxRef.current;
  }, []);

  const stopPlayback = useCallback(() => {
    if (playbackRef.current?.timer) {
      clearTimeout(playbackRef.current.timer);
    }
    playbackRef.current = null;
    setIsPlaying(false);
    setCurrentStep(-1);
  }, []);

  const scheduleStep = useCallback((stepIndex) => {
    const currentSteps = stepsRef.current;
    if (!currentSteps.length) {
      stopPlayback();
      return;
    }

    const ctx = ensureAudioContext();
    const nextIndex = stepIndex % currentSteps.length;
    const stepValue = currentSteps[nextIndex];

    setCurrentStep(nextIndex);
    playStep(ctx, stepValue, noteDurationRef.current);

    const isLastStep = nextIndex >= currentSteps.length - 1;
    const shouldContinue = !isLastStep || loopEnabledRef.current;

    if (!shouldContinue) {
      playbackRef.current = {
        timer: setTimeout(() => stopPlayback(), stepDelayRef.current),
      };
      return;
    }

    playbackRef.current = {
      timer: setTimeout(() => {
        scheduleStep(isLastStep ? 0 : nextIndex + 1);
      }, stepDelayRef.current),
    };
  }, [ensureAudioContext, stopPlayback]);

  useEffect(() => {
    return () => {
      stopPlayback();
    };
  }, [stopPlayback]);

  useEffect(() => {
    let canceled = false;
    api.get("/settings/melody")
      .then((s) => {
        if (canceled) return;
        setNoteColors((s?.note_assignment_colors || []).slice(0, 16));
      })
      .catch(() => {
        if (!canceled) setNoteColors([]);
      });
    return () => { canceled = true; };
  }, []);

  const toggleCell = (noteIndex, stepIndex) => {
    const bit = 1 << noteIndex;
    setSteps((prev) => {
      const next = [...prev];
      next[stepIndex] = (next[stepIndex] || 0) ^ bit;
      return next;
    });
  };

  const addStep = () => setSteps((prev) => [...prev, 0]);
  const removeStep = () => {
    setSteps((prev) => {
      if (prev.length <= 1) return prev;
      const next = prev.slice(0, prev.length - 1);
      if (currentStep >= next.length) setCurrentStep(next.length - 1);
      return next;
    });
  };

  const addNote = () => setNoteCount((prev) => Math.min(MAX_NOTES, prev + 1));
  const removeNote = () => {
    setNoteCount((prev) => {
      if (prev <= 1) return prev;
      const nextCount = prev - 1;
      const removedBitMask = ~((1 << nextCount) - 1);
      setSteps((currentSteps) => currentSteps.map((value) => value & ~removedBitMask));
      return nextCount;
    });
  };

  const clearAll = () => setSteps((prev) => prev.map(() => 0));
  const insertStepAt = (index) => {
    setSteps((prev) => {
      const next = [...prev];
      next.splice(index, 0, 0);
      return next;
    });
    setCurrentStep((prev) => (prev >= index ? prev + 1 : prev));
  };
  const deleteStepAt = (index) => {
    setSteps((prev) => {
      if (prev.length <= 1) return prev;
      const next = [...prev];
      next.splice(index, 1);
      return next;
    });
    setCurrentStep((prev) => {
      if (prev < 0) return prev;
      if (prev === index) return -1;
      if (prev > index) return prev - 1;
      return prev;
    });
  };

  const handlePlay = () => {
    if (!stepsRef.current.length) return;
    setError("");
    setIsPlaying(true);
    scheduleStep(0);
  };

  const openDeployModal = (mode = "new") => {
    setError("");
    setSuccessMsg("");
    setDeployError("");
    setDeployMode(mode);
    if (mode === "update" && loadedArchetype) {
      setDeployName(loadedArchetype.name || "");
      setDeployPid(loadedArchetype.pid || "");
    } else {
      setDeployName("");
      setDeployPid("");
    }
    setShowDeployModal(true);
  };

  const closeDeployModal = () => {
    if (deploying) return;
    setDeployError("");
    setShowDeployModal(false);
  };

  const handleDeploy = async () => {
    const name = deployName.trim();
    const pid = deployPid.trim();
    if (!name) { setDeployError("Name is required."); return; }
    if (!pid) { setDeployError("PID is required."); return; }

    setDeploying(true);
    setDeployError("");
    setSuccessMsg("");
    try {
      const stepsStr = steps.map(stepToNotation).join(",");

      if (deployMode === "update" && loadedArchetype?.id) {
        const updated = await api.put(`/builder/melodies/${loadedArchetype.id}`, { name, pid, steps: stepsStr });
        setSuccessMsg(`Archetype "${name}" updated successfully.`);
        setShowDeployModal(false);
        if (updated?.id) navigate(`/melodies/archetypes/${updated.id}`);
      } else {
        const existing = await api.get("/builder/melodies");
        const list = existing.melodies || [];
        const dupName = list.find((m) => m.name.toLowerCase() === name.toLowerCase());
        if (dupName) { setDeployError(`An archetype with the name "${name}" already exists.`); return; }
        const dupPid = list.find((m) => m.pid && m.pid.toLowerCase() === pid.toLowerCase());
        if (dupPid) { setDeployError(`An archetype with the PID "${pid}" already exists.`); return; }

        const created = await api.post("/builder/melodies", { name, pid, steps: stepsStr });
        setSuccessMsg(`Archetype "${name}" deployed successfully.`);
        setShowDeployModal(false);
        setDeployName("");
        setDeployPid("");
        if (created?.id) navigate(`/melodies/archetypes/${created.id}`);
      }
    } catch (err) {
      setDeployError(err.message);
    } finally {
      setDeploying(false);
    }
  };

  const activeBellsInCurrentStep = useMemo(() => {
    if (currentStep < 0 || !steps[currentStep]) return [];
    const active = [];
    for (let bit = 0; bit < noteCount; bit++) {
      if (steps[currentStep] & (1 << bit)) active.push(bit + 1);
    }
    return active;
  }, [currentStep, noteCount, steps]);
  const speedBpm = msToBpm(stepDelayMs);
  const measureSliderValue = Math.max(1, Math.min(16, Number(measureEvery) || 1));

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-bold" style={{ color: "var(--text-heading)" }}>
          Melody Composer
        </h1>
        <p className="text-sm mt-1" style={{ color: "var(--text-muted)" }}>
          Build bell-step melodies visually. Notes map directly to bell numbers (1-16).
        </p>
      </div>

      {loadedArchetype && (
        <div className="rounded-lg border px-4 py-3 flex items-center gap-3"
          style={{ backgroundColor: "rgba(139,92,246,0.08)", borderColor: "rgba(139,92,246,0.3)" }}>
          <span className="text-xs font-semibold uppercase tracking-wide" style={{ color: "#a78bfa" }}>Editing Archetype</span>
          <span className="text-sm font-medium" style={{ color: "var(--text-heading)" }}>{loadedArchetype.name}</span>
          <span className="text-xs" style={{ color: "var(--text-muted)" }}>·</span>
          <span className="text-xs font-mono" style={{ color: "var(--text-muted)" }}>{loadedArchetype.id}</span>
          <button
            type="button"
            onClick={() => navigate("/melodies/composer", { replace: true, state: null })}
            className="ml-auto text-xs px-2 py-1 rounded"
            style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-muted)", border: "1px solid var(--border-primary)" }}
          >
            Clear
          </button>
        </div>
      )}

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

      <section className="ui-section-card">
        <div className="flex flex-wrap items-center gap-2">
          <button type="button" onClick={addStep} className="px-3 py-1.5 text-sm rounded-md" style={{ backgroundColor: "var(--btn-primary)", color: "var(--text-white)" }}>+ Step</button>
          <button type="button" onClick={removeStep} className="px-3 py-1.5 text-sm rounded-md" style={{ backgroundColor: "var(--btn-neutral)", color: "var(--text-white)" }}>- Step</button>
          <span className="mx-1 text-sm" style={{ color: "var(--border-primary)" }}>|</span>
          <button type="button" onClick={addNote} disabled={noteCount >= MAX_NOTES} className="px-3 py-1.5 text-sm rounded-md disabled:opacity-50" style={{ backgroundColor: "var(--btn-primary)", color: "var(--text-white)" }}>+ Note</button>
          <button type="button" onClick={removeNote} disabled={noteCount <= 1} className="px-3 py-1.5 text-sm rounded-md disabled:opacity-50" style={{ backgroundColor: "var(--btn-neutral)", color: "var(--text-white)" }}>- Note</button>
          <span className="mx-1 text-sm" style={{ color: "var(--border-primary)" }}>|</span>
          <button type="button" onClick={clearAll} className="px-3 py-1.5 text-sm rounded-md" style={{ backgroundColor: "var(--danger-btn)", color: "var(--text-white)" }}>Clear</button>
          <div className="ml-auto flex items-center gap-3">
            <div className="text-xs inline-flex items-center gap-2" style={{ color: "var(--text-muted)" }}>
              {currentStep >= 0 && (
                <>
                  <span>
                    Playing step {currentStep + 1}/{steps.length}
                    {activeBellsInCurrentStep.length ? ` (bells: ${activeBellsInCurrentStep.join(", ")})` : " (silence)"}
                  </span>
                  <span style={{ color: "var(--border-primary)" }}>|</span>
                </>
              )}
              <span>{steps.length} steps, {noteCount} notes</span>
            </div>
            {loadedArchetype ? (
              <>
                <button type="button" onClick={() => openDeployModal("new")} className="px-3 py-1.5 rounded-md text-sm whitespace-nowrap" style={{ backgroundColor: "var(--btn-neutral)", color: "var(--text-white)" }}>Deploy as New Archetype</button>
                <button type="button" onClick={() => openDeployModal("update")} className="px-3 py-1.5 rounded-md text-sm whitespace-nowrap" style={{ backgroundColor: "var(--text-link)", color: "var(--text-white)" }}>Update Current Archetype</button>
              </>
            ) : (
              <button type="button" onClick={() => openDeployModal("new")} className="px-3 py-1.5 rounded-md text-sm whitespace-nowrap" style={{ backgroundColor: "var(--text-link)", color: "var(--text-white)" }}>Deploy Archetype</button>
            )}
          </div>
        </div>

        <div className="mt-4 pt-4 border-t" style={{ borderColor: "var(--border-primary)" }}>
          <div className="flex flex-wrap lg:flex-nowrap items-end gap-4">
            <div className="flex items-center gap-2">
              {!isPlaying ? (
                <button type="button" onClick={handlePlay} className="w-24 px-4 py-2 rounded-md text-sm" style={{ backgroundColor: "var(--btn-primary)", color: "var(--text-white)" }}>Play</button>
              ) : (
                <button type="button" onClick={stopPlayback} className="w-24 px-4 py-2 rounded-md text-sm" style={{ backgroundColor: "var(--danger-btn)", color: "var(--text-white)" }}>Stop</button>
              )}
              <button
                type="button"
                onClick={() => setLoopEnabled((v) => !v)}
                className="px-4 py-2 rounded-md text-sm inline-flex items-center gap-2"
                style={{
                  backgroundColor: loopEnabled ? "rgba(34,197,94,0.2)" : "var(--bg-card-hover)",
                  color: loopEnabled ? "#22c55e" : "var(--text-secondary)",
                  border: "1px solid var(--border-primary)",
                }}
              >
                <span>Loop</span>
                <span className="inline-block w-2.5 h-2.5 rounded-full" style={{ backgroundColor: loopEnabled ? "#22c55e" : "var(--text-muted)" }} />
              </button>
              <span className="mx-1 text-sm" style={{ color: "var(--border-primary)" }}>|</span>
            </div>

            <div className="flex-1 min-w-0 grid grid-cols-1 sm:grid-cols-5 gap-5 items-end">
              <div className="sm:col-span-2 min-w-0">
                <div className="flex items-center justify-between">
                  <label className="text-sm font-medium" style={{ color: "var(--text-secondary)" }}>Speed in BPM</label>
                  <span className="text-sm inline-flex items-baseline gap-2">
                    <span style={{ color: "var(--text-muted)", fontSize: "11px" }}>{stepDelayMs} ms</span>
                    <span style={{ color: "var(--accent)", fontWeight: 600 }}>{speedBpm} bpm</span>
                  </span>
                </div>
                <input type="range" min="30" max="1500" step="1" value={speedBpm} onChange={(e) => setStepDelayMs(bpmToMs(Number(e.target.value)))} className="w-full mt-2" />
              </div>

              <div className="sm:col-span-2 min-w-0">
                <div className="flex items-center justify-between">
                  <label className="text-sm font-medium" style={{ color: "var(--text-secondary)" }}>Note Duration</label>
                  <span className="text-sm font-semibold" style={{ color: "var(--accent)" }}>{noteDurationMs} ms</span>
                </div>
                <input type="range" min="20" max="500" step="10" value={noteDurationMs} onChange={(e) => setNoteDurationMs(Number(e.target.value))} className="w-full mt-2" />
              </div>

              <div className="sm:col-span-1 min-w-0">
                <div className="flex items-center justify-between">
                  <label className="text-sm font-medium" style={{ color: "var(--text-secondary)" }}>Measure</label>
                  <span className="text-sm font-semibold" style={{ color: "var(--accent)" }}>{measureEvery}</span>
                </div>
                <input type="range" min="1" max="16" step="1" value={measureSliderValue} onChange={(e) => setMeasureEvery(Number(e.target.value))} className="w-full mt-2" />
              </div>
            </div>
          </div>
        </div>
      </section>

      <section className="ui-section-card">
        <div className="overflow-x-auto">
          <table className="min-w-max border-separate border-spacing-0">
            <thead>
              <tr>
                <th
                  className="sticky top-0 left-0 z-30 px-3 py-2 text-xs font-semibold border-b border-r"
                  style={{ backgroundColor: "var(--bg-secondary)", borderColor: "var(--border-primary)", color: "var(--text-secondary)" }}
                >
                  Note \\ Step
                </th>
                {steps.map((_, stepIndex) => {
                  const isCurrent = stepIndex === currentStep;
                  const measureHit = measureEvery > 0 && (stepIndex + 1) % measureEvery === 0;
                  const measureBlockOdd = measureEvery > 0 && Math.floor(stepIndex / measureEvery) % 2 === 1;
                  return (
                    <th
                      key={stepIndex}
                      className="sticky top-0 z-20 px-1 py-1 text-xs font-semibold border-b border-r relative"
                      style={{
                        minWidth: "44px",
                        backgroundColor: isCurrent
                          ? "rgba(116,184,22,0.24)"
                          : (measureBlockOdd ? "rgba(255,255,255,0.02)" : "var(--bg-secondary)"),
                        borderColor: measureHit ? "rgba(255,255,255,0.38)" : "var(--border-primary)",
                        borderRightWidth: measureHit ? "2px" : "1px",
                        color: isCurrent ? "var(--accent)" : "var(--text-secondary)",
                      }}
                    >
                      <button
                        type="button"
                        className="w-full px-1 py-1"
                        style={{ background: "transparent", border: "none", color: "inherit" }}
                        onClick={(e) => {
                          e.stopPropagation();
                          setStepMenuIndex((prev) => (prev === stepIndex ? null : stepIndex));
                        }}
                      >
                        {stepIndex + 1}
                      </button>
                      {stepMenuIndex === stepIndex && (
                        <div
                          ref={stepMenuRef}
                          className="absolute right-0 top-full mt-1 w-28 rounded-md border shadow-lg z-50"
                          style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-primary)" }}
                        >
                          <button
                            type="button"
                            className="w-full text-left px-2 py-1.5 text-xs"
                            style={{ color: "var(--text-primary)", background: "transparent", border: "none" }}
                            onClick={() => { insertStepAt(stepIndex + 1); setStepMenuIndex(null); }}
                          >
                            Add After
                          </button>
                          <button
                            type="button"
                            className="w-full text-left px-2 py-1.5 text-xs"
                            style={{ color: "var(--text-primary)", background: "transparent", border: "none" }}
                            onClick={() => { insertStepAt(stepIndex); setStepMenuIndex(null); }}
                          >
                            Add Before
                          </button>
                          <button
                            type="button"
                            className="w-full text-left px-2 py-1.5 text-xs"
                            style={{ color: "var(--danger)", background: "transparent", border: "none" }}
                            onClick={() => { deleteStepAt(stepIndex); setStepMenuIndex(null); }}
                          >
                            Delete
                          </button>
                        </div>
                      )}
                    </th>
                  );
                })}
              </tr>
            </thead>
            <tbody>
              {Array.from({ length: noteCount }, (_, noteIndex) => (
                <tr key={noteIndex}>
                  <th
                    className="sticky left-0 z-10 px-3 py-2 text-xs font-medium border-b border-r"
                    style={{
                      backgroundColor: "var(--bg-secondary)",
                      borderColor: "var(--border-primary)",
                      color: "var(--text-secondary)",
                    }}
                  >
                    {NOTE_LABELS[noteIndex]}
                  </th>
                  {steps.map((stepValue, stepIndex) => {
                    const enabled = Boolean(stepValue & (1 << noteIndex));
                    const isCurrent = stepIndex === currentStep;
                    const measureHit = measureEvery > 0 && (stepIndex + 1) % measureEvery === 0;
                    const measureBlockOdd = measureEvery > 0 && Math.floor(stepIndex / measureEvery) % 2 === 1;
                    return (
                      <td
                        key={`${noteIndex}-${stepIndex}`}
                        className="border-b border-r"
                        style={{
                          borderColor: measureHit ? "rgba(255,255,255,0.34)" : "var(--border-primary)",
                          borderRightWidth: measureHit ? "2px" : "1px",
                          backgroundColor: isCurrent
                            ? "rgba(116,184,22,0.08)"
                            : (measureBlockOdd ? "rgba(255,255,255,0.015)" : "transparent"),
                          width: "44px",
                          height: "44px",
                        }}
                      >
                        <button
                          type="button"
                          aria-label={`Toggle note ${noteIndex + 1} on step ${stepIndex + 1}`}
                          aria-pressed={enabled}
                          onClick={() => toggleCell(noteIndex, stepIndex)}
                          className="w-full h-full flex items-center justify-center transition-colors"
                          style={{
                            backgroundColor: "transparent",
                            border: "none",
                            outline: "none",
                          }}
                        >
                          <span
                            aria-hidden="true"
                            style={{
                              width: "54%",
                              height: "54%",
                              borderRadius: "9999px",
                              backgroundColor: noteDotColorFromSettings(noteIndex + 1, noteColors),
                              opacity: enabled ? 1 : 0,
                              transform: enabled ? "scale(1)" : "scale(0.4)",
                              boxShadow: enabled ? `0 0 10px 3px ${noteDotGlowFromSettings(noteIndex + 1, noteColors)}` : "none",
                              transition: "opacity 140ms ease, transform 140ms ease, box-shadow 180ms ease",
                            }}
                          />
                        </button>
                      </td>
                    );
                  })}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </section>

      <section className="ui-section-card">
        <div className="grid grid-cols-1 xl:grid-cols-2 gap-4">
          <div>
            <p className="text-xs mb-1" style={{ color: "var(--text-muted)" }}>Generated CSV notation</p>
            <pre
              className="rounded-md p-3 text-xs overflow-auto"
              style={{ backgroundColor: "var(--bg-primary)", border: "1px solid var(--border-primary)", color: "var(--text-primary)" }}
            >
{`{${steps.map(stepToNotation).join(",")}}`}
            </pre>
          </div>
          <div>
            <p className="text-xs mb-1" style={{ color: "var(--text-muted)" }}>Generated PROGMEM Values</p>
            <pre
              className="rounded-md p-3 text-xs overflow-auto"
              style={{ backgroundColor: "var(--bg-primary)", border: "1px solid var(--border-primary)", color: "var(--text-primary)" }}
            >
{`const uint16_t PROGMEM melody_builtin_custom[] = {\n  ${steps.map(stepToHex).join(", ")}\n};`}
            </pre>
          </div>
        </div>
      </section>

      {showDeployModal && (
        <div
          className="fixed inset-0 flex items-center justify-center z-50"
          style={{ backgroundColor: "rgba(0,0,0,0.7)" }}
          onClick={(e) => e.target === e.currentTarget && closeDeployModal()}
        >
          <div
            className="w-full max-w-md rounded-lg border shadow-xl"
            style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-primary)" }}
          >
            <div
              className="flex items-center justify-between px-6 py-4 border-b"
              style={{ borderColor: "var(--border-primary)" }}
            >
              <div>
                <h2 className="text-lg font-semibold" style={{ color: "var(--text-heading)" }}>
                  {deployMode === "update" ? "Update Archetype" : "Deploy Archetype"}
                </h2>
                <p className="text-xs mt-0.5" style={{ color: "var(--text-muted)" }}>
                  {deployMode === "update"
                    ? "Rebuild the existing archetype with the current composer pattern."
                    : "Create a new archetype from this composer pattern."}
                </p>
              </div>
              <button
                type="button"
                onClick={closeDeployModal}
                className="text-xl leading-none"
                style={{ color: "var(--text-muted)" }}
                disabled={deploying}
              >
                &times;
              </button>
            </div>

            <div className="px-6 py-5 space-y-4">
              {deployError && (
                <div
                  className="text-sm rounded-md p-3 border"
                  style={{
                    backgroundColor: "var(--danger-bg)",
                    borderColor: "var(--danger)",
                    color: "var(--danger-text)",
                  }}
                >
                  {deployError}
                </div>
              )}
              <div>
                <label className="block text-sm font-medium mb-1" style={{ color: "var(--text-secondary)" }}>
                  Name *
                </label>
                <input
                  type="text"
                  value={deployName}
                  onChange={(e) => setDeployName(e.target.value)}
                  className="w-full px-3 py-2 rounded-md text-sm border"
                  placeholder="e.g. Doksologia_3k"
                  disabled={deploying}
                />
              </div>
              <div>
                <label className="block text-sm font-medium mb-1" style={{ color: "var(--text-secondary)" }}>
                  PID *
                </label>
                <input
                  type="text"
                  value={deployPid}
                  onChange={(e) => setDeployPid(e.target.value)}
                  className="w-full px-3 py-2 rounded-md text-sm border"
                  placeholder="e.g. builtin_doksologia_3k"
                  disabled={deploying}
                />
              </div>
            </div>

            <div
              className="flex justify-end gap-2 px-6 py-4 border-t"
              style={{ borderColor: "var(--border-primary)" }}
            >
              <button
                type="button"
                onClick={closeDeployModal}
                className="px-4 py-2 text-sm rounded-md transition-colors"
                style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-primary)" }}
                disabled={deploying}
              >
                Cancel
              </button>
              <button
                type="button"
                onClick={handleDeploy}
                className="px-4 py-2 text-sm rounded-md transition-colors disabled:opacity-50"
                style={{ backgroundColor: "var(--btn-primary)", color: "var(--text-white)" }}
                disabled={deploying}
              >
                {deploying ? (deployMode === "update" ? "Updating..." : "Deploying...") : (deployMode === "update" ? "Update" : "Deploy")}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
