import { useState, useEffect, useRef, useCallback } from "react";

// ── Design tokens (mirrored) ──────────────────────────────────
const T = {
  bg: "#0A0A0C", panel: "#141418", surface: "#1C1C22", border: "#2A2A32",
  amber: "#E8A030", amberDim: "#7A5218", blue: "#3A7BA8",
  green: "#3AB87A", red: "#C84040", textPrimary: "#F0EDE6",
  textSec: "#8888A0", textDim: "#444458",
};

// ── String labels matching _STRING_NAMES ──────────────────────
const STRING_LABELS = [
  { num: 6, name: "E", freq: 82.41, color: "#C84040" },    // Low E
  { num: 5, name: "A", freq: 110.0, color: "#D07030" },    // A
  { num: 4, name: "D", freq: 146.83, color: "#E8A030" },   // D
  { num: 3, name: "G", freq: 196.0, color: "#60A0E0" },    // G
  { num: 2, name: "B", freq: 246.94, color: "#3A7BA8" },   // B
  { num: 1, name: "e", freq: 329.63, color: "#50C080" },   // High e
];

// ── Note names for reference ─────────────────────────────────
const NOTE_FLAT = ["C","Db","D","Eb","E","F","Gb","G","Ab","A","Bb","B"];

// ── Mock tuner data generator (when pedal offline) ───────────
const MOCK_NOTES = [
  { note: "E2", freq: 82.41 }, { note: "F2", freq: 87.31 },
  { note: "G2", freq: 98.0 },  { note: "A2", freq: 110.0 },
  { note: "B2", freq: 123.47 }, { note: "C3", freq: 130.81 },
  { note: "D3", freq: 146.83 }, { note: "E3", freq: 164.81 },
  { note: "F3", freq: 174.61 }, { note: "G3", freq: 196.0 },
  { note: "A3", freq: 220.0 }, { note: "B3", freq: 246.94 },
  { note: "C4", freq: 261.63 }, { note: "D4", freq: 293.66 },
  { note: "E4", freq: 329.63 },
];

function getMockTunerData() {
  // Simulate a slowly wandering note
  const t = Date.now() / 1000;
  const idx = Math.floor((t * 0.3) % MOCK_NOTES.length);
  const n = MOCK_NOTES[idx];
  const wobble = Math.sin(t * 2.5) * 15;  // cent wobble
  const confidence = 0.6 + Math.sin(t * 0.7) * 0.25;
  // Guess string
  let string = -1;
  for (let si = 0; si < STRING_LABELS.length; si++) {
    if (Math.abs(n.freq - STRING_LABELS[si].freq) / STRING_LABELS[si].freq < 0.2) {
      string = STRING_LABELS[si].num;
      break;
    }
  }
  return {
    note: n.note,
    cents: Math.round(wobble),
    string,
    confidence: Math.max(0, Math.min(1, confidence)),
    frequency: n.freq + wobble / 10,
  };
}

// ── Tuner Screen ──────────────────────────────────────────────
export default function TunerScreen({ tunerData, connected, onExit }) {
  const [data, setData] = useState(() => ({
    note: "--",
    cents: 0,
    string: -1,
    confidence: 0,
    frequency: 0,
  }));

  // Fast update from external data or mock
  useEffect(() => {
    if (connected && tunerData) {
      setData({
        note: tunerData.tuner_note || "--",
        cents: tunerData.tuner_cents ?? 0,
        string: tunerData.tuner_string ?? -1,
        confidence: tunerData.tuner_confidence ?? 0,
        frequency: tunerData.tuner_frequency ?? 0,
      });
    }
  }, [connected, tunerData]);

  // Mock animation when offline or no data
  useEffect(() => {
    if (connected && tunerData?.tuner_enabled) return;
    const id = setInterval(() => {
      setData(getMockTunerData());
    }, 200);
    return () => clearInterval(id);
  }, [connected, tunerData]);

  // Fast polling for tuner pitch data when enabled
  useEffect(() => {
    if (!connected) return;
    if (!tunerData?.tuner_enabled) return;
    let cancelled = false;
    const poll = async () => {
      try {
        const res = await fetch("/api/tuner/pitch");
        if (!cancelled && res.ok) {
          const d = await res.json();
          setData({
            note: d.note || "--",
            cents: d.cents ?? 0,
            string: d.string ?? -1,
            confidence: d.confidence ?? 0,
            frequency: d.frequency ?? 0,
          });
        }
      } catch {}
    };
    poll(); // Initial fetch
    const id = setInterval(poll, 80); // ~12.5 Hz for smooth needle
    return () => { cancelled = true; clearInterval(id); };
  }, [connected, tunerData?.tuner_enabled]);

  // ── Calculate needle angle from cents ──
  const cents = data.cents;
  const confidence = data.confidence;
  // Needle angle: -50 to +50 degrees for -50 to +50 cents
  const needleAngle = Math.max(-50, Math.min(50, cents));
  const needlePct = (needleAngle + 50) / 100; // 0.0 to 1.0
  const isInTune = Math.abs(cents) <= 3;
  const isClose = Math.abs(cents) <= 10;

  // ── String indicators ──
  const stringMatch = data.string;

  // ── Cent display segments ──
  const centSegments = [];
  for (let i = -50; i <= 50; i += 5) {
    centSegments.push(i);
  }

  // Determine note color (green = in tune, amber = close, red = far)
  const noteColor = isInTune
    ? T.green
    : isClose
      ? T.amber
      : T.textPrimary;

  return (
    <div style={{
      display: "flex",
      flexDirection: "column",
      height: "100%",
      background: T.bg,
      overflow: "hidden",
    }}>
      {/* ── Header ── */}
      <div style={{
        display: "flex",
        justifyContent: "space-between",
        alignItems: "center",
        padding: "6px 12px",
        background: T.panel,
        borderBottom: `1px solid ${T.border}`,
        flexShrink: 0,
      }}>
        <div style={{
          fontSize: 10,
          fontWeight: 700,
          letterSpacing: ".12em",
          textTransform: "uppercase",
          color: isInTune ? T.green : T.amber,
        }}>
          {isInTune ? "● In Tune" : "◌ Tuner"}
        </div>
        <button
          onClick={onExit}
          style={{
            padding: "6px 14px",
            borderRadius: 6,
            background: T.surface,
            border: `1px solid ${T.border}`,
            color: T.textPrimary,
            fontSize: 11,
            fontWeight: 600,
            cursor: "pointer",
          }}
        >
          ✕ Exit Tuner
        </button>
      </div>

      {/* ── Main tuner area ── */}
      <div style={{
        flex: 1,
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
        justifyContent: "center",
        gap: 6,
        padding: "8px 16px",
      }}>
        {/* Note name — very large */}
        <div style={{
          fontFamily: "'JetBrains Mono', monospace",
          fontSize: 72,
          fontWeight: 700,
          color: noteColor,
          textShadow: isInTune
            ? `0 0 30px ${T.green}44`
            : isClose
              ? `0 0 20px ${T.amber}33`
              : "none",
          lineHeight: 1,
          letterSpacing: ".02em",
          transition: "color .08s, text-shadow .08s",
          minHeight: 76,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
        }}>
          {data.note}
        </div>

        {/* Cent deviation — needle display */}
        <div style={{
          width: "100%",
          maxWidth: 320,
          height: 60,
          position: "relative",
          marginTop: 4,
        }}>
          {/* Cent tick marks */}
          <div style={{
            position: "absolute",
            bottom: 16,
            left: 0,
            right: 0,
            height: 16,
            display: "flex",
            alignItems: "flex-end",
            justifyContent: "space-between",
            padding: "0 10px",
          }}>
            {centSegments.map((c, i) => {
              const isMid = c === 0;
              const isMajor = c % 10 === 0;
              return (
                <div key={i} style={{
                  width: isMid ? 3 : (isMajor ? 2 : 1),
                  height: isMid ? 16 : (isMajor ? 10 : 5),
                  background: isMid ? T.amber : T.border,
                  borderRadius: 1,
                  flexShrink: 0,
                }} />
              );
            })}
          </div>

          {/* Cent labels */}
          <div style={{
            position: "absolute",
            bottom: 2,
            left: 0,
            right: 0,
            display: "flex",
            justifyContent: "space-between",
            padding: "0 6px",
            fontSize: 7,
            color: T.textDim,
            fontFamily: "'JetBrains Mono', monospace",
          }}>
            <span>-50¢</span>
            <span>-25¢</span>
            <span>0¢</span>
            <span>+25¢</span>
            <span>+50¢</span>
          </div>

          {/* Needle */}
          <div style={{
            position: "absolute",
            bottom: 16,
            left: `calc(10px + ${needlePct} * (100% - 20px))`,
            transform: "translateX(-50%)",
            transition: "left .04s ease-out",
          }}>
            {/* Needle line */}
            <div style={{
              width: 2,
              height: 44,
              background: isInTune ? T.green : (isClose ? T.amber : T.textPrimary),
              borderRadius: 1,
              margin: "0 auto",
              boxShadow: isInTune
                ? `0 0 8px ${T.green}`
                : `0 0 4px ${isClose ? T.amber : "transparent"}`,
            }} />
            {/* Needle dot */}
            <div style={{
              width: 8,
              height: 8,
              borderRadius: "50%",
              background: isInTune ? T.green : (isClose ? T.amber : T.textPrimary),
              margin: "-1px auto 0",
              boxShadow: isInTune
                ? `0 0 12px ${T.green}`
                : `0 0 6px ${isClose ? T.amber : "transparent"}`,
            }} />
          </div>
        </div>

        {/* ── Cent readout ── */}
        <div style={{
          fontSize: 13,
          fontFamily: "'JetBrains Mono', monospace",
          color: noteColor,
          letterSpacing: ".04em",
          minHeight: 18,
        }}>
          {cents > 0 ? `+${cents}¢` : `${cents}¢`}
          {isInTune && <span style={{color: T.green}}> ✓</span>}
        </div>
      </div>

      {/* ── String indicator bar ── */}
      <div style={{
        display: "flex",
        gap: 6,
        padding: "8px 16px 12px",
        justifyContent: "center",
        borderTop: `1px solid ${T.border}`,
        flexShrink: 0,
      }}>
        {STRING_LABELS.map(s => {
          const isActive = s.num === stringMatch;
          return (
            <div
              key={s.num}
              style={{
                width: 40,
                height: 40,
                borderRadius: 8,
                display: "flex",
                flexDirection: "column",
                alignItems: "center",
                justifyContent: "center",
                background: isActive ? `${s.color}22` : T.surface,
                border: `2px solid ${isActive ? s.color : T.border}`,
                transition: "all .1s",
                boxShadow: isActive ? `0 0 12px ${s.color}44` : "none",
              }}
            >
              <span style={{
                fontFamily: "'JetBrains Mono', monospace",
                fontSize: 16,
                fontWeight: 700,
                color: isActive ? s.color : T.textDim,
                lineHeight: 1,
              }}>
                {s.name}
              </span>
              <span style={{
                fontSize: 8,
                color: isActive ? s.color : T.textDim,
                opacity: 0.7,
                lineHeight: 1,
              }}>
                {s.num}
              </span>
            </div>
          );
        })}
      </div>

      {/* ── Confidence bar ── */}
      <div style={{
        padding: "0 16px 8px",
        display: "flex",
        alignItems: "center",
        gap: 8,
        flexShrink: 0,
      }}>
        <span style={{ fontSize: 8, color: T.textDim, fontFamily: "'JetBrains Mono', monospace" }}>
          SIG
        </span>
        <div style={{
          flex: 1,
          height: 3,
          borderRadius: 2,
          background: T.border,
          overflow: "hidden",
        }}>
          <div style={{
            height: "100%",
            width: `${Math.max(0, Math.min(100, confidence * 100))}%`,
            background: confidence > 0.7 ? T.green : (confidence > 0.3 ? T.amber : T.red),
            borderRadius: 2,
            transition: "width .08s",
          }} />
        </div>
        <span style={{
          fontSize: 8,
          color: T.textDim,
          fontFamily: "'JetBrains Mono', monospace",
          minWidth: 20,
          textAlign: "right",
        }}>
          {Math.round(confidence * 100)}%
        </span>
      </div>
    </div>
  );
}
