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

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

// ── Block param definitions (mirrored from App.jsx) ──
const BLOCK_PARAMS = {
  overdrive:    [{ key:'drive', label:'Drive', min:0, max:100, def:30 }, { key:'tone', label:'Tone', min:0, max:100, def:50 }, { key:'level', label:'Level', min:0, max:100, def:70 }],
  distortion:   [{ key:'drive', label:'Drive', min:0, max:100, def:50 }, { key:'tone', label:'Tone', min:0, max:100, def:40 }, { key:'level', label:'Level', min:0, max:100, def:60 }],
  fuzz:         [{ key:'fuzz', label:'Fuzz', min:0, max:100, def:60 }, { key:'tone', label:'Tone', min:0, max:100, def:30 }, { key:'level', label:'Level', min:0, max:100, def:60 }],
  delay:        [{ key:'time', label:'Time', min:0, max:100, def:40 }, { key:'feedback', label:'Feedback', min:0, max:100, def:30 }, { key:'mix', label:'Mix', min:0, max:100, def:35 }],
  echo:         [{ key:'time', label:'Time', min:0, max:100, def:40 }, { key:'feedback', label:'Feedback', min:0, max:100, def:30 }, { key:'mix', label:'Mix', min:0, max:100, def:35 }],
  reverb:       [{ key:'decay', label:'Decay', min:0, max:100, def:50 }, { key:'mix', label:'Mix', min:0, max:100, def:30 }, { key:'tone', label:'Tone', min:0, max:100, def:50 }],
  chorus:       [{ key:'rate', label:'Rate', min:0, max:100, def:40 }, { key:'depth', label:'Depth', min:0, max:100, def:40 }, { key:'mix', label:'Mix', min:0, max:100, def:30 }],
  flanger:      [{ key:'rate', label:'Rate', min:0, max:100, def:30 }, { key:'depth', label:'Depth', min:0, max:100, def:50 }, { key:'feedback', label:'Feedback', min:0, max:100, def:40 }, { key:'mix', label:'Mix', min:0, max:100, def:30 }],
  phaser:       [{ key:'rate', label:'Rate', min:0, max:100, def:30 }, { key:'depth', label:'Depth', min:0, max:100, def:50 }, { key:'feedback', label:'Feedback', min:0, max:100, def:40 }, { key:'mix', label:'Mix', min:0, max:100, def:30 }],
  compressor:   [{ key:'threshold', label:'Thresh', min:0, max:100, def:50 }, { key:'ratio', label:'Ratio', min:1, max:20, def:4 }, { key:'gain', label:'Gain', min:0, max:100, def:50 }],
  gate:         [{ key:'threshold', label:'Thresh', min:0, max:100, def:30 }, { key:'release', label:'Release', min:0, max:100, def:50 }],
  eq:           [{ key:'low', label:'Low', min:-12, max:12, def:0 }, { key:'mid', label:'Mid', min:-12, max:12, def:0 }, { key:'high', label:'High', min:-12, max:12, def:0 }, { key:'level', label:'Level', min:0, max:100, def:70 }],
  cabinet:      [{ key:'level', label:'Level', min:0, max:100, def:75 }],
  ir:           [{ key:'level', label:'Level', min:0, max:100, def:75 }],
};

const BLOCK_COLORS = {
  overdrive: T.amber, distortion: T.red, fuzz: '#C07030',
  delay: T.blue, echo: T.blue, reverb: '#60B0D0',
  chorus: T.green, flanger: '#50C080', phaser: '#80C050',
  tremolo: T.green, compressor: '#D09040', gate: T.textSec, eq: '#7080D0',
  cabinet: '#D07090', ir: '#D07090', nam: '#E0A040', boost: T.amber,
  wah: '#D0A060', volume: T.textSec, tuner: '#80D0A0',
};

const BLOCK_DISPLAY_NAMES = {
  overdrive: "OD-808", distortion: "RAT", fuzz: "Big Muff",
  delay: "Digital Delay", echo: "Tape Echo", reverb: "Hall Reverb",
  chorus: "Chorus", flanger: "Flanger", phaser: "Phase 90",
  tremolo: "Tremolo", compressor: "Compressor", gate: "Noise Gate",
  eq: "EQ", cabinet: "Cabinet", ir: "IR Loader", nam: "NAM Model",
  boost: "Clean Boost", wah: "Wah", volume: "Volume", tuner: "Tuner",
  loop: "FX Loop",
};

function getBlockParams(type) {
  return BLOCK_PARAMS[(type || '').toLowerCase()] || [{ key:'level', label:'Level', min:0, max:100, def:50 }];
}
function getBlockColor(type) {
  return BLOCK_COLORS[(type || '').toLowerCase()] || T.amber;
}
function getBlockDisplayName(block) {
  const key = (block.type || '').toLowerCase();
  if (block.nam_model_path) {
    const parts = block.nam_model_path.split('/').pop()?.replace(/\.(nam|wav|aiff?)$/i, '') || '';
    return parts || 'NAM Model';
  }
  if (block.ir_file_path) {
    const parts = block.ir_file_path.split('/').pop()?.replace(/\.(wav|aiff?|ir)$/i, '') || '';
    return parts || 'IR Loader';
  }
  return BLOCK_DISPLAY_NAMES[key] || key.charAt(0).toUpperCase() + key.slice(1);
}

// ── Large touch knob (bigger version for Focus View) ──
function FocusKnob({ label, value = 50, onChange, size = 72, color = T.amber, min = 0, max = 100, compact = false }) {
  const startRef = useRef(null);
  const norm = (value - min) / (max - min);
  const angle = -140 + norm * 280;
  const dotH = size * 0.38;
  const dotTop = size * 0.5 - dotH;

  const handleStart = (e) => {
    e.preventDefault();
    const clientY = e.touches ? e.touches[0].clientY : e.clientY;
    startRef.current = { y: clientY, val: value };
    const move = (ev) => {
      const cy = ev.touches ? ev.touches[0].clientY : ev.clientY;
      const delta = (startRef.current.y - cy) / 120;
      const next = Math.max(min, Math.min(max, startRef.current.val + delta * (max - min)));
      onChange?.(Math.round(next));
    };
    const up = () => { window.removeEventListener("mousemove",move);window.removeEventListener("mouseup",up);
      window.removeEventListener("touchmove",move);window.removeEventListener("touchend",up); };
    window.addEventListener("mousemove",move);window.addEventListener("mouseup",up);
    window.addEventListener("touchmove",move,{passive:false});window.addEventListener("touchend",up);
  };

  const svgSize = size + 16, cx = svgSize / 2, cy = svgSize / 2, r = size / 2 + 4;
  const lx = cx + r * Math.cos((-140 - 90) * (Math.PI / 180)), ly = cy + r * Math.sin((-140 - 90) * (Math.PI / 180));
  const ex = cx + r * Math.cos((angle - 90) * (Math.PI / 180)), ey = cy + r * Math.sin((angle - 90) * (Math.PI / 180));
  const large = norm * 280 > 180 ? 1 : 0;

  return (
    <div style={{
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: compact ? 2 : 6,
      cursor: 'pointer',
    }}>
      <div style={{ width: size, height: size, position: 'relative', touchAction: 'none' }}
        onMouseDown={handleStart} onTouchStart={handleStart}>
        <svg style={{ position: 'absolute', inset: -8, width: svgSize, height: svgSize, overflow: 'visible' }}>
          <circle cx={cx} cy={cy} r={r} fill="none" stroke={T.border} strokeWidth="3" strokeLinecap="round" opacity=".5" />
          {norm > 0 && <path d={`M ${lx} ${ly} A ${r} ${r} 0 ${large} 1 ${ex} ${ey}`} fill="none" stroke={color} strokeWidth="3" strokeLinecap="round" style={{ filter: `drop-shadow(0 0 4px ${color})` }} />}
        </svg>
        <div style={{
          borderRadius: '50%', width: '100%', height: '100%', position: 'relative',
          background: 'radial-gradient(circle at 35% 30%, #3A3A48, #1A1A22)',
          boxShadow: '0 3px 12px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.07)',
        }}>
          <div style={{
            position: 'absolute', width: 4, borderRadius: 2, background: color,
            left: '50%', transformOrigin: 'bottom center',
            height: dotH, top: dotTop,
            transform: `translateX(-50%) rotate(${angle}deg)`,
            transformOrigin: `50% ${dotH}px`,
            boxShadow: `0 0 6px ${color}`,
          }} />
        </div>
      </div>
      <div style={{
        fontFamily: "'JetBrains Mono', monospace", fontSize: compact ? 11 : 14,
        fontWeight: 700, color,
      }}>{value}</div>
      <div style={{
        fontSize: compact ? 7 : 9, color: T.textSec,
        letterSpacing: '.06em', textTransform: 'uppercase', textAlign: 'center',
        whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: size + 16,
      }}>{label}</div>
    </div>
  );
}

// ── Large Param Slider (bigger for Focus View) ──
function FocusSlider({ label, value = 50, onChange, onChangeEnd, min = 0, max = 100, color = T.amber }) {
  const trackRef = useRef(null);
  const dragRef = useRef(false);
  const lastValRef = useRef(value);
  const onChangeRef = useRef(onChange);
  const onChangeEndRef = useRef(onChangeEnd);
  const pct = ((value - min) / (max - min)) * 100;

  const [touchVal, setTouchVal] = useState(null);

  useMemo(() => { onChangeRef.current = onChange; }, [onChange]);
  useMemo(() => { onChangeEndRef.current = onChangeEnd; }, [onChangeEnd]);

  const valFromEvent = useCallback((e) => {
    const t = trackRef.current; if (!t) return value;
    const r = t.getBoundingClientRect();
    const x = (e.touches ? e.touches[0].clientX : e.clientX) - r.left;
    return Math.round(min + Math.max(0, Math.min(1, x / r.width)) * (max - min));
  }, [min, max, value]);

  useMemo(() => {
    const move = (e) => { if (!dragRef.current) return; e.preventDefault(); const v = valFromEvent(e); lastValRef.current = v; setTouchVal(v); onChangeRef.current?.(v); };
    const up = () => { if (dragRef.current) { onChangeEndRef.current?.(lastValRef.current); dragRef.current = false; setTouchVal(null); } };
    window.addEventListener('mousemove', move); window.addEventListener('mouseup', up);
    window.addEventListener('touchmove', move, { passive: false }); window.addEventListener('touchend', up);
    return () => { window.removeEventListener('mousemove', move); window.removeEventListener('mouseup', up);
      window.removeEventListener('touchmove', move); window.removeEventListener('touchend', up); };
  }, [valFromEvent]);

  const handleStart = (e) => { e.preventDefault(); const v = valFromEvent(e); lastValRef.current = v; dragRef.current = true; setTouchVal(v); onChangeRef.current?.(v); };
  const quick = (delta) => (e) => { e.preventDefault(); e.stopPropagation(); const next = Math.max(min, Math.min(max, value + delta)); onChangeRef.current?.(next); onChangeEndRef.current?.(next); };

  return (
    <div style={{ marginBottom: 4 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 2 }}>
        <span style={{ fontSize: 11, fontWeight: 500, textTransform: 'uppercase', letterSpacing: '.06em', color }}>{label}</span>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          <button style={{
            width: 34, height: 34, borderRadius: '50%', border: `1px solid ${T.border}`,
            background: T.panel, color: T.textPrimary, fontSize: 16, fontWeight: 700,
            display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
            lineHeight: 1,
          }} onMouseDown={quick(-5)} onTouchStart={quick(-5)}>−</button>
          <span style={{
            fontFamily: "'JetBrains Mono', monospace", fontSize: 16, fontWeight: 700, color,
            minWidth: 40, textAlign: 'center',
          }}>{touchVal ?? value}</span>
          <button style={{
            width: 34, height: 34, borderRadius: '50%', border: `1px solid ${T.border}`,
            background: T.panel, color: T.textPrimary, fontSize: 16, fontWeight: 700,
            display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
            lineHeight: 1,
          }} onMouseDown={quick(5)} onTouchStart={quick(5)}>+</button>
        </div>
      </div>
      <div ref={trackRef}
        onMouseDown={handleStart} onTouchStart={handleStart}
        style={{
          position: 'relative', height: 44, display: 'flex', alignItems: 'center',
          cursor: 'pointer', touchAction: 'none',
        }}>
        <div style={{
          width: '100%', height: 10, background: T.border, borderRadius: 5,
          position: 'relative', overflow: 'hidden',
        }}>
          <div style={{
            height: '100%', borderRadius: 5, position: 'absolute', top: 0, left: 0,
            width: `${pct}%`, background: color,
            boxShadow: `0 0 8px ${color}44`,
            transition: 'width .03s',
          }} />
        </div>
        <div style={{
          width: 30, height: 30, borderRadius: '50%', position: 'absolute',
          top: '50%', left: `${pct}%`,
          transform: 'translate(-50%,-50%)',
          background: color,
          boxShadow: `0 2px 10px rgba(0,0,0,.6), 0 0 0 3px ${T.bg}`,
          pointerEvents: 'none',
          transition: 'left .03s',
        }} />
      </div>
    </div>
  );
}

// ── Parameter page (single page of up to 8 params) ──
function ParamPage({ defs, params, viewMode, color, onParamChange, onParamChangeEnd, compact }) {
  return (
    <div style={{
      display: 'flex', flexDirection: 'column', gap: viewMode === 'knob' ? 8 : 0,
      width: '100%', minWidth: 0, flexShrink: 0,
    }}>
      {viewMode === 'slider' ? (
        defs.map(p => (
          <FocusSlider key={p.key} label={p.label}
            value={params[p.key] != null ? params[p.key] : p.def}
            min={p.min} max={p.max} color={color}
            onChange={v => onParamChange(p.key, v)}
            onChangeEnd={v => onParamChangeEnd(p.key, v)} />
        ))
      ) : (
        <div style={{
          display: 'grid',
          gridTemplateColumns: `repeat(${compact ? 4 : Math.min(4, defs.length)}, 1fr)`,
          gap: 12,
          padding: '8px 0',
          justifyItems: 'center',
          width: '100%',
          maxWidth: 480,
          margin: '0 auto',
        }}>
          {defs.map(p => (
            <FocusKnob key={p.key} label={p.label} size={compact ? 60 : 72}
              value={params[p.key] != null ? params[p.key] : p.def}
              min={p.min} max={p.max} color={color}
              onChange={v => { onParamChange(p.key, v); onParamChangeEnd(p.key, v); }}
              compact={compact} />
          ))}
        </div>
      )}
    </div>
  );
}

// ── Focus View (full-screen overlay) ──
export default function FocusView({
  block,
  params,
  viewMode,
  onClose,
  onParamChange,
  onParamChangeEnd,
  onToggleView,
  onToggleBypass,
  onOpenModelBrowser,
}) {
  const defs = getBlockParams(block.type);
  const color = getBlockColor(block.type);
  const displayName = getBlockDisplayName(block);

  // Pagination — max 8 params per page
  const PER_PAGE = 8;
  const pages = useMemo(() => {
    const p = [];
    for (let i = 0; i < defs.length; i += PER_PAGE) {
      p.push(defs.slice(i, i + PER_PAGE));
    }
    return p;
  }, [defs]);

  const [currentPage, setCurrentPage] = useState(0);
  const scrollRef = useRef(null);
  const touchStartX = useRef(null);
  const [isCompact, setIsCompact] = useState(window.innerWidth < 500);

  // Track resize for compact layout
  useMemo(() => {
    const onResize = () => setIsCompact(window.innerWidth < 500);
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);

  // ── Swipe handling ──
  const handleTouchStart = useCallback((e) => {
    touchStartX.current = e.touches[0].clientX;
  }, []);

  const handleTouchEnd = useCallback((e) => {
    if (touchStartX.current == null) return;
    const dx = e.changedTouches[0].clientX - touchStartX.current;
    touchStartX.current = null;
    if (Math.abs(dx) < 50) return; // threshold
    if (dx < 0 && currentPage < pages.length - 1) {
      setCurrentPage(p => Math.min(p + 1, pages.length - 1));
    } else if (dx > 0 && currentPage > 0) {
      setCurrentPage(p => Math.max(p - 1, 0));
    }
  }, [currentPage, pages.length]);

  // ── Keyboard nav ──
  useMemo(() => {
    const handler = (e) => {
      if (e.key === 'ArrowLeft' && currentPage > 0) setCurrentPage(p => p - 1);
      if (e.key === 'ArrowRight' && currentPage < pages.length - 1) setCurrentPage(p => p + 1);
      if (e.key === 'Escape') onClose?.();
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [currentPage, pages.length, onClose]);

  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 1000,
      display: 'flex', flexDirection: 'column',
      background: T.bg,
      fontFamily: "'Inter', sans-serif",
      color: T.textPrimary,
    }}>
      {/* ── Header ── */}
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '10px 14px',
        borderBottom: `1px solid ${T.border}`,
        background: T.panel,
        flexShrink: 0,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 0 }}>
          <button onClick={onClose}
            style={{
              width: 34, height: 34, borderRadius: 8,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              background: T.surface, border: `1px solid ${T.border}`,
              color: T.textPrimary, fontSize: 16, cursor: 'pointer',
              flexShrink: 0,
            }}>
            ✕
          </button>
          <div style={{ minWidth: 0 }}>
            <div style={{
              fontSize: 15, fontWeight: 600, whiteSpace: 'nowrap',
              overflow: 'hidden', textOverflow: 'ellipsis',
            }}>
              {displayName}
            </div>
            <div style={{
              display: 'flex', alignItems: 'center', gap: 6, marginTop: 2,
            }}>
              <span style={{
                display: 'inline-flex', padding: '1px 6px', borderRadius: 3,
                fontSize: 9, fontWeight: 700, letterSpacing: '.06em',
                textTransform: 'uppercase',
                background: `${color}22`, color,
              }}>
                {(block.type || 'fx').replace(/_/g, ' ').toUpperCase()}
              </span>
            </div>
          </div>
        </div>

        <div style={{ display: 'flex', gap: 6, alignItems: 'center', flexShrink: 0 }}>
          {/* Slider/Knob toggle */}
          <button onClick={onToggleView}
            style={{
              padding: '6px 10px', borderRadius: 6, fontSize: 10, fontWeight: 600,
              background: T.surface, border: `1px solid ${T.border}`,
              color: T.textPrimary, cursor: 'pointer', letterSpacing: '.04em',
            }}>
            {viewMode === 'slider' ? '◉ Knobs' : '▦ Sliders'}
          </button>
        </div>
      </div>

      {/* ── Bypass toggle (prominent) ── */}
      <div style={{
        padding: '6px 14px',
        borderBottom: `1px solid ${T.border}`,
        background: T.surface,
        flexShrink: 0,
      }}>
        <button onClick={onToggleBypass}
          style={{
            width: '100%',
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
            padding: '10px 14px',
            borderRadius: 8,
            border: `2px solid ${block.bypassed ? T.red + '66' : T.green + '66'}`,
            background: block.bypassed
              ? `linear-gradient(180deg, ${T.red + '18'}, ${T.panel})`
              : `linear-gradient(180deg, ${T.green + '18'}, ${T.panel})`,
            cursor: 'pointer',
            transition: 'all .12s',
          }}>
          <div style={{
            width: 12, height: 12, borderRadius: '50%',
            background: block.bypassed ? T.textDim : T.green,
            boxShadow: block.bypassed ? 'none' : `0 0 8px ${T.green}`,
          }} />
          <span style={{
            fontSize: 12, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase',
            color: block.bypassed ? T.red : T.green,
          }}>
            {block.bypassed ? 'Bypassed — Tap to Enable' : 'Active — Tap to Bypass'}
          </span>
        </button>
      </div>

      {/* ── Parameter area (scrollable with pages) ── */}
      <div
        ref={scrollRef}
        onTouchStart={handleTouchStart}
        onTouchEnd={handleTouchEnd}
        style={{
          flex: 1, overflowY: 'auto', overflowX: 'hidden',
          padding: '12px 16px',
          display: 'flex', flexDirection: 'column',
          gap: 6,
        }}>

        {pages.length === 0 ? (
          <div style={{
            flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: T.textDim, fontSize: 12,
          }}>
            No parameters for this block type
          </div>
        ) : (
          <>
            {/* Page content */}
            <ParamPage
              defs={pages[currentPage]}
              params={params}
              viewMode={viewMode}
              color={color}
              onParamChange={onParamChange}
              onParamChangeEnd={onParamChangeEnd}
              compact={isCompact}
            />

            {/* Spacer so page dots don't crowd content */}
            <div style={{ flex: 1, minHeight: 8 }} />
          </>
        )}
      </div>

      {/* ── Bottom bar: Model browser + page indicators ── */}
      <div style={{
        padding: '8px 14px 12px',
        borderTop: `1px solid ${T.border}`,
        background: T.panel,
        flexShrink: 0,
        display: 'flex', flexDirection: 'column', gap: 6,
      }}>
        {/* Page dots */}
        {pages.length > 1 && (
          <div style={{ display: 'flex', justifyContent: 'center', gap: 5 }}>
            {pages.map((_, i) => (
              <button key={i} onClick={() => setCurrentPage(i)}
                style={{
                  width: 8, height: 8, borderRadius: '50%', border: 'none',
                  padding: 0, cursor: 'pointer',
                  background: i === currentPage ? color : T.border,
                  opacity: i === currentPage ? 1 : 0.4,
                  transition: 'all .12s',
                }} />
            ))}
          </div>
        )}

        {/* Page indicator text */}
        {pages.length > 1 && (
          <div style={{
            textAlign: 'center', fontSize: 9, color: T.textDim,
            fontFamily: "'JetBrains Mono', monospace", letterSpacing: '.04em',
          }}>
            Page {currentPage + 1} / {pages.length}
            <span style={{ marginLeft: 8, opacity: 0.6 }}>
              ← swipe to navigate →
            </span>
          </div>
        )}

        {/* Model browser button / swap block */}
        {onOpenModelBrowser && (
          <button onClick={onOpenModelBrowser}
            style={{
              width: '100%',
              padding: '8px 14px', borderRadius: 7,
              background: T.surface, border: `1px solid ${T.border}`,
              color: T.textPrimary, fontSize: 11, fontWeight: 600,
              cursor: 'pointer', letterSpacing: '.04em',
              display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6,
            }}>
            <span>🎛</span> Swap Model / Block Type
          </button>
        )}
      </div>
    </div>
  );
}
