
const BreachGate = ({ onUnlock }) => {
  const [code, setCode] = React.useState('');
  const [status, setStatus] = React.useState('idle'); // idle | wrong | dissolving
  const [glitch, setGlitch] = React.useState(false);
  const CORRECT_CODE = '451227';

  React.useEffect(() => {
    const interval = setInterval(() => {
      setGlitch(true);
      setTimeout(() => setGlitch(false), 150);
    }, 7000);
    return () => clearInterval(interval);
  }, []);

  const runVaultAnimation = (callback) => {
    const canvas = document.getElementById('particle-canvas');
    if (!canvas) { callback(); return; }
    const ctx = canvas.getContext('2d');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    canvas.style.display = 'block';
    const cx = canvas.width / 2;
    const cy = canvas.height / 2;

    let startTime = null;
    const totalDuration = 3200;

    const drawVaultDoor = (progress, alpha) => {
      ctx.save();
      ctx.globalAlpha = alpha;

      // Outer vault ring with glow
      ctx.strokeStyle = '#C9A84C';
      ctx.lineWidth = 4;
      ctx.shadowColor = 'rgba(201,168,76,0.6)';
      ctx.shadowBlur = 20;
      ctx.beginPath();
      ctx.arc(cx, cy, 140, 0, Math.PI * 2);
      ctx.stroke();
      ctx.shadowBlur = 0;

      // Inner security rings with rotation
      for (let i = 1; i <= 4; i++) {
        const angle = progress * Math.PI * 3 * (i % 2 === 0 ? 1 : -1);
        ctx.strokeStyle = `rgba(79,195,247,${0.7 - i * 0.15})`;
        ctx.lineWidth = 1.5;
        ctx.beginPath();
        ctx.arc(cx, cy, 140 - i * 32, 0, Math.PI * 2);
        ctx.stroke();

        // Rotating tick marks
        for (let j = 0; j < 12; j++) {
          const tickAngle = (j / 12) * Math.PI * 2 + angle;
          const r1 = 140 - i * 32;
          const r2 = r1 + 12;
          ctx.strokeStyle = `rgba(79,195,247,${0.4 - i * 0.08})`;
          ctx.lineWidth = 1;
          ctx.beginPath();
          ctx.moveTo(cx + Math.cos(tickAngle) * r1, cy + Math.sin(tickAngle) * r1);
          ctx.lineTo(cx + Math.cos(tickAngle) * r2, cy + Math.sin(tickAngle) * r2);
          ctx.stroke();
        }
      }

      // Corner accent bolts
      for (let angle = 0; angle < Math.PI * 2; angle += Math.PI / 2) {
        const bx = cx + Math.cos(angle) * 180;
        const by = cy + Math.sin(angle) * 180;
        ctx.fillStyle = '#C9A84C';
        ctx.shadowColor = 'rgba(201,168,76,0.5)';
        ctx.shadowBlur = 10;
        ctx.fillRect(bx - 6, by - 6, 12, 12);
        ctx.strokeStyle = '#4FC3F7';
        ctx.lineWidth = 1.5;
        ctx.shadowBlur = 0;
        ctx.strokeRect(bx - 6, by - 6, 12, 12);
      }

      ctx.restore();
    };

    const drawLock = (progress, alpha) => {
      ctx.save();
      ctx.globalAlpha = alpha;
      ctx.translate(cx, cy);

      const lockRotation = progress < 0.35 ? 0 : (progress - 0.35) / 0.35 * Math.PI * 3;
      ctx.rotate(lockRotation);

      // Lock body with gradient
      const grad = ctx.createRadialGradient(0, 0, 5, 0, 0, 45);
      grad.addColorStop(0, '#E5C671');
      grad.addColorStop(1, '#C9A84C');
      ctx.fillStyle = grad;
      ctx.shadowColor = 'rgba(201,168,76,0.6)';
      ctx.shadowBlur = 20;
      ctx.beginPath();
      ctx.arc(0, 0, 40, 0, Math.PI * 2);
      ctx.fill();

      // Lock dial rings
      ctx.strokeStyle = '#0A0A0A';
      ctx.lineWidth = 2;
      ctx.beginPath();
      ctx.arc(0, 0, 32, 0, Math.PI * 2);
      ctx.stroke();

      ctx.strokeStyle = '#0A0A0A';
      ctx.lineWidth = 1;
      ctx.beginPath();
      ctx.arc(0, 0, 24, 0, Math.PI * 2);
      ctx.stroke();

      // Lock dial numbers/marks
      for (let i = 0; i < 12; i++) {
        const angle = (i / 12) * Math.PI * 2;
        const x1 = Math.cos(angle) * 28;
        const y1 = Math.sin(angle) * 28;
        const x2 = Math.cos(angle) * 35;
        const y2 = Math.sin(angle) * 35;
        ctx.strokeStyle = '#0A0A0A';
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
        ctx.stroke();
      }

      // Lock keyhole
      ctx.fillStyle = '#0A0A0A';
      ctx.shadowBlur = 0;
      ctx.beginPath();
      ctx.arc(0, 0, 7, 0, Math.PI * 2);
      ctx.fill();
      ctx.strokeStyle = '#4FC3F7';
      ctx.lineWidth = 1;
      ctx.beginPath();
      ctx.arc(0, 0, 7, 0, Math.PI * 2);
      ctx.stroke();

      ctx.restore();
    };

    const frame = (timestamp) => {
      if (!startTime) startTime = timestamp;
      const elapsed = Math.min(timestamp - startTime, totalDuration);
      const progress = elapsed / totalDuration;

      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // Background fade + vignette
      const bgAlpha = Math.min(progress * 0.9, 0.75);
      ctx.fillStyle = `rgba(10,10,10,${bgAlpha})`;
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      const vignetteAlpha = Math.min(progress * 1.2, 0.6);
      const grad = ctx.createRadialGradient(cx, cy, 0, cx, cy, Math.max(canvas.width, canvas.height) * 0.8);
      grad.addColorStop(0, `rgba(10,10,10,0)`);
      grad.addColorStop(1, `rgba(10,10,10,${vignetteAlpha})`);
      ctx.fillStyle = grad;
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      // Phase 1: Vault door emerges (0-0.25)
      if (progress < 0.25) {
        const p1 = progress / 0.25;
        drawVaultDoor(p1, p1);
      }

      // Phase 2: Lock spins and unlocks (0.25-0.65)
      if (progress >= 0.25) {
        const p2 = Math.min((progress - 0.25) / 0.4, 1);
        drawVaultDoor(1, 1);
        drawLock(p2, p2 < 0.1 ? p2 * 10 : 1);

        // Unlock burst energy rings (0.6+)
        if (progress > 0.6) {
          const p3 = (progress - 0.6) / 0.15;
          for (let ring = 0; ring < 3; ring++) {
            const delay = ring * 0.05;
            if (p3 > delay) {
              const ringProgress = Math.min((p3 - delay) / 0.1, 1);
              const ringRadius = 45 + ringProgress * 80;
              const ringAlpha = Math.max(1 - ringProgress, 0);
              ctx.strokeStyle = `rgba(79,195,247,${ringAlpha * 0.8})`;
              ctx.lineWidth = 2;
              ctx.shadowColor = 'rgba(79,195,247,0.8)';
              ctx.shadowBlur = 12;
              ctx.beginPath();
              ctx.arc(cx, cy, ringRadius, 0, Math.PI * 2);
              ctx.stroke();
              ctx.shadowBlur = 0;
            }
          }
        }
      }

      // Phase 3: Particles dissolve inward (0.65-1.0)
      if (progress >= 0.65) {
        const p3 = (progress - 0.65) / 0.35;

        if (!frame.particles) {
          frame.particles = Array.from({ length: 320 }, (_, i) => ({
            x: cx + (Math.random() - 0.5) * 500,
            y: cy + (Math.random() - 0.5) * 500,
            vx: (Math.random() - 0.5) * 8,
            vy: (Math.random() - 0.5) * 8,
            alpha: Math.random() * 0.9 + 0.2,
            size: Math.random() * 3 + 0.5,
            color: Math.random() > 0.5 ? '#C9A84C' : '#4FC3F7',
            decay: 0.01 + Math.random() * 0.015,
            targetX: cx,
            targetY: cy,
          }));
        }

        frame.particles.forEach(p => {
          const dx = p.targetX - p.x;
          const dy = p.targetY - p.y;
          const dist = Math.sqrt(dx * dx + dy * dy);
          if (dist > 2) {
            p.x += (dx / dist) * 12;
            p.y += (dy / dist) * 12;
          }
          p.alpha -= p.decay;

          if (p.alpha > 0) {
            ctx.save();
            ctx.globalAlpha = p.alpha * (1 - p3 * 0.7);
            ctx.shadowColor = p.color;
            ctx.shadowBlur = 12;
            ctx.fillStyle = p.color;
            ctx.beginPath();
            ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
            ctx.fill();
            ctx.restore();
          }
        });
      }

      if (progress < 1) {
        requestAnimationFrame(frame);
      } else {
        canvas.style.display = 'none';
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        callback();
      }
    };
    requestAnimationFrame(frame);
  };

  const handleKey = (digit) => {
    if (status === 'dissolving') return;
    if (digit === '⌫') {
      setCode(prev => prev.slice(0, -1));
      return;
    }
    if (digit === 'CLR') { setCode(''); return; }
    if (code.length >= 6) return;
    const next = code + digit;
    setCode(next);
    if (next.length === 6) {
      if (next === CORRECT_CODE) {
        setStatus('dissolving');
        setTimeout(() => runVaultAnimation(onUnlock), 300);
      } else {
        setStatus('wrong');
        setTimeout(() => { setCode(''); setStatus('idle'); }, 700);
      }
    }
  };

  React.useEffect(() => {
    const handler = (e) => {
      if (status === 'dissolving') return;
      if (e.key >= '0' && e.key <= '9') handleKey(e.key);
      if (e.key === 'Backspace') handleKey('⌫');
      if (e.key === 'Escape') handleKey('CLR');
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [code, status]);

  const dissolving = status === 'dissolving';
  const wrong = status === 'wrong';

  const keys = ['1','2','3','4','5','6','7','8','9','⌫','0','CLR'];

  const s = {
    wrapper: {
      position: 'fixed', inset: 0,
      background: '#0A0A0A',
      display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
      gap: 0,
      animation: dissolving ? 'dissolveOut 0.8s ease-out forwards' : 'none',
    },
    gridLines: {
      position: 'absolute', inset: 0, pointerEvents: 'none', overflow: 'hidden',
      opacity: 0.035,
    },
    logo: {
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 16,
      marginBottom: 48,
      animation: glitch ? 'flicker 0.2s ease-out' : 'none',
    },
    logoTitle: {
      fontFamily: "'Playfair Display', Georgia, serif",
      fontSize: 22,
      fontWeight: 700,
      letterSpacing: '0.22em',
      color: '#E2E2E2',
      textTransform: 'uppercase',
    },
    logoSub: {
      fontFamily: "'JetBrains Mono', monospace",
      fontSize: 10,
      letterSpacing: '0.35em',
      color: '#C9A84C',
      textTransform: 'uppercase',
    },
    gate: {
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 28,
      padding: '40px 44px',
      background: 'rgba(255,255,255,0.022)',
      border: '1px solid rgba(255,255,255,0.07)',
      borderRadius: 10,
      backdropFilter: 'blur(16px)',
      animation: wrong ? 'shake 0.5s ease-out' : 'none',
      boxShadow: wrong ? '0 0 32px rgba(224,82,82,0.15)' : '0 0 60px rgba(0,0,0,0.5)',
    },
    gateLabel: {
      fontFamily: "'JetBrains Mono', monospace",
      fontSize: 10,
      letterSpacing: '0.3em',
      color: wrong ? '#E05252' : '#666',
      textTransform: 'uppercase',
      transition: 'color 0.3s',
    },
    dots: {
      display: 'flex', gap: 12, alignItems: 'center', height: 28,
    },
    dot: (filled, isWrong) => ({
      width: 10, height: 10, borderRadius: '50%',
      background: isWrong ? '#E05252' : filled ? '#C9A84C' : 'transparent',
      border: `1px solid ${isWrong ? '#E05252' : filled ? '#C9A84C' : 'rgba(255,255,255,0.2)'}`,
      boxShadow: filled && !isWrong ? '0 0 8px rgba(201,168,76,0.6)' : 'none',
      transition: 'all 0.2s',
    }),
    keypad: {
      display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8,
    },
    key: (isSpecial) => ({
      width: 68, height: 68,
      background: isSpecial ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.03)',
      border: '1px solid rgba(255,255,255,0.08)',
      borderRadius: 5,
      fontFamily: "'JetBrains Mono', monospace",
      fontSize: isSpecial ? 13 : 20,
      fontWeight: isSpecial ? 400 : 500,
      color: isSpecial ? '#666' : '#D8D8D8',
      cursor: 'pointer',
      transition: 'all 0.15s',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      userSelect: 'none',
      letterSpacing: '0.02em',
    }),
    hint: {
      fontFamily: "'JetBrains Mono', monospace",
      fontSize: 9,
      color: 'rgba(255,255,255,0.1)',
      letterSpacing: '0.2em',
      marginTop: 8,
    },
    bottomLine: {
      position: 'absolute', bottom: 32,
      fontFamily: "'JetBrains Mono', monospace",
      fontSize: 9,
      color: 'rgba(255,255,255,0.12)',
      letterSpacing: '0.25em',
    }
  };

  return (
    <div style={s.wrapper}>
      {/* Grid lines background */}
      <svg style={s.gridLines} width="100%" height="100%">
        {Array.from({ length: 30 }, (_, i) => (
          <line key={`v${i}`} x1={`${(i / 29) * 100}%`} y1="0" x2={`${(i / 29) * 100}%`} y2="100%"
            stroke="white" strokeWidth="1"/>
        ))}
        {Array.from({ length: 20 }, (_, i) => (
          <line key={`h${i}`} x1="0" y1={`${(i / 19) * 100}%`} x2="100%" y2={`${(i / 19) * 100}%`}
            stroke="white" strokeWidth="1"/>
        ))}
      </svg>

      {/* Corner accents */}
      {[['0,0','tl'],['calc(100% - 40px),0','tr'],['0,calc(100% - 40px)','bl'],['calc(100% - 40px),calc(100% - 40px)','br']].map(([pos, id]) => {
        const [x, y] = pos.split(',');
        const isR = id.includes('r'), isB = id.includes('b');
        return (
          <svg key={id} style={{ position:'absolute', left: x, top: y, opacity: 0.4 }} width="40" height="40">
            {!isR && !isB && <><line x1="0" y1="0" x2="20" y2="0" stroke="#C9A84C" strokeWidth="1"/><line x1="0" y1="0" x2="0" y2="20" stroke="#C9A84C" strokeWidth="1"/></>}
            {isR && !isB && <><line x1="40" y1="0" x2="20" y2="0" stroke="#C9A84C" strokeWidth="1"/><line x1="40" y1="0" x2="40" y2="20" stroke="#C9A84C" strokeWidth="1"/></>}
            {!isR && isB && <><line x1="0" y1="40" x2="20" y2="40" stroke="#C9A84C" strokeWidth="1"/><line x1="0" y1="40" x2="0" y2="20" stroke="#C9A84C" strokeWidth="1"/></>}
            {isR && isB && <><line x1="40" y1="40" x2="20" y2="40" stroke="#C9A84C" strokeWidth="1"/><line x1="40" y1="40" x2="40" y2="20" stroke="#C9A84C" strokeWidth="1"/></>}
          </svg>
        );
      })}

      {/* Logo */}
      <div style={s.logo}>
        <svg viewBox="0 0 100 100" width="72" height="72" style={{ filter: 'drop-shadow(0 0 12px rgba(201,168,76,0.4))' }}>
          <polygon points="50,6 79,19 94,50 79,81 50,94 21,81 6,50 21,19"
            fill="none" stroke="#C9A84C" strokeWidth="1.2"/>
          <polygon points="50,24 76,50 50,76 24,50"
            fill="none" stroke="#4FC3F7" strokeWidth="0.8" opacity="0.8"/>
          <line x1="50" y1="24" x2="50" y2="76" stroke="rgba(79,195,247,0.25)" strokeWidth="0.5"/>
          <line x1="24" y1="50" x2="76" y2="50" stroke="rgba(79,195,247,0.25)" strokeWidth="0.5"/>
          <circle cx="50" cy="50" r="7" fill="none" stroke="#C9A84C" strokeWidth="1.2"/>
          <circle cx="50" cy="50" r="2.5" fill="#C9A84C"/>
          <circle cx="50" cy="6" r="2" fill="#C9A84C"/>
          <circle cx="94" cy="50" r="2" fill="#C9A84C"/>
          <circle cx="50" cy="94" r="2" fill="#C9A84C"/>
          <circle cx="6" cy="50" r="2" fill="#C9A84C"/>
        </svg>
        <div style={s.logoTitle}>Cipher Intelligence Hub</div>
        <div style={s.logoSub}>Classified Access Portal — Level V Clearance</div>
      </div>

      {/* Gate */}
      <div style={s.gate}>
        <div style={s.gateLabel}>{wrong ? '⚠ Clearance Denied — Retry' : 'Enter Clearance Code'}</div>
        <div style={s.dots}>
          {Array.from({ length: 6 }, (_, i) => (
            <div key={i} style={s.dot(i < code.length, wrong)}/>
          ))}
        </div>
        <div style={s.keypad}>
          {keys.map((k) => {
            const isSpecial = k === '⌫' || k === 'CLR';
            return (
              <button key={k} style={s.key(isSpecial)} onClick={() => handleKey(k)}
                onMouseEnter={e => {
                  e.currentTarget.style.background = isSpecial ? 'rgba(255,255,255,0.05)' : 'rgba(201,168,76,0.08)';
                  e.currentTarget.style.borderColor = 'rgba(201,168,76,0.3)';
                  e.currentTarget.style.color = isSpecial ? '#999' : '#C9A84C';
                }}
                onMouseLeave={e => {
                  e.currentTarget.style.background = isSpecial ? 'rgba(255,255,255,0.025)' : 'rgba(255,255,255,0.03)';
                  e.currentTarget.style.borderColor = 'rgba(255,255,255,0.08)';
                  e.currentTarget.style.color = isSpecial ? '#666' : '#D8D8D8';
                }}>
                {k}
              </button>
            );
          })}
        </div>
        <div style={s.hint}>PROTOTYPE CLEARANCE ·· 4 5 1 2 2 7</div>
      </div>

      <div style={s.bottomLine}>CIPHER SYS v4.1 · SECURE CHANNEL ESTABLISHED · {new Date().getFullYear()}</div>
    </div>
  );
};

Object.assign(window, { BreachGate });
