// src/features/meetings/ui/permission-help.jsx
//
// Camera / microphone permission modal. Two variants:
//   'pre-prompt'     — browser has never asked; warn user to click Allow.
//   'denied-help'    — cam/mic blocked; browser-specific plain-English help.
//   'standalone-help' — same as denied-help, opened via the help link.
//
// Exposed as window.Meetings.ui.PermissionHelp.
// Accessibility: role=dialog, aria-modal, focus trap, ESC to close.

(function () {
  'use strict';

  window.Meetings = window.Meetings || {};
  window.Meetings.ui = window.Meetings.ui || {};

  const S = {
    overlay: { position:'fixed', inset:0, background:'rgba(0,0,0,0.55)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:9900, padding:'16px' },
    dialog:  { background:'#fff', borderRadius:16, maxWidth:540, width:'100%', maxHeight:'90vh', overflowY:'auto', padding:'32px 28px 28px', boxSizing:'border-box', fontFamily:"'Plus Jakarta Sans', sans-serif", position:'relative' },
    closeBtn:{ position:'absolute', top:16, right:16, background:'none', border:'none', cursor:'pointer', padding:8, borderRadius:8, color:'#6b7280', fontSize:20, lineHeight:1, display:'flex', alignItems:'center', justifyContent:'center', minWidth:44, minHeight:44 },
    heading: { fontSize:22, fontWeight:700, color:'#111827', margin:'0 0 8px', paddingRight:40, lineHeight:1.3 },
    subhead: { fontSize:16, color:'#374151', margin:'0 0 24px', lineHeight:1.6 },
    list:    { margin:'0 0 24px', padding:0, listStyle:'none' },
    item:    { display:'flex', alignItems:'flex-start', gap:14, marginBottom:16, fontSize:17, color:'#1f2937', lineHeight:1.55 },
    num:     { flexShrink:0, width:30, height:30, borderRadius:'50%', background:'oklch(56% 0.13 250)', color:'#fff', display:'flex', alignItems:'center', justifyContent:'center', fontWeight:700, fontSize:14, marginTop:1 },
    primary: { display:'block', width:'100%', padding:'14px 24px', background:'oklch(56% 0.13 250)', color:'#fff', border:'none', borderRadius:10, fontFamily:"'Plus Jakarta Sans', sans-serif", fontWeight:700, fontSize:17, cursor:'pointer', marginBottom:10, minHeight:50 },
    secondary:{ display:'block', width:'100%', padding:'13px 24px', background:'transparent', color:'#374151', border:'1.5px solid #d1d5db', borderRadius:10, fontFamily:"'Plus Jakarta Sans', sans-serif", fontWeight:600, fontSize:16, cursor:'pointer', minHeight:50 },
    note:    { fontSize:14, color:'#6b7280', margin:'16px 0 0', lineHeight:1.5, textAlign:'center' },
  };

  const INSTRUCTIONS = {
    'safari-mac': {
      name: 'Safari on Mac',
      steps: [
        'In the top menu bar, click Safari, then click Settings for This Website.',
        'A box appears. Find Camera, click the dropdown beside it, and choose Allow.',
        'Find Microphone in the same box and choose Allow.',
        'Close the box. You may need to refresh the page.',
        'Click "Try again" below.',
      ],
    },
    'safari-ios': {
      name: 'Safari on iPhone or iPad',
      steps: [
        'Close your browser and open the Settings app (the grey icon with gears).',
        'Scroll down to Safari and tap it.',
        'Find Camera and make sure it says Allow or Ask.',
        'Go back up and find Microphone — make sure it also says Allow or Ask.',
        'Return to this page and tap "Try again" below.',
      ],
    },
    'chrome-desktop': {
      name: 'Google Chrome',
      steps: [
        'Look at the top of your browser window, in the address bar. Find a small lock icon or camera icon on the left side.',
        'Click that icon. A small menu opens.',
        'Find Camera and change it to Allow. Then find Microphone and change it to Allow.',
        'Close that menu. The page may ask you to reload — do so if you see that message.',
        'Click "Try again" below.',
      ],
    },
    'chrome-android': {
      name: 'Chrome on Android',
      steps: [
        'In the address bar at the top, tap the lock icon (small padlock).',
        'Tap Permissions.',
        'Find Camera and tap Allow. Find Microphone and tap Allow.',
        'Return to this page and tap "Try again" below.',
      ],
    },
    'edge': {
      name: 'Microsoft Edge',
      steps: [
        'Look at the address bar at the top. Find a small lock or shield icon on the left.',
        'Click that icon. A panel opens.',
        'Find Camera and change it to Allow. Find Microphone and change it to Allow.',
        'Close the panel. Refresh the page if prompted.',
        'Click "Try again" below.',
      ],
    },
    'firefox': {
      name: 'Firefox',
      steps: [
        'Look at the address bar at the top. Find the lock icon on the left side.',
        'Click the lock icon. A small box opens.',
        'If you see a crossed-out camera or microphone, click the X next to "Blocked" to remove it.',
        'Press F5 on your keyboard (or click the circular arrow near the address bar) to refresh.',
        'When the browser asks about camera and microphone, click Allow.',
        'Click "Try again" below.',
      ],
    },
    'other': {
      name: 'your browser',
      steps: [
        'Look near the top of your browser, close to where you type website addresses. There may be a lock icon or camera icon.',
        'Click that icon and look for options to allow camera and microphone for this website.',
        'If you cannot find it, open your browser\'s settings and search for "camera" or "microphone."',
        'Once you have changed the setting, click "Try again" below.',
      ],
    },
  };

  function useFocusTrap(ref) {
    React.useEffect(() => {
      if (!ref || !ref.current) return;
      const el = ref.current;
      const getFocusable = () => Array.from(el.querySelectorAll(
        'button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"])'
      )).filter(n => !n.disabled && n.offsetParent !== null);

      const onKey = (e) => {
        if (e.key !== 'Tab') return;
        const nodes = getFocusable();
        if (!nodes.length) return;
        if (e.shiftKey) {
          if (document.activeElement === nodes[0]) { e.preventDefault(); nodes[nodes.length - 1].focus(); }
        } else {
          if (document.activeElement === nodes[nodes.length - 1]) { e.preventDefault(); nodes[0].focus(); }
        }
      };
      document.addEventListener('keydown', onKey);
      setTimeout(() => { try { getFocusable()[0]?.focus(); } catch (_) {} }, 30);
      return () => document.removeEventListener('keydown', onKey);
    }, []);
  }

  const StepList = ({ steps }) => (
    <ol style={S.list}>
      {steps.map((step, i) => (
        <li key={i} style={S.item}>
          <span style={S.num} aria-hidden="true">{i + 1}</span>
          <span>{step}</span>
        </li>
      ))}
    </ol>
  );

  const Modal = ({ labelId, onClose, children }) => {
    const ref = React.useRef(null);
    useFocusTrap(ref);
    React.useEffect(() => {
      const h = (e) => { if (e.key === 'Escape') onClose?.(); };
      document.addEventListener('keydown', h);
      return () => document.removeEventListener('keydown', h);
    }, [onClose]);
    return (
      <div style={S.overlay} role="presentation" onClick={(e) => { if (e.target === e.currentTarget) onClose?.(); }}>
        <div ref={ref} role="dialog" aria-modal="true" aria-labelledby={labelId} style={S.dialog}>
          <button type="button" style={S.closeBtn} onClick={onClose} aria-label="Close">×</button>
          {children}
        </div>
      </div>
    );
  };

  const PrePromptModal = ({ onContinue, onClose }) => (
    <Modal labelId="perm-pre-heading" onClose={onClose}>
      <h2 id="perm-pre-heading" style={S.heading}>Your browser needs to access your camera and microphone</h2>
      <p style={S.subhead}>When the next box appears, please click <strong>Allow</strong>. This lets your teacher see and hear you during the lesson.</p>
      <StepList steps={[
        'Click the "Continue" button below.',
        'A box from your browser will appear asking about your camera and microphone.',
        'Click "Allow" in that box. The lesson will then start.',
      ]} />
      <button type="button" style={S.primary} onClick={onContinue}>Continue</button>
      <button type="button" style={S.secondary} onClick={onClose}>Not now</button>
      <p style={S.note}>We only use your camera and microphone during the lesson. We never record video without your permission.</p>
    </Modal>
  );

  const DeniedHelpModal = ({ browser, onRetry, onClose, standalone = false }) => {
    const info = INSTRUCTIONS[browser] || INSTRUCTIONS.other;
    return (
      <Modal labelId="perm-denied-heading" onClose={onClose}>
        <h2 id="perm-denied-heading" style={S.heading}>
          {standalone ? 'Camera and microphone help' : 'Your camera and microphone are blocked'}
        </h2>
        <p style={S.subhead}>
          {standalone
            ? `Here is how to make sure ${info.name} can use your camera and microphone for your lesson:`
            : `It looks like ${info.name} is not allowing this website to use your camera or microphone. Follow these steps to fix it:`}
        </p>
        <StepList steps={info.steps} />
        <button type="button" style={S.primary} onClick={onRetry}>
          {standalone ? 'Check now' : 'Try again'}
        </button>
        <button type="button" style={S.secondary} onClick={onClose}>Close</button>
        <p style={S.note}>Need more help? Ask someone nearby, or contact your teacher to reschedule.</p>
      </Modal>
    );
  };

  const PermissionHelp = ({ variant, onContinue, onRetry, onClose }) => {
    if (variant === 'pre-prompt') return <PrePromptModal onContinue={onContinue} onClose={onClose} />;
    // Detect browser once at the dispatch level so DeniedHelpModal stays a
    // pure presentational component — easier to test and no global coupling.
    const browser = (window.Meetings && window.Meetings.permission && window.Meetings.permission.detectBrowser) ? window.Meetings.permission.detectBrowser() : 'other';
    if (variant === 'standalone-help') return <DeniedHelpModal browser={browser} onRetry={onRetry} onClose={onClose} standalone={true} />;
    return <DeniedHelpModal browser={browser} onRetry={onRetry} onClose={onClose} />;
  };

  window.Meetings.ui.PermissionHelp = PermissionHelp;
})();
