import React, { useState, useEffect, useCallback, useRef, useLayoutEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { api } from '../services/api';
import TutorialRefinity from '../components/TutorialRefinity';
import { 
  AcademicCapIcon, 
  DocumentTextIcon, 
  CheckCircleIcon,
  ClockIcon,
  ArrowRightIcon,
  PencilIcon,
  XMarkIcon,
  CheckIcon,
  PlusIcon,
  TrashIcon,
  ArrowTopRightOnSquareIcon,
  ArrowsRightLeftIcon
} from '@heroicons/react/24/outline';
// import ReactDOM from 'react-dom';

interface TutorialTask {
  _id: string;
  content: string;
  weekNumber: number;
  translationBrief?: string;
  imageUrl?: string;
  imageAlt?: string;
  imageSize?: number;
  imageAlignment?: 'left' | 'center' | 'right' | 'portrait-split';
  position?: number;
}

interface TutorialWeek {
  weekNumber: number;
  translationBrief?: string;
  tasks: TutorialTask[];
}

interface UserSubmission {
  _id: string;
  transcreation: string;
  status: string;
  score: number;
  groupNumber?: number;
  isOwner?: boolean;
  userId?: {
    _id: string;
    username: string;
  };
  voteCounts: {
    '1': number;
    '2': number;
    '3': number;
  };
}

const TutorialTasks: React.FC = () => {
  const [selectedWeek, setSelectedWeek] = useState<number>(() => {
    const savedWeek = localStorage.getItem('selectedTutorialWeek');
    return savedWeek ? parseInt(savedWeek) : 1;
  });
  const [isWeekTransitioning, setIsWeekTransitioning] = useState(false);
  const [tutorialTasks, setTutorialTasks] = useState<TutorialTask[]>([]);
  const [tutorialWeek, setTutorialWeek] = useState<TutorialWeek | null>(null);
  const [userSubmissions, setUserSubmissions] = useState<{[key: string]: UserSubmission[]}>({});
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState<{[key: string]: boolean}>({});
  const [isWeekHidden, setIsWeekHidden] = useState<boolean>(false);
  const [translationText, setTranslationText] = useState<{[key: string]: string}>({});
  const [mutatingTaskId, setMutatingTaskId] = useState<string | null>(null);
  const [spacerHeights, setSpacerHeights] = useState<{[key: string]: number}>({});
  
  const [expandedSections, setExpandedSections] = useState<{[key: string]: boolean}>({});
  const cardRefs = useRef<{[key: string]: HTMLDivElement | null}>({});
  const briefRef = useRef<HTMLDivElement | null>(null);
  const groupDocRef = useRef<HTMLDivElement | null>(null);
  const listRef = useRef<HTMLDivElement | null>(null);
  const submissionsGridRefs = useRef<{[key: string]: HTMLDivElement | null}>({});
  const submissionsContainerRefs = useRef<{[key: string]: HTMLDivElement | null}>({});
  const withPreservedScroll = useRef<(fn: () => void) => void>();
  const pendingUnlocksRef = useRef<Set<string>>(new Set());
  const lastPreHeightRef = useRef<{[key: string]: number}>({});
  const disableCompensationRef = useRef<Set<string>>(new Set());

  const setGlobalAnchorDisabled = (disabled: boolean) => {
    try {
      if (disabled) {
        document.documentElement.style.setProperty('overflow-anchor', 'none');
        document.body.style.setProperty('overflow-anchor', 'none');
      } else {
        document.documentElement.style.removeProperty('overflow-anchor');
        document.body.style.removeProperty('overflow-anchor');
      }
    } catch {}
  };

  // Last-resort scroll freeze during tiny mutation window (no visual/layout change)
  const scrollLockState = useRef<{ y: number } | null>(null);
  const freezeScroll = () => {
    try {
      if (scrollLockState.current) return; // already frozen
      const y = window.scrollY;
      scrollLockState.current = { y };
      try { console.log('[Trace] Safari:freezeScroll', { y }); } catch {}
      const body = document.body as HTMLElement;
      body.style.position = 'fixed';
      body.style.top = `-${y}px`;
      body.style.width = '100%';
      body.style.overflowY = 'scroll';
    } catch {}
  };
  const unfreezeScroll = () => {
    try {
      const state = scrollLockState.current;
      if (!state) return;
      const body = document.body as HTMLElement;
      body.style.position = '';
      body.style.top = '';
      body.style.width = '';
      body.style.overflowY = '';
      window.scrollTo(0, state.y);
      scrollLockState.current = null;
      try { console.log('[Trace] Safari:unfreezeScroll'); } catch {}
    } catch {}
  };

  // Minimal, local scroll-stability helpers for submit/delete
  // Basic UA check; Chrome on iOS uses WKWebView but includes 'CriOS'
  const isSafari = typeof navigator !== 'undefined' && /Safari\//.test(navigator.userAgent) && !/Chrome\//.test(navigator.userAgent) && !/CriOS\//.test(navigator.userAgent);
  const SAFARI_FREEZE_ENABLED = false; // disable body-freeze so scroll compensation can apply

  const lockListHeight = () => {
    const el = listRef.current;
    if (!el) return;
    const h = el.getBoundingClientRect().height;
    el.style.minHeight = `${h}px`;
    el.style.height = `${h}px`;
    el.style.overflow = 'hidden';
    try { console.log('[Trace] lockListHeight', { h }); } catch {}
  };
  const unlockListHeight = () => {
    const el = listRef.current;
    if (!el) return;
    el.style.overflow = '';
    el.style.height = '';
    el.style.minHeight = '';
    try { console.log('[Trace] unlockListHeight'); } catch {}
  };

  const lockCardHeightById = (id: string) => {
    const el = cardRefs.current[id];
    if (!el) return;
    const h = el.getBoundingClientRect().height;
    el.style.minHeight = `${h}px`;
    el.style.height = `${h}px`;
    el.style.overflow = 'hidden';
    try { console.log('[Trace] lockCardHeight', { id, h }); } catch {}
  };
  const unlockCardHeightById = (id: string) => {
    const el = cardRefs.current[id];
    if (!el) return;
    el.style.overflow = '';
    el.style.height = '';
    el.style.minHeight = '';
    try { console.log('[Trace] unlockCardHeight', { id }); } catch {}
  };

  const lockGridHeightById = (id: string) => {
    const el = submissionsGridRefs.current[id];
    if (!el) return;
    const h = el.getBoundingClientRect().height;
    el.style.minHeight = `${h}px`;
    el.style.height = `${h}px`;
    el.style.overflow = 'hidden';
    try { console.log('[Trace] lockGridHeight', { id, h }); } catch {}
  };
  const unlockGridHeightById = (id: string) => {
    const el = submissionsGridRefs.current[id];
    if (!el) return;
    el.style.overflow = '';
    el.style.height = '';
    el.style.minHeight = '';
    try { console.log('[Trace] unlockGridHeight', { id }); } catch {}
  };

  // No-op container height locks (reverted)
  const lockContainerHeightById = (_id: string) => {};
  const unlockContainerHeightById = (_id: string) => {};

  // (removed) ResizeObserver scroll compensator

  const withPreservedCardOffset = (taskId: string, fn: () => void) => {
    // If scroll is frozen, avoid additional scroll adjustments that can fight WebKit
    if (scrollLockState.current) {
      fn();
      return;
    }
    if (disableCompensationRef.current.has(taskId)) {
      fn();
      return;
    }
    if ((lastPreHeightRef.current[taskId] || 0) === 0) {
      fn();
      return;
    }
    const el = cardRefs.current[taskId];
    const topBefore = el ? el.getBoundingClientRect().top : null;
    const scrollYBefore = window.scrollY;
    fn();
    requestAnimationFrame(() => {
      const topAfter = el ? el.getBoundingClientRect().top : null;
      if (topBefore !== null && topAfter !== null) {
        const delta = topAfter - topBefore;
        const clampedDelta = Math.max(-150, Math.min(150, delta));
        const allowComp = isSafari ? Math.abs(clampedDelta) > 0 : true;
        if (delta !== 0 && allowComp) {
          try { console.log('[Trace] ScrollPreserve', { taskId, delta, topBefore, topAfter, scrollYBefore }); } catch {}
          // Invert clamped delta to counteract element movement (keep card anchored)
          window.scrollBy(0, -clampedDelta);
        }
      } else {
        window.scrollTo(0, scrollYBefore);
      }
    });
  };

  // Initialize scroll preservation helper once
  useLayoutEffect(() => {
    withPreservedScroll.current = (fn: () => void) => {
      try {
        const y = window.scrollY;
        fn();
        // Restore scroll position after DOM updates with multiple frames
        requestAnimationFrame(() => {
          requestAnimationFrame(() => {
            requestAnimationFrame(() => {
              window.scrollTo(0, y);
            });
          });
        });
      } catch {
        fn();
      }
    };
  }, []);

  // Measure static containers once to avoid reflow jumps (Week 1 only prominent)

  // Move a task up or down by normalizing positions for the current visible list (weeks 4–6 only)
  const moveTask = async (taskId: string, direction: 'up' | 'down') => {
    try {
      const viewMode = (localStorage.getItem('viewMode') || 'auto');
      const actualRole = (JSON.parse(localStorage.getItem('user') || '{}').role);
      const isAdmin = viewMode === 'student' ? false : actualRole === 'admin';
      if (!isAdmin || selectedWeek < 4) return;
      // Build ordered list for the current week from what is rendered
      const current = tutorialTasks.filter(t => t.weekNumber === selectedWeek);
      const index = current.findIndex(t => t._id === taskId);
      if (index === -1) return;
      const targetIndex = direction === 'up' ? index - 1 : index + 1;
      if (targetIndex < 0 || targetIndex >= current.length) return;

      // Normalize positions to 0..n-1 based on current screen order
      const normalized = current.map((t, i) => ({ id: t._id, position: i }));
      // Swap the two entries (calculate new positions first)
      const posA = normalized[index].position;
      const posB = normalized[targetIndex].position;
      normalized[index].position = posB;
      normalized[targetIndex].position = posA;

      // Optimistic UI update: swap in local state immediately for smoother UX
      // const prevState = tutorialTasks; // not used
      setTutorialTasks((prev) => {
        const next = [...prev];
        // find actual indices in full list and swap their relative order by updating their position fields
        const aId = normalized[index].id;
        const bId = normalized[targetIndex].id;
        return next.map(item => {
          if (item._id === aId) return { ...item, position: posB } as any;
          if (item._id === bId) return { ...item, position: posA } as any;
          return item;
        });
      });

      // Send both updates in parallel; if either fails, revert then refetch
      await Promise.all([
        api.put(`/api/auth/admin/tutorial-tasks/${normalized[index].id}/position`, { position: posB }),
        api.put(`/api/auth/admin/tutorial-tasks/${normalized[targetIndex].id}/position`, { position: posA })
      ]);
      // Light refresh to ensure list order is consistent with server
      fetchTutorialTasks(false);
    } catch (error) {
      console.error('Reorder failed', error);
    }
  };

  
  const [selectedGroups, setSelectedGroups] = useState<{[key: string]: number}>({});
  
  const GroupDocSection: React.FC<{ weekNumber: number }> = ({ weekNumber }) => {
    const containerRef = useRef<HTMLDivElement | null>(null);
    const [group, setGroup] = useState<number>(() => {
      const saved = localStorage.getItem(`tutorial_group_${weekNumber}`);
      return saved ? parseInt(saved) : 1;
    });
    const [creating, setCreating] = useState(false);
    const [docs, setDocs] = useState<any[]>([]);
    const [urlInput, setUrlInput] = useState<string>('');
    const [errorMsg, setErrorMsg] = useState<string>('');
    const [copiedLink, setCopiedLink] = useState<string>('');
    const viewMode = (localStorage.getItem('viewMode') || 'auto');
    const actualRole = (JSON.parse(localStorage.getItem('user') || '{}').role);
    const isAdmin = viewMode === 'student' ? false : actualRole === 'admin';
    const isDocsFetchInFlightRef = useRef(false);

    const CopySquaresIcon: React.FC<{ className?: string }> = ({ className }) => (
      <svg className={className || 'h-4 w-4'} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg">
        <rect x="8" y="8" width="12" height="12" rx="2"/>
        <rect x="4" y="4" width="12" height="12" rx="2"/>
      </svg>
    );

    const loadDocs = useCallback(async () => {
      try {
        // throttle fetch during and just after mutations to avoid reflow interference
        if (mutatingTaskId) {
          try { console.log('[Trace] Docs:skipDuringMutate', { weekNumber, mutatingTaskId }); } catch {}
          setTimeout(() => { if (!mutatingTaskId) loadDocs(); }, 600);
          return;
        }
        if (isDocsFetchInFlightRef.current) {
          try { console.log('[Trace] Docs:skipInFlight', { weekNumber }); } catch {}
          return;
        }
        isDocsFetchInFlightRef.current = true;
        try { console.log('[Trace] Docs:fetch', { weekNumber }); } catch {}
        const resp = await api.get(`/api/docs/list?weekNumber=${weekNumber}`);
        setDocs(resp.data?.docs || []);
      } catch (e) {
        setDocs([]);
      } finally {
        isDocsFetchInFlightRef.current = false;
      }
    }, [weekNumber, mutatingTaskId]);

    useEffect(() => { loadDocs(); }, [loadDocs]);

    const current = docs.find(d => d.groupNumber === group);

    const createDoc = async () => {
      try {
        setCreating(true);
        setErrorMsg('');
        const url = urlInput.trim();
        if (!url) {
          setErrorMsg('Please paste a Google Doc link.');
          return;
        }
        const isValid = /docs\.google\.com\/document\/d\//.test(url);
        if (!isValid) {
          setErrorMsg('Provide a valid Google Doc link (docs.google.com/document/d/...).');
          return;
        }
        await api.post('/api/docs/create', { weekNumber, groupNumber: group, docUrl: url });
        await loadDocs();
        setUrlInput('');
      } finally {
        setCreating(false);
      }
    };

    const copyLink = async (link: string) => {
      try {
        await navigator.clipboard.writeText(link);
        // Persist until refresh: do not clear after timeout
        setCopiedLink(link);
      } catch {}
    };

    useEffect(() => {
      const el = containerRef.current;
      if (!el) return;
      if (mutatingTaskId) {
        const h = el.getBoundingClientRect().height;
        try { console.log('[Trace] Docs:lockHeight', { h }); } catch {}
        el.style.minHeight = `${h}px`;
        el.style.height = `${h}px`;
        el.style.overflow = 'hidden';
      } else {
        el.style.minHeight = '';
        el.style.height = '';
        el.style.overflow = '';
        try { console.log('[Trace] Docs:unlockHeight'); } catch {}
      }
    }, [mutatingTaskId]);

    return (
      <div ref={containerRef}>
        {/* Top control row */}
        {isAdmin && (
          <div className="mb-4 max-w-2xl">
            <label className="text-sm text-gray-700 block mb-1">Group</label>
            <select
              value={group}
              onChange={(e) => {
                const g = parseInt(e.target.value);
                setGroup(g);
                localStorage.setItem(`tutorial_group_${weekNumber}`, String(g));
              }}
              className="w-full px-3 py-2 border rounded-md text-sm"
            >
              {[1,2,3,4,5,6,7,8].map(g => <option key={g} value={g}>Group {g}</option>)}
            </select>
          </div>
        )}

        {/* Replace / Add link inline editor */}
        {isAdmin && (
          <div className="mb-4 max-w-2xl">
            <div className="flex items-center gap-2">
              <input
                type="url"
                value={urlInput}
                onChange={(e) => { setUrlInput(e.target.value); setErrorMsg(''); }}
                placeholder="Paste Google Doc link (docs.google.com/document/d/...)"
                className="flex-1 px-3 py-2 border border-gray-300 rounded-md text-sm"
              />
              <button onClick={createDoc} disabled={creating} className="relative inline-flex items-center justify-center gap-2 px-4 py-2 rounded-2xl text-sm font-medium text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 shadow-[inset_0_1px_0_rgba(255,255,255,0.6),inset_0_-1px_0_rgba(0,0,0,0.12)] bg-sky-600/70 disabled:bg-gray-400">{creating ? 'Saving…' : (current ? 'Save new link' : 'Add Doc Link')}</button>
            </div>
            {errorMsg && <div className="mt-1 text-xs text-red-600">{errorMsg}</div>}
          </div>
        )}

        {/* All groups table */}
        <div className="mt-6 max-w-2xl">
          <h5 className="text-sm font-semibold text-gray-800 uppercase tracking-wide mb-2">All Groups</h5>
          <div className="overflow-hidden rounded-lg border border-gray-200">
            <table className="min-w-full text-sm">
              <thead className="bg-gray-50 text-gray-600">
                <tr>
                  <th className="px-4 py-2 text-left">Group</th>
                  <th className="px-4 py-2 text-left">Actions</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-gray-200">
                {docs.length === 0 && (
                  <tr><td colSpan={2} className="px-4 py-3 text-gray-500">No group docs yet.</td></tr>
                )}
                {docs.map(d => (
                  <tr key={d._id}>
                    <td className="px-4 py-3">Group {d.groupNumber}</td>
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-4">
                        <a href={d.docUrl} target="_blank" rel="noreferrer" className="inline-flex items-center gap-1 text-ui-neonBlue">
                          <ArrowTopRightOnSquareIcon className="h-4 w-4" /> Open
                        </a>
                        <button onClick={() => copyLink(d.docUrl)} className="inline-flex items-center gap-1 text-ui-neonBlue">
                          <CopySquaresIcon className="h-4 w-4" />
                          <span className="inline-block w-14 text-left">{copiedLink === d.docUrl ? 'Copied' : 'Copy'}</span>
                        </button>
                        {isAdmin && (
                          <>
                            <button onClick={() => { setGroup(d.groupNumber); setUrlInput(d.docUrl || ''); }} className="inline-flex items-center gap-1 text-gray-700">
                            <ArrowsRightLeftIcon className="h-4 w-4" /> Edit
                          </button>
                            <button
                              onClick={async () => {
                                try {
                                  await api.delete(`/api/docs/${d._id}`);
                                  await loadDocs();
                                } catch (e) {
                                  console.error('Delete failed', e);
                                }
                              }}
                              className="inline-flex items-center gap-1 text-red-600"
                            >
                              <TrashIcon className="h-4 w-4" /> Delete
                            </button>
                          </>
                        )}
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    );
  };

  // Basic inline formatting helpers (bold/italic via simple markdown) for weeks 4–6
  const renderFormatted = (text: string) => {
    const escape = (s: string) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
    // Auto-linker: supports [label](url), plain URLs, and www.* without touching existing href attributes
    const html = escape(text)
      // Markdown-style links: [label](https://example.com)
      .replace(/\[([^\]]+?)\]\((https?:\/\/[^\s)]+)\)/g, '<a class="text-indigo-600 underline" href="$2" target="_blank" rel="noopener noreferrer">$1</a>')
      // Plain URLs with protocol, avoid matching inside attributes (require a non-attribute preceding char)
      .replace(/(^|[^=\"'\/:])(https?:\/\/[^\s<]+)/g, (m, p1, url) => `${p1}<a class="text-indigo-600 underline" href="${url}" target="_blank" rel="noopener noreferrer">${url}</a>`)
      // www.* domains (prepend https://), also avoid attributes
      .replace(/(^|[^=\"'\/:])(www\.[^\s<]+)/g, (m, p1, host) => `${p1}<a class="text-indigo-600 underline" href="https://${host}" target="_blank" rel="noopener noreferrer">${host}</a>`)
      .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
      .replace(/\*(.+?)\*/g, '<em>$1</em>')
      .replace(/\n/g, '<br/>');
    return <span dangerouslySetInnerHTML={{ __html: html.replace(/text-indigo-600/g, 'text-ui-neonBlue').replace(/text-indigo-900/g, 'text-ui-text') }} />;
  };

  const applyLinkFormat = (
    elementId: string,
    current: string,
    setValue: (v: string) => void
  ) => {
    const urlInput = window.prompt('Enter URL (e.g., https://example.com):');
    if (!urlInput) return;
    // Sanitize URL: ensure protocol, and strip accidental trailing quotes/attributes pasted from elsewhere
    let url = /^https?:\/\//i.test(urlInput) ? urlInput : `https://${urlInput}`;
    url = url.replace(/["'>)\s]+$/g, '');
    const el = document.getElementById(elementId) as HTMLTextAreaElement | null;
    if (!el) {
      setValue(`${current}[link](${url})`);
      return;
    }
    const start = el.selectionStart ?? current.length;
    const end = el.selectionEnd ?? current.length;
    const before = current.slice(0, start);
    const selection = current.slice(start, end) || 'link';
    const after = current.slice(end);
    setValue(`${before}[${selection}](${url})${after}`);
    // Restore focus and selection
    setTimeout(() => {
      el.focus();
      const newPos = before.length + selection.length + 4 + url.length + 2; // rough caret placement
      try { el.setSelectionRange(newPos, newPos); } catch {}
    }, 0);
  };

  const applyInlineFormat = (
    elementId: string,
    current: string,
    setValue: (v: string) => void,
    wrapper: '**' | '*'
  ) => {
    const el = document.getElementById(elementId) as HTMLTextAreaElement | null;
    if (!el) {
      setValue(current + wrapper + wrapper);
      return;
    }
    const start = el.selectionStart ?? current.length;
    const end = el.selectionEnd ?? current.length;
    const before = current.slice(0, start);
    const selection = current.slice(start, end);
    const after = current.slice(end);
    const next = `${before}${wrapper}${selection}${wrapper}${after}`;
    setValue(next);
    setTimeout(() => {
      try {
        el.focus();
        el.selectionStart = start + wrapper.length;
        el.selectionEnd = end + wrapper.length;
      } catch {}
    }, 0);
  };

  const [editingTask, setEditingTask] = useState<string | null>(null);
  const [editingBrief, setEditingBrief] = useState<{[key: number]: boolean}>({});
  const [addingTask, setAddingTask] = useState<boolean>(false);
  const [addingImage, setAddingImage] = useState<boolean>(false);
  const [addingRevision, setAddingRevision] = useState<boolean>(false);
  const [revisionAdded, setRevisionAdded] = useState<boolean>(false);
  const [hasRevisionTasks, setHasRevisionTasks] = useState<boolean>(false);
  
  // Check if Deep Revision tasks exist for the current week
  React.useEffect(() => {
    const checkForRevisionTasks = async () => {
      if (selectedWeek < 5) {
        setHasRevisionTasks(false);
        return;
      }
      try {
        // Use the same API base detection as other parts of the app
        const base = (((api.defaults as any)?.baseURL as string) || '').replace(/\/$/, '');
        const tasksUrl = `${base}/api/tutorial-refinity/tasks?weekNumber=${selectedWeek}`;
        const user = JSON.parse(localStorage.getItem('user') || '{}');
        const headers: any = {};
        if (user.name) headers['x-user-name'] = user.name;
        if (user.email) headers['x-user-email'] = user.email;
        if (user.role === 'admin') {
          headers['x-user-role'] = 'admin';
          headers['user-role'] = 'admin';
        }
        const resp = await fetch(tasksUrl, { headers });
        const data: any[] = await resp.json().catch(()=>[]);
        const hasTasks = Array.isArray(data) && data.length > 0;
        setHasRevisionTasks(hasTasks);
        // If tasks exist, automatically show the revision module
        if (hasTasks) {
          setRevisionAdded(true);
          // Also save to localStorage for consistency
          try {
            localStorage.setItem(`tutorial_revision_added_week_${selectedWeek}`, 'true');
          } catch (e) {
            // Ignore localStorage errors
          }
        }
      } catch (e) {
        console.warn('Failed to check for revision tasks:', e);
        setHasRevisionTasks(false);
      }
    };
    
    checkForRevisionTasks();
  }, [selectedWeek]);
  
  // Initialize and update revisionAdded state from localStorage (Safari-compatible)
  // Use useEffect instead of useState initializer for better Safari compatibility
  React.useEffect(() => {
    const checkRevisionState = () => {
      try {
        const saved = localStorage.getItem(`tutorial_revision_added_week_${selectedWeek}`);
        const isAdded = saved === 'true';
        // Only set from localStorage if tasks don't exist (to avoid overriding the auto-show logic)
        if (!hasRevisionTasks) {
          setRevisionAdded(isAdded);
        }
      } catch (e) {
        // Safari might block localStorage in some contexts, fallback to false
        if (!hasRevisionTasks) {
          setRevisionAdded(false);
        }
      }
    };
    
    // Check immediately
    checkRevisionState();
    
    // Also check after a short delay for Safari (in case localStorage isn't ready immediately)
    const timeoutId = setTimeout(checkRevisionState, 100);
    
    return () => clearTimeout(timeoutId);
  }, [selectedWeek, hasRevisionTasks]);
  const [editForm, setEditForm] = useState<{
    content: string;
    translationBrief: string;
    imageUrl: string;
    imageAlt: string;
  }>({
    content: '',
    translationBrief: '',
    imageUrl: '',
    imageAlt: ''
  });
  const [imageForm, setImageForm] = useState<{
    imageUrl: string;
    imageAlt: string;
    imageSize: number;
  imageAlignment: 'left' | 'center' | 'right' | 'portrait-split';
  }>({
    imageUrl: '',
    imageAlt: '',
    imageSize: 200,
    imageAlignment: 'center'
  });
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [uploading, setUploading] = useState(false);
  const [saving, setSaving] = useState(false);
  const navigate = useNavigate();

  const weeks = [1, 2, 3, 4, 5];
  const isAdmin = (() => {
    try {
      const viewMode = (localStorage.getItem('viewMode')||'auto');
      const role = JSON.parse(localStorage.getItem('user')||'{}').role;
      return (viewMode !== 'student') && role === 'admin';
    } catch { return false; }
  })();

  const handleWeekChange = async (week: number) => {
    setIsWeekTransitioning(true);
    
    // Clear existing data first
    setTutorialTasks([]);
    setTutorialWeek(null);
    setUserSubmissions({});
    
    // Update state and localStorage
    setSelectedWeek(week);
    localStorage.setItem('selectedTutorialWeek', week.toString());
    
    // Force a small delay to ensure state is updated
    await new Promise(resolve => setTimeout(resolve, 50));
    
    // Wait for actual content to load before ending animation
    try {
      // Fetch new week's data with the updated selectedWeek
      let response;
      try {
        response = await api.get(`/api/search/tutorial-tasks/${week}`);
      } catch (e) {
        // Soft retry once on transient errors
        response = await api.get(`/api/search/tutorial-tasks/${week}`);
      }
      
      if (response.data) {
        const tasks = response.data;
        console.log('Fetched tasks for week', week, ':', tasks);
        
        // Ensure tasks are sorted by title
        const sortedTasks = tasks.sort((a: any, b: any) => {
          const aNum = parseInt(a.title?.match(/ST (\d+)/)?.[1] || '0');
          const bNum = parseInt(b.title?.match(/ST (\d+)/)?.[1] || '0');
          return aNum - bNum;
        });
        
        setTutorialTasks(sortedTasks);
        
        // Use translation brief from tasks; if none and no tasks, only fall back to localStorage for admins
        let translationBrief = null as string | null;
        if (tasks.length > 0) {
          translationBrief = tasks[0].translationBrief;
        } else {
          const briefKey = `translationBrief_week_${week}`;
          const viewMode = (localStorage.getItem('viewMode')||'auto');
          const role = (JSON.parse(localStorage.getItem('user')||'{}').role);
          const isAdminView = (viewMode !== 'student') && role === 'admin';
          translationBrief = isAdminView ? localStorage.getItem(briefKey) : '';
        }
        
        const tutorialWeekData: TutorialWeek = {
          weekNumber: week,
          translationBrief: (translationBrief ?? undefined),
          tasks: tasks
        };
        setTutorialWeek(tutorialWeekData);
        
        // Fetch user submissions for the new tasks
        await fetchUserSubmissions(tasks);
      }
      
      // Wait longer for DOM to update with new content (especially for Week 2)
      const delay = week === 2 ? 400 : 200;
      await new Promise(resolve => setTimeout(resolve, delay));
    } catch (error) {
      console.error('Error loading week data:', error);
    } finally {
      // End transition after content is loaded and rendered
      setIsWeekTransitioning(false);
    }
  };

  useEffect(() => {
    const loadVisibility = async () => {
      try {
        const base = (((api.defaults as any)?.baseURL as string) || '').replace(/\/$/, '');
        const resp = await fetch(`${base}/api/admin/weeks/tutorial/${selectedWeek}/visibility`, {
          headers: {
            'Authorization': localStorage.getItem('token') ? `Bearer ${localStorage.getItem('token')}` : '',
            'user-role': 'admin'
          }
        });
        const json = await resp.json().catch(() => ({}));
        setIsWeekHidden(!!json?.week?.hidden);
      } catch (e) { /* noop */ }
    };
    loadVisibility();
  }, [selectedWeek]);

  const handleFileUpload = async (file: File): Promise<string> => {
    try {
      setUploading(true);
      
      // Convert file to data URL for display
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => {
          const dataUrl = reader.result as string;
          console.log('File uploaded:', file.name, 'Size:', file.size);
          console.log('Generated data URL:', dataUrl.substring(0, 50) + '...');
          resolve(dataUrl);
        };
        reader.onerror = () => {
          console.error('Error reading file:', reader.error);
          reject(reader.error);
        };
        reader.readAsDataURL(file);
      });
    } catch (error) {
      console.error('Error uploading file:', error);
      throw error;
    } finally {
      setUploading(false);
    }
  };

  const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      setSelectedFile(file);
    }
  };

  const toggleExpanded = (taskId: string) => {
    setExpandedSections(prev => ({
      ...prev,
      [taskId]: !prev[taskId]
    }));
  };

  const fetchUserSubmissions = useCallback(async (tasks: TutorialTask[]) => {
    try {
      const token = localStorage.getItem('token');
      const user = localStorage.getItem('user');
      
      if (!token || !user) {
        return;
      }

      const response = await api.get('/api/submissions/my-submissions');

      if (response.data && response.data.submissions) {
        const data = response.data;
        
        const groupedSubmissions: {[key: string]: UserSubmission[]} = {};
        
        // Initialize all tasks with empty arrays
        tasks.forEach(task => {
          groupedSubmissions[task._id] = [];
        });
        
        // Then populate with actual submissions and mark ownership for edit visibility after refresh/login
        if (data.submissions && Array.isArray(data.submissions)) {
          data.submissions.forEach((submission: any) => {
            const sourceTextId = submission.sourceTextId?._id || submission.sourceTextId;
            if (sourceTextId && groupedSubmissions[sourceTextId]) {
              groupedSubmissions[sourceTextId].push({ ...submission, isOwner: true });
            }
          });
        }
                  
        setUserSubmissions(groupedSubmissions);
      }
    } catch (error) {
      console.error('Error fetching user submissions:', error);
    }
  }, []);

  const fetchTutorialTasks = useCallback(async (showLoading = true) => {
    try {
      if (showLoading) {
        setLoading(true);
      }
      const token = localStorage.getItem('token');
      const user = localStorage.getItem('user');
      
      if (!token || !user) {
        navigate('/login');
        return;
      }

      let response;
      try {
        response = await api.get(`/api/search/tutorial-tasks/${selectedWeek}`);
      } catch (e) {
        response = await api.get(`/api/search/tutorial-tasks/${selectedWeek}`);
      }

      if (response.data) {
        const tasks = response.data;
        console.log('Fetched tasks:', tasks);
        console.log('Tasks with images:', tasks.filter((task: TutorialTask) => task.imageUrl));
        // Debug: Log each task's fields
        tasks.forEach((task: any, index: number) => {
          console.log(`Task ${index} fields:`, {
            _id: task._id,
            content: task.content,
            imageUrl: task.imageUrl,
            imageAlt: task.imageAlt,
            translationBrief: task.translationBrief,
            weekNumber: task.weekNumber,
            category: task.category
          });
          console.log(`Task ${index} imageUrl:`, task.imageUrl);
          console.log(`Task ${index} translationBrief:`, task.translationBrief);
        });
        
        // Ensure tasks are sorted by title to maintain correct order (Tutorial ST 1, Tutorial ST 2, etc.)
        const sortedTasks = tasks.sort((a: any, b: any) => {
          const aNum = parseInt(a.title?.match(/ST (\d+)/)?.[1] || '0');
          const bNum = parseInt(b.title?.match(/ST (\d+)/)?.[1] || '0');
          return aNum - bNum;
        });
        setTutorialTasks(sortedTasks);
        
        // Use translation brief from tasks or localStorage
        let translationBrief = null;
        if (tasks.length > 0) {
          translationBrief = tasks[0].translationBrief;
          console.log('Translation brief from task:', translationBrief);
        } else {
          // Check localStorage for brief if no tasks exist
          const briefKey = `translationBrief_week_${selectedWeek}`;
          translationBrief = localStorage.getItem(briefKey);
          console.log('Translation brief from localStorage:', translationBrief);
          console.log('localStorage key:', briefKey);
        }
        
        console.log('Final translation brief:', translationBrief);
        const tutorialWeekData: TutorialWeek = {
          weekNumber: selectedWeek,
          translationBrief: translationBrief,
          tasks: tasks
        };
        setTutorialWeek(tutorialWeekData);
        
        await fetchUserSubmissions(tasks);
      } else {
        console.error('Failed to fetch tutorial tasks');
      }
    } catch (error) {
      console.error('Error fetching tutorial tasks:', error);
    } finally {
      if (showLoading) {
        setLoading(false);
      }
    }
  }, [selectedWeek, fetchUserSubmissions, navigate]);

  useEffect(() => {
    const user = localStorage.getItem('user');
    if (!user) {
      navigate('/login');
      return;
    }
    fetchTutorialTasks();
  }, [fetchTutorialTasks, navigate]);

  // Listen for week reset events from page navigation
  useEffect(() => {
    const handleWeekReset = (event: CustomEvent) => {
      if (event.detail.page === 'tutorial-tasks') {
        console.log('Week reset event received for tutorial tasks');
        setSelectedWeek(event.detail.week);
        localStorage.setItem('selectedTutorialWeek', event.detail.week.toString());
      }
    };

    window.addEventListener('weekReset', handleWeekReset as EventListener);
    return () => {
      window.removeEventListener('weekReset', handleWeekReset as EventListener);
    };
  }, []);

  // Refresh submissions when user changes (after login/logout)
  useEffect(() => {
    const user = localStorage.getItem('user');
    if (user && tutorialTasks.length > 0) {
      fetchUserSubmissions(tutorialTasks);
    }
  }, [tutorialTasks, fetchUserSubmissions]);

  const handleSubmitTranslation = async (taskId: string, localText?: string, localGroup?: number) => {
    const text = localText || translationText[taskId];
    const group = localGroup || selectedGroups[taskId];
    
    if (!text?.trim()) {
      return;
    }

    if (!group) {
      return;
    }

    try {
      setMutatingTaskId(taskId);
      if (isSafari && SAFARI_FREEZE_ENABLED) {
        try { (document.activeElement as HTMLElement | null)?.blur?.(); } catch {}
        freezeScroll();
      }
      lockListHeight();
      lockCardHeightById(taskId);
      lockGridHeightById(taskId);
      withPreservedCardOffset(taskId, () => {
      setSubmitting({ ...submitting, [taskId]: true });
      });
      const user = JSON.parse(localStorage.getItem('user') || '{}');
      const t0 = performance.now();
      const response = await new Promise((resolve) => requestAnimationFrame(async () => {
        const res = await api.post('/api/submissions', {
        sourceTextId: taskId,
          transcreation: text,
          groupNumber: group,
        culturalAdaptations: [],
        username: user.name || 'Unknown'
      });
        resolve(res);
      })) as any;
      try { console.log('[Trace] Submit:response', { taskId, dt: Math.round(performance.now() - t0) }); } catch {}

      if (response.status >= 200 && response.status < 300) {
        const created = response.data;
        console.log('Submission created successfully:', created);

        // Optimistic append to avoid large reflow from full refetch
        setUserSubmissions(prev => {
          const current = prev[taskId] || [];
          // Put newest first like server returns
          const next = [{ ...created, isOwner: true }, ...current];
          return { ...prev, [taskId]: next };
        });

        // Defer state updates and minimal refetch
        // Measure grid height and set spacer before refetch to keep layout height constant
        const gridEl = submissionsGridRefs.current[taskId];
        const containerEl = submissionsContainerRefs.current[taskId];
        const cardEl = cardRefs.current[taskId];
        const preGridH = gridEl ? gridEl.getBoundingClientRect().height : 0;
        const preContH = containerEl ? containerEl.getBoundingClientRect().height : 0;
        const preCardH = cardEl ? cardEl.getBoundingClientRect().height : 0;
        const preHeight = preGridH > 0 ? preGridH : (preContH > 0 ? preContH : preCardH);
        try { console.log('[Trace] Submit:preHeights', { taskId, preGridH, preContH, preCardH, chosen: preHeight }); } catch {}
        if (!isSafari && preHeight > 0) setSpacerHeights(prev => ({ ...prev, [taskId]: preHeight }));
        if (isSafari) { try { console.log('[Trace] Submit:preHeights', { taskId, preGridH, preContH, preCardH, chosen: preHeight }); } catch {} }
        lastPreHeightRef.current[taskId] = preHeight;
        disableCompensationRef.current.add(taskId);
        withPreservedCardOffset(taskId, () => {
          try {
            const el = cardRefs.current[taskId];
            const topBefore = el ? el.getBoundingClientRect().top : null;
            console.log('[Trace] ScrollPreserve:before', { taskId, topBefore });
          } catch {}
          React.startTransition(() => {
        setTranslationText({ ...translationText, [taskId]: '' });
        setSelectedGroups({ ...selectedGroups, [taskId]: 0 });
          });
          if (!isSafari) {
            // Narrow refetch immediately for non-Safari
            pendingUnlocksRef.current.add(taskId);
            api.get(`/api/submissions/by-source/${taskId}`).then(r => {
              const list = (r.data && r.data.submissions) || [];
              setUserSubmissions(prev => ({ ...prev, [taskId]: list }));
              requestAnimationFrame(() => setSpacerHeights(prev => ({ ...prev, [taskId]: 0 })));
            }).catch(() => {
              requestAnimationFrame(() => setSpacerHeights(prev => ({ ...prev, [taskId]: 0 })));
            });
      } else {
            // Safari: delay refetch and keep locks until refetch completes
            pendingUnlocksRef.current.add(taskId);
            setTimeout(() => {
              api.get(`/api/submissions/by-source/${taskId}`).then(r => {
                const list = (r.data && r.data.submissions) || [];
                setUserSubmissions(prev => ({ ...prev, [taskId]: list }));
                requestAnimationFrame(() => {
                  // Allow scroll compensation at unlock time
                  disableCompensationRef.current.delete(taskId);
                  setSpacerHeights(prev => ({ ...prev, [taskId]: 0 }));
                  withPreservedCardOffset(taskId, () => {
                    unlockListHeight();
                    unlockCardHeightById(taskId);
                    unlockGridHeightById(taskId);
                    unlockContainerHeightById(taskId);
                    pendingUnlocksRef.current.delete(taskId);
                  });
                });
              }).catch(() => {
                requestAnimationFrame(() => {
                  disableCompensationRef.current.delete(taskId);
                  setSpacerHeights(prev => ({ ...prev, [taskId]: 0 }));
                  withPreservedCardOffset(taskId, () => {
                    unlockListHeight();
                    unlockCardHeightById(taskId);
                    unlockGridHeightById(taskId);
                    unlockContainerHeightById(taskId);
                    pendingUnlocksRef.current.delete(taskId);
                  });
                });
              });
            }, 300);
          }
        });
      } else {
        console.error('[Trace] Submit:Error', response.data);
      }
    } catch (error) {
      console.error('[Trace] Submit:Exception', error);
      
    } finally {
      withPreservedCardOffset(taskId, () => {
      setSubmitting({ ...submitting, [taskId]: false });
      });
      // release after a couple frames to let DOM settle (extra frame on Safari)
      const release = () => {
        // If a gated refetch is in-flight, defer unlock until postRefetch block
        if (pendingUnlocksRef.current.has(taskId)) return;
        unlockListHeight();
        unlockCardHeightById(taskId);
        unlockGridHeightById(taskId);
        unlockContainerHeightById(taskId);
        if (isSafari && SAFARI_FREEZE_ENABLED) unfreezeScroll();
      };
      if (isSafari) {
        requestAnimationFrame(() => requestAnimationFrame(() => requestAnimationFrame(release)));
      } else {
        requestAnimationFrame(() => requestAnimationFrame(release));
      }
      setMutatingTaskId(null);
    }
  };

  const [editingSubmission, setEditingSubmission] = useState<{id: string, text: string} | null>(null);
  const [editSubmissionText, setEditSubmissionText] = useState('');

  const handleEditSubmission = async (submissionId: string, currentText: string) => {
    setEditingSubmission({ id: submissionId, text: currentText });
    setEditSubmissionText(currentText);
  };

  const saveEditedSubmission = async () => {
    if (!editingSubmission || !editSubmissionText.trim()) return;

    try {
      const response = await api.put(`/api/submissions/${editingSubmission.id}`, {
        transcreation: editSubmissionText
      });

      if (response.status >= 200 && response.status < 300) {
  
        // Defer all state updates to prevent UI jumping
        React.startTransition(() => {
        setEditingSubmission(null);
        setEditSubmissionText('');
          fetchUserSubmissions(tutorialTasks);
        });
      } else {
        console.error('Failed to update translation:', response.data);
      }
    } catch (error) {
      console.error('Error updating translation:', error);

    }
  };

  const cancelEditSubmission = () => {
    setEditingSubmission(null);
    setEditSubmissionText('');
  };

  const handleDeleteSubmission = async (submissionId: string, taskId?: string) => {


    try {
      if (taskId) setMutatingTaskId(taskId);
      if (isSafari && SAFARI_FREEZE_ENABLED) { freezeScroll(); }
      lockListHeight();
      if (taskId) {
        lockCardHeightById(taskId);
        lockGridHeightById(taskId);
      }
      const t0 = performance.now();
      const response = await api.delete(`/api/submissions/${submissionId}`);

      if (response.status === 200) {
        try { console.log('[Trace] Delete:response', { taskId, submissionId, dt: Math.round(performance.now() - t0) }); } catch {}
  
        // Optimistic removal (disabled on Safari to prevent multi-phase jumps)
        if (taskId && !isSafari) {
          setUserSubmissions(prev => {
            const list = prev[taskId] || [];
            const next = list.filter(s => s._id !== submissionId);
            return { ...prev, [taskId]: next };
          });
        }

        // Defer refetch to prevent UI jumping and preserve scroll around DOM updates
        if (taskId) {
          const gridEl = submissionsGridRefs.current[taskId];
          const containerEl = submissionsContainerRefs.current[taskId];
          const cardEl = cardRefs.current[taskId];
          const preGridH = gridEl ? gridEl.getBoundingClientRect().height : 0;
          const preContH = containerEl ? containerEl.getBoundingClientRect().height : 0;
          const preCardH = cardEl ? cardEl.getBoundingClientRect().height : 0;
          const preHeight = preGridH > 0 ? preGridH : (preContH > 0 ? preContH : preCardH);
          lastPreHeightRef.current[taskId] = preHeight;
          try { console.log('[Trace] Delete:preHeights', { taskId, preGridH, preContH, preCardH, chosen: preHeight }); } catch {}
        }
        withPreservedCardOffset(taskId || '', () => {
          try {
            if (taskId) {
              const el = cardRefs.current[taskId];
              const topBefore = el ? el.getBoundingClientRect().top : null;
              console.log('[Trace] ScrollPreserve(del):before', { taskId, topBefore });
            }
          } catch {}
          React.startTransition(() => {
            // Narrow refetch: only this task's submissions
            if (taskId) {
              if (!isSafari) {
                const gridEl = submissionsGridRefs.current[taskId];
                const gridHeight = gridEl ? gridEl.getBoundingClientRect().height : 0;
                if (gridHeight > 0) setSpacerHeights(prev => ({ ...prev, [taskId]: gridHeight }));
                api.get(`/api/submissions/by-source/${taskId}`).then(r => {
                  const list = (r.data && r.data.submissions) || [];
                  setUserSubmissions(prev => ({ ...prev, [taskId]: list }));
                  requestAnimationFrame(() => setSpacerHeights(prev => ({ ...prev, [taskId]: 0 })));
                }).catch(() => {
                  requestAnimationFrame(() => setSpacerHeights(prev => ({ ...prev, [taskId]: 0 })));
                });
              }
            } else {
              // Fallback
              requestAnimationFrame(() => requestAnimationFrame(() => fetchUserSubmissions(tutorialTasks)));
            }
          });
        });
      } else {

      }
    } catch (error) {
      console.error('[Trace] Delete:Exception', error);

    }
    // let DOM settle then unlock (both list and card if id known)
    requestAnimationFrame(() => requestAnimationFrame(() => {
      if (isSafari && taskId) {
        // Hold locks until per-task refetch completes
        pendingUnlocksRef.current.add(taskId);
        setTimeout(() => {
          api.get(`/api/submissions/by-source/${taskId}`).then(r => {
            const list = (r.data && r.data.submissions) || [];
            setUserSubmissions(prev => ({ ...prev, [taskId]: list }));
          }).catch(() => {}).finally(() => {
            withPreservedCardOffset(taskId, () => {
              unlockListHeight();
              unlockCardHeightById(taskId);
              unlockGridHeightById(taskId);
              if (SAFARI_FREEZE_ENABLED) unfreezeScroll();
              pendingUnlocksRef.current.delete(taskId);
            });
            try {
              const el = cardRefs.current[taskId];
              const topAfter = el ? el.getBoundingClientRect().top : null;
              console.log('[Trace] ScrollPreserve(del):after', { taskId, topAfter });
            } catch {}
          });
        }, 300);
      } else {
        unlockListHeight();
        if (taskId) {
          unlockCardHeightById(taskId);
          unlockGridHeightById(taskId);
        }
        if (isSafari && SAFARI_FREEZE_ENABLED) { unfreezeScroll(); }
      }
      setMutatingTaskId(null);
    }));
  };

  const getStatusIcon = (status: string) => {
    switch (status) {
      case 'approved':
        return <CheckCircleIcon className="h-5 w-5 text-green-500" />;
      case 'pending':
        return <ClockIcon className="h-5 w-5 text-yellow-500" />;
      default:
        return <ClockIcon className="h-5 w-5 text-gray-500" />;
    }
  };

  const startEditing = (task: TutorialTask) => {
    setEditingTask(task._id);
    setEditForm({
      content: task.content,
      translationBrief: task.translationBrief || '',
      imageUrl: task.imageUrl || '',
      imageAlt: task.imageAlt || ''
    });
  };

  const startEditingBrief = () => {
    setEditingBrief(prev => ({ ...prev, [selectedWeek]: true }));
    setEditForm({
      content: '',
      translationBrief: tutorialWeek?.translationBrief || '',
      imageUrl: '',
      imageAlt: ''
    });
  };

  const startAddingBrief = () => {
    setEditingBrief(prev => ({ ...prev, [selectedWeek]: true }));
    setEditForm({
      content: '',
      translationBrief: '',
      imageUrl: '',
      imageAlt: ''
    });
  };

  const removeBrief = async () => {

    
    try {
      setSaving(true);
      const token = localStorage.getItem('token');
      const user = JSON.parse(localStorage.getItem('user') || '{}');
      
      // Check if user is admin
      if (user.role !== 'admin') {
  
        return;
      }

              const response = await api.put(`/api/auth/admin/tutorial-brief/${selectedWeek}`, {
        translationBrief: '',
        weekNumber: selectedWeek
      });

      if (response.status >= 200 && response.status < 300) {
        const briefKey = `translationBrief_week_${selectedWeek}`;
        localStorage.removeItem(briefKey);
        setEditForm((prev) => ({ ...prev, translationBrief: '' }));
        await fetchTutorialTasks();

      } else {
        console.error('Failed to remove translation brief:', response.data);
        
      }
    } catch (error) {
      console.error('Failed to remove translation brief:', error);
      
    } finally {
      setSaving(false);
    }
  };

  const cancelEditing = () => {
    setEditingTask(null);
    setEditingBrief(prev => ({ ...prev, [selectedWeek]: false }));
    setEditForm({
      content: '',
      translationBrief: '',
      imageUrl: '',
      imageAlt: ''
    });
    setSelectedFile(null);
  };

  const saveTask = async () => {
    if (!editingTask) return;
    
    try {
      setSaving(true);
      const token = localStorage.getItem('token');
      const user = JSON.parse(localStorage.getItem('user') || '{}');
      
      // Check if user is admin
      if (user.role !== 'admin') {

        return;
      }

      const updateData = {
        ...editForm,
        weekNumber: selectedWeek
      };
      console.log('Saving task with data:', updateData);
      
              const response = await api.put(`/api/auth/admin/tutorial-tasks/${editingTask}`, updateData);

              if (response.status >= 200 && response.status < 300) {
          await fetchTutorialTasks(false);
          setEditingTask(null);

        } else {
          console.error('Failed to update tutorial task:', response.data);
          
        }
    } catch (error) {
      console.error('Failed to update tutorial task:', error);
      
    } finally {
      setSaving(false);
    }
  };

  const saveBrief = async () => {
    try {
      setSaving(true);
      const user = JSON.parse(localStorage.getItem('user') || '{}');
      
      // Check if user is admin
      if (user.role !== 'admin') {
        return;
      }

      console.log('Saving brief for week:', selectedWeek);
      console.log('Brief content:', editForm.translationBrief);

      // Save brief by creating or updating the first task of the week
      if (tutorialTasks.length > 0) {
        const firstTask = tutorialTasks[0];
        console.log('Updating first task with brief:', firstTask._id);
        
        const response = await api.put(`/api/auth/admin/tutorial-tasks/${firstTask._id}`, {
          ...firstTask,
          translationBrief: editForm.translationBrief,
          weekNumber: selectedWeek
        });

        if (response.status >= 200 && response.status < 300) {
          console.log('Brief saved successfully');
          // Optimistic UI update
          const briefKey = `translationBrief_week_${selectedWeek}`;
          localStorage.setItem(briefKey, editForm.translationBrief);
          setTutorialWeek(prev => prev ? { ...prev, translationBrief: editForm.translationBrief } : prev);
          setEditingBrief(prev => ({ ...prev, [selectedWeek]: false }));
          // Background refresh
          fetchTutorialTasks(false);
        } else {
          console.error('Failed to save brief:', response.data);
        }
      } else {
        // If no tasks exist, save the brief to localStorage
        console.log('No tasks available to save brief to - saving to localStorage');
        const briefKey = `translationBrief_week_${selectedWeek}`;
        localStorage.setItem(briefKey, editForm.translationBrief);
        setEditingBrief(prev => ({ ...prev, [selectedWeek]: false }));
      }
    } catch (error) {
      console.error('Failed to update translation brief:', error);
    } finally {
      setSaving(false);
    }
  };

  const startAddingTask = () => {
    setAddingTask(true);
    setEditForm({
      content: '',
      translationBrief: '',
      imageUrl: '',
      imageAlt: ''
    });
  };

  const cancelAddingTask = () => {
    setAddingTask(false);
    setEditForm({
      content: '',
      translationBrief: '',
      imageUrl: '',
      imageAlt: ''
    });
    setSelectedFile(null);
  };

  const startAddingImage = () => {
    setAddingImage(true);
    setImageForm({
      imageUrl: '',
      imageAlt: '',
      imageSize: 200,
      imageAlignment: 'center'
    });
  };

  const cancelAddingImage = () => {
    setAddingImage(false);
    setImageForm({
      imageUrl: '',
      imageAlt: '',
      imageSize: 200,
      imageAlignment: 'center'
    });
  };

  const startAddingRevision = () => {
    setAddingRevision(true);
  };

  const cancelAddingRevision = () => {
    setAddingRevision(false);
  };

  const addRevision = () => {
    setRevisionAdded(true);
    setAddingRevision(false);
    try {
      localStorage.setItem(`tutorial_revision_added_week_${selectedWeek}`, 'true');
    } catch (e) {
      // Safari might block localStorage, but state is already updated
      console.warn('Failed to save revision state to localStorage:', e);
    }
  };

  const removeRevision = () => {
    // Only allow removing if no tasks exist
    if (!hasRevisionTasks) {
      setRevisionAdded(false);
      try {
        localStorage.removeItem(`tutorial_revision_added_week_${selectedWeek}`);
      } catch (e) {
        // Safari might block localStorage, but state is already updated
        console.warn('Failed to remove revision state from localStorage:', e);
      }
    } else {
      // If tasks exist, warn the admin that they need to delete tasks first
      alert('Cannot hide Deep Revision module while tasks exist. Please delete all tasks for this week first.');
    }
  };



  const saveNewTask = async () => {
    try {
      setSaving(true);
      const user = JSON.parse(localStorage.getItem('user') || '{}');
      
      // Check if user is admin
      if (user.role !== 'admin') {
        return;
      }

      // Allow either content or imageUrl, but not both empty
      if (!editForm.content.trim() && !editForm.imageUrl.trim()) {
        return;
      }

      console.log('Saving new task for week:', selectedWeek);
      console.log('Task content:', editForm.content);
      console.log('Image URL:', editForm.imageUrl);
      console.log('Image Alt:', editForm.imageAlt);

      const taskData = {
        title: `Week ${selectedWeek} Tutorial Task`,
        content: editForm.content,
        sourceLanguage: 'English',
        weekNumber: selectedWeek,
        category: 'tutorial',
        imageUrl: editForm.imageUrl || null,
        imageAlt: editForm.imageAlt || null,
        // Add imageSize and imageAlignment for image-only content
        ...(editForm.imageUrl && !editForm.content.trim() && { imageSize: 200 }),
        ...(editForm.imageUrl && !editForm.content.trim() && { imageAlignment: 'center' })
      };

      console.log('Task data being sent:', JSON.stringify(taskData, null, 2));

      console.log('Sending task data:', taskData);

              const response = await api.post('/api/auth/admin/tutorial-tasks', taskData);
      
      console.log('Task save response:', response.data);

      if (response.status >= 200 && response.status < 300) {
        console.log('Task saved successfully');
                  console.log('Saved task response:', response.data);
          console.log('Saved task response keys:', Object.keys(response.data || {}));
          console.log('Saved task response.task:', response.data?.task);
          console.log('Saved task response.task.imageUrl:', response.data?.task?.imageUrl);
          console.log('Saved task response.task.translationBrief:', response.data?.task?.translationBrief);
        await fetchTutorialTasks(false);
        setAddingTask(false);

              } else {
          console.error('Failed to add tutorial task:', response.data);
        }
      } catch (error) {
        console.error('Failed to add tutorial task:', error);
      } finally {
      setSaving(false);
    }
  };

  const saveNewImage = async () => {
    try {
      setSaving(true);
      const user = JSON.parse(localStorage.getItem('user') || '{}');
      
      // Check if user is admin
      if (user.role !== 'admin') {
        return;
      }

      if (!imageForm.imageUrl.trim()) {
        return;
      }

      const payload = {
        title: `Week ${selectedWeek} Image Task`,
        content: '', // Empty content for image-only task
        sourceLanguage: 'English',
        weekNumber: selectedWeek,
        category: 'tutorial',
        imageUrl: imageForm.imageUrl.trim(),
        imageAlt: imageForm.imageAlt.trim() || null,
        imageSize: imageForm.imageSize,
        imageAlignment: imageForm.imageAlignment
      };

      console.log('Saving new image task with payload:', payload);

      const response = await api.post('/api/auth/admin/tutorial-tasks', payload);

      if (response.data) {
        console.log('Image task saved successfully:', response.data);
        await fetchTutorialTasks(false);
        setAddingImage(false);
      } else {
        console.error('Failed to save image task');
      }
    } catch (error) {
      console.error('Failed to add image task:', error);
    } finally {
      setSaving(false);
    }
  };

  const deleteTask = async (taskId: string) => {

    
    try {
      const token = localStorage.getItem('token');
      const user = JSON.parse(localStorage.getItem('user') || '{}');
      
      // Check if user is admin
      if (user.role !== 'admin') {

        return;
      }

      const response = await api.delete(`/api/auth/admin/tutorial-tasks/${taskId}`);

      if (response.status >= 200 && response.status < 300) {
        await fetchTutorialTasks(false);
      } else {
        console.error('Failed to delete tutorial task:', response.data);
      }

      await fetchTutorialTasks(false);
    } catch (error) {
      console.error('Failed to delete task:', error);
    }
  };

  // Remove intrusive loading screen - just show content with loading state


  const GroupInputs: React.FC<{
    taskId: string;
    label: string;
    selectWidthClass: string;
    selectedGroup: number | '';
    onGroupChange: (n: number) => void;
    translationValue: string;
    onTranslationChange: (v: string) => void;
    submitting: boolean;
    onSubmit: () => void;
  }> = React.memo(({ taskId, label, selectWidthClass, selectedGroup, onGroupChange, translationValue, onTranslationChange, submitting, onSubmit }) => {
  return (
      <>
        <div className="mb-2">
          <label className="block text-xs font-medium text-gray-700 mb-1">{label}</label>
          <select
            value={selectedGroup || ''}
            onChange={(e) => {
              const v = parseInt(e.target.value);
              onGroupChange(Number.isNaN(v) ? ('' as any) : v);
            }}
            className={`${selectWidthClass} px-2 py-1 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white text-xs`}
          >
            <option value="">Choose...</option>
            {[1,2,3,4,5,6,7,8].map((g) => (<option key={g} value={g}>Group {g}</option>))}
          </select>
        </div>
        <div className="flex items-center justify-end space-x-2 mb-2">
          <button onClick={() => applyInlineFormat(`tutorial-translation-${taskId}`, translationValue || '', v => onTranslationChange(v), '**')} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded">B</button>
          <button onClick={() => applyInlineFormat(`tutorial-translation-${taskId}`, translationValue || '', v => onTranslationChange(v), '*')} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded italic">I</button>
          <button onClick={() => applyLinkFormat(`tutorial-translation-${taskId}`, translationValue || '', v => onTranslationChange(v))} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded">Link</button>
        </div>
        <textarea
          id={`tutorial-translation-${taskId}`}
          value={translationValue || ''}
          
          onChange={(e) => {
            onTranslationChange(e.target.value);
          }}
          className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white"
          style={{ height: '150px' }}
          rows={4}
          placeholder="Enter your group's translation here..."
        />
        <div className="flex justify-end mt-2">
          <button onClick={onSubmit} disabled={submitting} className="btn-primary disabled:bg-gray-400 text-white px-4 py-2 rounded-lg text-sm">{submitting ? 'Submitting...' : 'Submit Translation'}</button>
        </div>
      </>
    );
  }, (a, b) => (
    a.selectedGroup === b.selectedGroup &&
    a.translationValue === b.translationValue &&
    a.submitting === b.submitting &&
    a.label === b.label &&
    a.selectWidthClass === b.selectWidthClass &&
    a.taskId === b.taskId
  ));

  return (
    <div className="min-h-screen bg-white py-8">
      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
        {/* Header */}
        <div className="mb-8">
          <div className="flex items-center mb-4">
            <img src="/icons/tutorial tasks.svg" alt="Tutorial Tasks" className="h-8 w-8 mr-3" />
            <h1 className="text-3xl font-bold text-ui-text">Tutorial Tasks</h1>
          </div>
          <p className="text-ui-text/70">
            Complete weekly tutorial tasks with your group to practice collaborative translation skills.
          </p>
        </div>

        {/* Week Selector */}
        <div className="mb-6">
          <div className="flex space-x-3 overflow-x-auto pb-2">
            {weeks.map((week) => {
              const isActive = selectedWeek === week;
              return (
              <button
                key={week}
                onClick={() => handleWeekChange(week)}
                  className={`relative inline-flex items-center justify-center rounded-2xl px-4 py-1.5 whitespace-nowrap transition-all duration-300 ease-out ring-1 ring-inset ${isActive ? 'ring-white/50 backdrop-brightness-110 backdrop-saturate-150' : 'ring-white/30'} backdrop-blur-md isolate shadow-[inset_0_0.5px_0_rgba(255,255,255,0.5),inset_0_-1px_1.5px_rgba(0,0,0,0.12)]`}
                  style={{ background: 'rgba(255,255,255,0.10)' }}
                >
                  {/* Rim washes */}
                  <div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
                  {/* Soft glossy wash */}
                  <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
                  {/* Tiny hotspot near TL */}
                  <div className="pointer-events-none absolute rounded-full" style={{ width: '28px', height: '28px', left: '8px', top: '6px', background: 'radial-gradient(16px_16px_at_10px_10px,rgba(255,255,255,0.5),rgba(255,255,255,0)_60%)', opacity: 0.45 }} />
                  {/* Center darken for depth */}
                  {!isActive && (
                    <div className="pointer-events-none absolute inset-0 rounded-2xl" style={{ background: 'radial-gradient(120%_120%_at_50%_55%,rgba(0,0,0,0.04),rgba(0,0,0,0)_60%)', opacity: 0.9 }} />
                  )}
                  {/* Blue tint overlay to match brand */}
                  <div className={`pointer-events-none absolute inset-0 rounded-2xl ${isActive ? 'bg-sky-600/70 mix-blend-normal opacity-100' : 'bg-sky-500/30 mix-blend-overlay opacity-35'}`} />
                  <span className={`relative z-10 text-sm font-medium ${isActive ? 'text-white' : 'text-black'}`}>Week {week}</span>
              </button>
              );
            })}
          </div>
          {isAdmin && (
            <div className="mt-2 flex items-center gap-2">
              <span className="text-xs text-ui-text/70">Visibility</span>
              <label className="switch">
                <input type="checkbox" checked={isWeekHidden} onChange={async(e)=>{
                  try {
                    const base = (((api.defaults as any)?.baseURL as string) || '').replace(/\/$/,'');
                    const nextHidden = e.currentTarget.checked;
                    await fetch(`${base}/api/admin/weeks/tutorial/${selectedWeek}/visibility`,{ method:'PUT', headers:{ 'Content-Type':'application/json', 'Authorization': localStorage.getItem('token')?`Bearer ${localStorage.getItem('token')}`:'', 'user-role':'admin' }, body: JSON.stringify({ hidden: nextHidden }) });
                    setIsWeekHidden(nextHidden);
                    await fetchTutorialTasks(true);
                  } catch (err) { console.error(err);} 
                }}/>
                <span className="slider" />
              </label>
              <span className="text-xs">{isWeekHidden ? 'Hidden' : 'Shown'}</span>
            </div>
          )}
        </div>

                {/* Week Transition Loading Spinner */}
        {isWeekTransitioning && (
          <div className="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-50">
            <div className="bg-white rounded-lg shadow-lg p-4 flex items-center space-x-3">
              <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-ui-neonBlue"></div>
              <span className="text-gray-700 font-medium">Loading...</span>
            </div>
          </div>
        )}

        {!isWeekTransitioning && (
          <>
            {/* Translation Brief - Shown once at the top (hidden for students when week is hidden) */}
            {tutorialWeek && tutorialWeek.translationBrief && (!isWeekHidden || (isWeekHidden && isAdmin)) ? (
          <div ref={briefRef} className="bg-ui-panel rounded-lg p-6 mb-8 border border-ui-border shadow-sm">
            <div className="flex items-center justify-between mb-4">
              <div className="flex items-center space-x-3">
                <div className="relative p-2 rounded-2xl bg-white/10 backdrop-blur-md ring-1 ring-inset ring-white/30 shadow-[inset_0_0.5px_0_rgba(255,255,255,0.5),inset_0_-1px_1.5px_rgba(0,0,0,0.12)]">
                  <div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
                  <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
                  <div className="pointer-events-none absolute rounded-full" style={{ width: '20px', height: '20px', left: '6px', top: '6px', background: 'radial-gradient(12px_12px_at_10px_10px,rgba(255,255,255,0.5),rgba(255,255,255,0)_60%)', opacity: 0.45 }} />
                  <div className="pointer-events-none absolute inset-0 rounded-2xl" style={{ background: 'radial-gradient(120%_120%_at_50%_55%,rgba(0,0,0,0.04),rgba(0,0,0,0)_60%)', opacity: 0.9 }} />
                  <div className="pointer-events-none absolute inset-0 rounded-2xl bg-sky-500/30 mix-blend-overlay opacity-35" />
                  <DocumentTextIcon className="relative h-5 w-5 text-ui-text" />
                </div>
                <h3 className="text-ui-text font-semibold text-xl">Translation Brief</h3>
              </div>
              {JSON.parse(localStorage.getItem('user') || '{}').role === 'admin' && (
                <div className="flex items-center space-x-2">
                  {editingBrief[selectedWeek] ? (
                    <>
                      <button
                        onClick={saveBrief}
                        disabled={saving}
                        className="relative inline-flex items-center gap-2 px-3 py-1 rounded-2xl text-sm font-medium text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 shadow-[inset_0_1px_0_rgba(255,255,255,0.6),inset_0_-1px_0_rgba(0,0,0,0.12)] bg-sky-600/70"
                      >
                        {saving ? (
                          <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
                        ) : (
                          <CheckIcon className="h-4 w-4" />
                        )}
                      </button>
                      <button
                        onClick={cancelEditing}
                        className="relative inline-flex items-center gap-2 px-3 py-1 rounded-2xl text-sm font-medium text-black ring-1 ring-inset ring-white/30 backdrop-blur-md shadow-[inset_0_0.5px_0_rgba(255,255,255,0.5),inset_0_-1px_1.5px_rgba(0,0,0,0.12)] bg-white/10"
                      >
                        <XMarkIcon className="h-4 w-4" />
                      </button>
                    </>
                  ) : (
                    <>
                      <button
                        onClick={startEditingBrief}
                        className="bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 py-1 rounded-md transition-colors duration-200 text-sm"
                      >
                        <PencilIcon className="h-4 w-4" />
                      </button>
                      <button
                        onClick={() => removeBrief()}
                        className="bg-red-100 hover:bg-red-200 text-red-700 px-3 py-1 rounded-md transition-colors duration-200 text-sm"
                      >
                        <TrashIcon className="h-4 w-4" />
                      </button>
                    </>
                  )}
                </div>
              )}
            </div>
            {editingBrief[selectedWeek] ? (
              <div>
                <div className="flex items-center justify-end space-x-2 mb-2">
                  <button onClick={() => applyInlineFormat('tutorial-brief-input', editForm.translationBrief, v => setEditForm({ ...editForm, translationBrief: v }), '**')} className="px-2 py-1 text-xs bg-blue-100 text-ui-neonBlue rounded">B</button>
                  <button onClick={() => applyInlineFormat('tutorial-brief-input', editForm.translationBrief, v => setEditForm({ ...editForm, translationBrief: v }), '*')} className="px-2 py-1 text-xs bg-blue-100 text-ui-neonBlue rounded italic">I</button>
                  <button onClick={() => applyLinkFormat('tutorial-brief-input', editForm.translationBrief || '', v => setEditForm({ ...editForm, translationBrief: v }))} className="px-2 py-1 text-xs bg-blue-100 text-ui-neonBlue rounded">Link</button>
                </div>
              <textarea id="tutorial-brief-input"
                value={editForm.translationBrief}
                onChange={(e) => setEditForm({ ...editForm, translationBrief: e.target.value })}
                className="w-full p-4 border border-gray-300 rounded-lg text-gray-900 leading-relaxed text-base bg-white focus:ring-2 focus:ring-ui-neonBlue focus:border-ui-neonBlue"
                rows={6}
                placeholder="Enter translation brief..."
              />
              </div>
            ) : (
              <div className="text-ui-text leading-relaxed text-lg font-smiley whitespace-pre-wrap">{renderFormatted(tutorialWeek.translationBrief || '')}</div>
            )}

            {/* Group Google Doc (refined) */}
            {(() => { const hasDocs = !!localStorage.getItem(`tutorial_group_${selectedWeek}`) || (Array.isArray((tutorialWeek as any)?.groupDocs) && (tutorialWeek as any).groupDocs.length>0); const vm=(localStorage.getItem('viewMode')||'auto'); return hasDocs || (vm!== 'student'); })() && (
              <div ref={groupDocRef} className="mt-6 bg-ui-panel rounded-xl border border-ui-border shadow-sm">
              <div className="px-6 pt-6">
                <h4 className="text-2xl font-bold text-ui-text">Group Google Doc</h4>
                <p className="mt-2 text-ui-text/70">Open or share each group's working document.</p>
              </div>
              <div className="px-6 pb-4 pt-4 border-t border-gray-100">
              <GroupDocSection weekNumber={selectedWeek} />
              </div>
            </div>
            )}
            <div className="mt-4 p-3 bg-ui-bg rounded-lg">
              <p className="text-ui-text text-sm">
                <strong>Note:</strong> Tutorial tasks are completed as group submissions. Each group should collaborate to create a single translation per task.
              </p>
            </div>
          </div>
        ) : (
          // Show add brief button when no brief exists
          JSON.parse(localStorage.getItem('user') || '{}').role === 'admin' && (
            <div className="bg-ui-panel rounded-lg p-6 mb-8 border border-ui-border border-dashed shadow-sm">
              <div className="flex items-center justify-between mb-4">
                              <div className="flex items-center space-x-3">
                <div className="relative p-2 rounded-2xl bg-white/10 backdrop-blur-md ring-1 ring-inset ring-white/30 shadow-[inset_0_0.5px_0_rgba(255,255,255,0.5),inset_0_-1px_1.5px_rgba(0,0,0,0.12)]">
                  <div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
                  <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
                  <div className="pointer-events-none absolute inset-0 rounded-2xl bg-sky-500/30 mix-blend-overlay opacity-35" />
                  <DocumentTextIcon className="relative h-5 w-5 text-ui-text" />
                </div>
                <h3 className="text-ui-text font-semibold text-xl">Translation Brief</h3>
              </div>
                <button
                  onClick={startAddingBrief}
                  className="relative inline-flex items-center gap-2 px-4 py-2 rounded-2xl text-sm font-medium text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 shadow-[inset_0_1px_0_rgba(255,255,255,0.6),inset_0_-1px_0_rgba(0,0,0,0.12)] bg-sky-600/70"
                >
                  <PlusIcon className="h-5 w-5" />
                  <span className="font-medium">Add Brief</span>
                </button>
              </div>
              {editingBrief[selectedWeek] && (
                <div className="space-y-4">
                  <div className="flex items-center justify-end space-x-2">
                    <button onClick={() => applyInlineFormat('tutorial-brief-input', editForm.translationBrief, v => setEditForm({ ...editForm, translationBrief: v }), '**')} className="px-2 py-1 text-xs bg-blue-100 text-ui-neonBlue rounded">B</button>
                    <button onClick={() => applyInlineFormat('tutorial-brief-input', editForm.translationBrief, v => setEditForm({ ...editForm, translationBrief: v }), '*')} className="px-2 py-1 text-xs bg-blue-100 text-ui-neonBlue rounded italic">I</button>
                    <button onClick={() => applyLinkFormat('tutorial-brief-input', editForm.translationBrief || '', v => setEditForm({ ...editForm, translationBrief: v }))} className="px-2 py-1 text-xs bg-blue-100 text-ui-neonBlue rounded">Link</button>
                  </div>
                  <textarea
                    id="tutorial-brief-input"
                    value={editForm.translationBrief}
                    onChange={(e) => setEditForm({ ...editForm, translationBrief: e.target.value })}
                    className="w-full p-4 border border-ui-border rounded-lg text-ui-text leading-relaxed text-base bg-ui-panel focus:ring-2 focus:ring-ui-neonBlue focus:border-ui-neonBlue"
                    rows={6}
                    placeholder="Enter translation brief..."
                  />
                  <div className="flex justify-end space-x-2">
                    <button
                      onClick={saveBrief}
                      disabled={saving}
                      className="bg-ui-neonBlue hover:bg-ui-neonBlue/90 text-white px-6 py-3 rounded-lg font-medium flex items-center space-x-2 shadow-sm"
                    >
                      {saving ? (
                        <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
                      ) : (
                        <>
                          <CheckIcon className="h-5 w-5" />
                          <span className="font-medium">Save Brief</span>
                        </>
                      )}
                    </button>
                    <button
                      onClick={cancelEditing}
                      className="bg-gray-500 hover:bg-gray-600 text-white px-6 py-3 rounded-lg font-medium flex items-center space-x-2 shadow-sm"
                    >
                      <XMarkIcon className="h-5 w-5" />
                      <span className="font-medium">Cancel</span>
                    </button>
                  </div>
                </div>
              )}
            </div>
          )
        )}

        {/* Tutorial Tasks */}
        <div className="space-y-6">
          {/* Add New Tutorial Task Section */}
          {(() => { const u = JSON.parse(localStorage.getItem('user') || '{}'); const vm = (localStorage.getItem('viewMode')||'auto'); return vm === 'student' ? false : u.role === 'admin'; })() && (
            <div className="mb-8">
              {addingTask ? (
                <div className="bg-white rounded-lg p-6 border border-gray-200 shadow-sm">
                  <div className="flex items-center space-x-3 mb-4">
                    <div className="bg-gray-100 rounded-lg p-2">
                      <PlusIcon className="h-4 w-4 text-gray-600" />
                    </div>
                    <h4 className="text-gray-900 font-semibold text-lg">New Tutorial Task</h4>
                  </div>
                  <div className="space-y-4">
                    <div>
                      <label className="block text-sm font-medium text-gray-700 mb-2">
                        Task Content *
                      </label>
                      <div className="flex items-center justify-end space-x-2 mb-2">
                        <button onClick={() => applyInlineFormat('tutorial-newtask-input', editForm.content, v => setEditForm({ ...editForm, content: v }), '**')} className="px-2 py-1 text-xs bg-blue-100 text-ui-neonBlue rounded">B</button>
                        <button onClick={() => applyInlineFormat('tutorial-newtask-input', editForm.content, v => setEditForm({ ...editForm, content: v }), '*')} className="px-2 py-1 text-xs bg-blue-100 text-ui-neonBlue rounded italic">I</button>
                        <button onClick={() => applyLinkFormat('tutorial-newtask-input', editForm.content || '', v => setEditForm({ ...editForm, content: v }))} className="px-2 py-1 text-xs bg-blue-100 text-ui-neonBlue rounded">Link</button>
                      </div>
                      <textarea
                        id="tutorial-newtask-input"
                        value={editForm.content}
                        onChange={(e) => setEditForm({ ...editForm, content: e.target.value })}
                        className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-ui-neonBlue focus:border-ui-neonBlue bg-white"
                        rows={4}
                        placeholder="Enter tutorial task content..."
                      />
                    </div>
                    <div className="space-y-4">
                      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                          <label className="block text-sm font-medium text-gray-700 mb-2">
                            Image URL (Optional)
                          </label>
                          <input
                            type="url"
                            value={editForm.imageUrl}
                            onChange={(e) => setEditForm({ ...editForm, imageUrl: e.target.value })}
                            className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-ui-neonBlue focus:border-ui-neonBlue"
                            placeholder="https://example.com/image.jpg"
                          />
                        </div>
                        <div>
                          <label className="block text-sm font-medium text-gray-700 mb-2">
                            Image Alt Text (Optional)
                          </label>
                          <input
                            type="text"
                            value={editForm.imageAlt}
                            onChange={(e) => setEditForm({ ...editForm, imageAlt: e.target.value })}
                            className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-ui-neonBlue focus:border-ui-neonBlue"
                            placeholder="Description of the image"
                          />
                        </div>
                      </div>
                      
                      {/* File Upload Section - Only for Week 2+ */}
                      {selectedWeek >= 2 && (
                        <div className="border-t pt-4">
                          <label className="block text-sm font-medium text-gray-700 mb-2">
                            Upload Local Image (Optional)
                          </label>
                          <div className="space-y-2">
                            <input
                              type="file"
                              accept="image/*"
                              onChange={handleFileChange}
                              className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-ui-neonBlue focus:border-ui-neonBlue"
                            />
                            {selectedFile && (
                              <div className="flex items-center space-x-2">
                                <span className="text-sm text-gray-600">{selectedFile.name}</span>
                                <button
                                  type="button"
                                  onClick={async () => {
                                    try {
                                      const imageUrl = await handleFileUpload(selectedFile);
                                      setEditForm({ ...editForm, imageUrl });
                                                                                setSelectedFile(null);
                                                                          } catch (error) {
                                        console.error('Upload error:', error);
                                      }
                                  }}
                                  disabled={uploading}
                                  className="bg-green-500 hover:bg-green-600 disabled:bg-gray-400 text-white px-3 py-1 rounded text-sm"
                                >
                                  {uploading ? 'Uploading...' : 'Upload'}
                                </button>
                              </div>
                            )}
                          </div>
                        </div>
                      )}
                    </div>
                  </div>
                  <div className="flex justify-end space-x-2 mt-4">
                    <button
                      onClick={saveNewTask}
                      disabled={saving}
                      className="bg-indigo-500 hover:bg-indigo-600 text-white px-4 py-2 rounded-lg transition-colors duration-200 flex items-center space-x-2 text-sm"
                    >
                      {saving ? (
                        <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
                      ) : (
                        <>
                          <CheckIcon className="h-4 w-4" />
                          <span>Save Task</span>
                        </>
                      )}
                    </button>
                    <button
                      onClick={cancelAddingTask}
                      className="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg transition-colors duration-200 flex items-center space-x-2 text-sm"
                    >
                      <XMarkIcon className="h-4 w-4" />
                      <span>Cancel</span>
                    </button>
                  </div>
                </div>
              ) : addingImage ? (
                <div className="bg-white rounded-lg p-6 border border-gray-200 shadow-sm">
                  <div className="flex items-center space-x-3 mb-4">
                    <div className="bg-blue-100 rounded-lg p-2">
                      <PlusIcon className="h-4 w-4 text-blue-600" />
                    </div>
                    <h4 className="text-blue-900 font-semibold text-lg">New Image Task</h4>
                  </div>
                  <div className="space-y-4">
                    <div>
                      <label className="block text-sm font-medium text-gray-700 mb-2">
                        Image URL *
                      </label>
                      <input
                        type="url"
                        value={imageForm.imageUrl}
                        onChange={(e) => setImageForm({ ...imageForm, imageUrl: e.target.value })}
                        className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                        placeholder="https://example.com/image.jpg"
                      />
                    </div>
                    <div>
                      <label className="block text-sm font-medium text-gray-700 mb-2">
                        Image Alt Text (Optional)
                      </label>
                      <input
                        type="text"
                        value={imageForm.imageAlt}
                        onChange={(e) => setImageForm({ ...imageForm, imageAlt: e.target.value })}
                        className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                        placeholder="Description of the image"
                      />
                    </div>
                    
                    {/* File Upload Section */}
                    <div className="border-t pt-4">
                      <label className="block text-sm font-medium text-gray-700 mb-2">
                        Upload Local Image (Optional)
                      </label>
                      <div className="space-y-2">
                        <input
                          type="file"
                          accept="image/*"
                          onChange={handleFileChange}
                          className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                        />
                        {selectedFile && (
                          <div className="flex items-center space-x-2">
                            <span className="text-sm text-gray-600">{selectedFile.name}</span>
                            <button
                              type="button"
                              onClick={async () => {
                                try {
                                  const imageUrl = await handleFileUpload(selectedFile);
                                  setImageForm({ ...imageForm, imageUrl });
                                  setSelectedFile(null);
                                } catch (error) {
                                  console.error('Upload error:', error);
                                }
                              }}
                              disabled={uploading}
                              className="bg-green-500 hover:bg-green-600 disabled:bg-gray-400 text-white px-3 py-1 rounded text-sm"
                            >
                              {uploading ? 'Uploading...' : 'Upload'}
                            </button>
                          </div>
                        )}
                      </div>
                    </div>

                    <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                      <div>
                        <label className="block text-sm font-medium text-gray-700 mb-2">
                          Image Size
                        </label>
                        <select
                          value={imageForm.imageSize}
                          onChange={(e) => setImageForm({ ...imageForm, imageSize: parseInt(e.target.value) })}
                          className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                        >
                          <option value={150}>150px</option>
                          <option value={200}>200px</option>
                          <option value={300}>300px</option>
                        </select>
                      </div>
                      <div>
                        <label className="block text-sm font-medium text-gray-700 mb-2">
                          Image Alignment
                        </label>
                        <select
                          value={imageForm.imageAlignment}
                          onChange={(e) => setImageForm({ ...imageForm, imageAlignment: e.target.value as 'left' | 'center' | 'right' })}
                          className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                        >
                          <option value="left">Left</option>
                          <option value="center">Center</option>
                          <option value="right">Right</option>
                          {selectedWeek >= 4 && <option value="portrait-split">Portrait Split (image left, text+input right)</option>}
                        </select>
                      </div>
                    </div>
                  </div>
                  <div className="flex justify-end space-x-2 mt-4">
                    <button
                      onClick={saveNewImage}
                      disabled={saving}
                      className="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg transition-colors duration-200 flex items-center space-x-2 text-sm"
                    >
                      {saving ? (
                        <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
                      ) : (
                        <>
                          <CheckIcon className="h-4 w-4" />
                          <span>Save Image</span>
                        </>
                      )}
                    </button>
                    <button
                      onClick={cancelAddingImage}
                      className="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg transition-colors duration-200 flex items-center space-x-2 text-sm"
                    >
                      <XMarkIcon className="h-4 w-4" />
                      <span>Cancel</span>
                    </button>
                  </div>
                </div>
              ) : (
                <div className="bg-white rounded-lg p-6 border border-gray-200 border-dashed shadow-sm">
                  <div className="flex items-center justify-between">
                    <div className="flex items-center space-x-3">
                      <div className="bg-gray-100 rounded-lg p-2">
                        <PlusIcon className="h-5 w-5 text-gray-600" />
                      </div>
                      <div>
                        <h3 className="text-lg font-semibold text-indigo-900">Add New Tutorial Task</h3>
                        <p className="text-gray-600 text-sm">Create a new tutorial task for Week {selectedWeek}</p>
                      </div>
                    </div>
                    <div className="flex space-x-3">
                      <div className="flex space-x-3">
                        <button
                          onClick={startAddingTask}
                          className="relative inline-flex items-center gap-2 px-4 py-2 rounded-2xl text-sm font-medium text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 shadow-[inset_0_1px_0_rgba(255,255,255,0.6),inset_0_-1px_0_rgba(0,0,0,0.12)] bg-sky-600/70"
                        >
                          <PlusIcon className="h-5 w-5" />
                          <span className="font-medium">Add Task</span>
                        </button>
                        {selectedWeek >= 3 && (
                          <button
                            onClick={startAddingImage}
                            className="relative inline-flex items-center gap-2 px-4 py-2 rounded-2xl text-sm font-medium text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 shadow-[inset_0_1px_0_rgba(255,255,255,0.6),inset_0_-1px_0_rgba(0,0,0,0.12)] bg-sky-600/70"
                          >
                            <PlusIcon className="h-5 w-5" />
                            <span className="font-medium">Add Image</span>
                          </button>
                        )}
                        {selectedWeek >= 5 && (
                          <button
                            onClick={startAddingRevision}
                            className="relative inline-flex items-center gap-2 px-4 py-2 rounded-2xl text-sm font-medium text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 shadow-[inset_0_1px_0_rgba(255,255,255,0.6),inset_0_-1px_0_rgba(0,0,0,0.12)] bg-purple-600/70"
                          >
                            <PlusIcon className="h-5 w-5" />
                            <span className="font-medium">Add Revision</span>
                          </button>
                        )}
                      </div>

                    </div>
                  </div>
                </div>
              )}
            </div>
          )}

          <div ref={listRef} style={{ overflowAnchor: 'none' }}>
          {addingRevision ? (
            <div className="bg-white rounded-xl shadow-lg border border-gray-100 p-8 mb-8">
              <div className="flex items-center justify-between mb-4">
                <div className="flex items-center space-x-3">
                  <div className="bg-purple-100 rounded-lg p-2">
                    <PlusIcon className="h-5 w-5 text-purple-600" />
                  </div>
                  <h3 className="text-lg font-semibold text-gray-900">Add Deep Revision</h3>
                </div>
                <div className="flex items-center space-x-2">
                  <button
                    onClick={addRevision}
                    className="bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded-lg transition-colors duration-200 flex items-center space-x-2 text-sm"
                  >
                    <CheckIcon className="h-4 w-4" />
                    <span>Add</span>
                  </button>
                  <button
                    onClick={cancelAddingRevision}
                    className="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg transition-colors duration-200 flex items-center space-x-2 text-sm"
                  >
                    <XMarkIcon className="h-4 w-4" />
                    <span>Cancel</span>
                  </button>
                </div>
              </div>
              <div className="border-t pt-4">
                <div className="mx-auto w-full max-w-5xl">
                  <TutorialRefinity weekNumber={selectedWeek} />
                </div>
              </div>
            </div>
          ) : null}
          {revisionAdded ? (
            <div className="bg-white rounded-xl shadow-lg border border-gray-100 p-8 mb-8 max-w-full overflow-x-hidden">
              <div className="flex items-center justify-between mb-4">
                <div className="flex items-center space-x-3">
                  <div className="bg-purple-100 rounded-lg p-2">
                    <PlusIcon className="h-5 w-5 text-purple-600" />
                  </div>
                  <h3 className="text-lg font-semibold text-gray-900">Deep Revision</h3>
                </div>
                {JSON.parse(localStorage.getItem('user') || '{}').role === 'admin' && (
                  <button
                    onClick={removeRevision}
                    className="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg transition-colors duration-200 flex items-center space-x-2 text-sm"
                  >
                    <XMarkIcon className="h-4 w-4" />
                    <span>Remove</span>
                  </button>
                )}
              </div>
              <div className="border-t pt-4">
                <div className="mx-auto w-full max-w-5xl">
                  <TutorialRefinity weekNumber={selectedWeek} />
                </div>
              </div>
            </div>
          ) : null}
          {tutorialTasks.length === 0 && !addingTask && !addingRevision && !revisionAdded ? (
            <div className="text-center py-12">
              <DocumentTextIcon className="h-12 w-12 text-gray-400 mx-auto mb-4" />
              <h3 className="text-lg font-medium text-gray-900 mb-2">
                No tutorial tasks available
              </h3>
              <p className="text-gray-600">
                Tutorial tasks for Week {selectedWeek} haven't been set up yet.
              </p>
            </div>
          ) : (
            tutorialTasks.map((task) => (
              <div
                key={task._id}
                ref={(el) => { (cardRefs.current[task._id] = el); }}
                className="bg-white rounded-xl shadow-lg border border-gray-100 p-8 hover:shadow-xl transition-shadow duration-300 mb-8"
                style={{ 
                  minHeight: '700px',
                  overflowAnchor: mutatingTaskId === task._id ? 'none' as any : undefined
                }}
              >
                <div className="mb-6">
                  <div className="flex items-center justify-between mb-4">
                    <div className="flex items-center space-x-3">
                      <div className="relative p-2 rounded-2xl bg-white/10 backdrop-blur-md ring-1 ring-inset ring-white/30 shadow-[inset_0_0.5px_0_rgba(255,255,255,0.5),inset_0_-1px_1.5px_rgba(0,0,0,0.12)]">
                        <div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
                        <div className="pointer-events-none absolute inset-0 rounded-2xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-50" />
                        <div className="pointer-events-none absolute rounded-full" style={{ width: '20px', height: '20px', left: '6px', top: '6px', background: 'radial-gradient(12px_12px_at_10px_10px,rgba(255,255,255,0.5),rgba(255,255,255,0)_60%)', opacity: 0.45 }} />
                        <div className="pointer-events-none absolute inset-0 rounded-2xl" style={{ background: 'radial-gradient(120%_120%_at_50%_55%,rgba(0,0,0,0.04),rgba(0,0,0,0)_60%)', opacity: 0.9 }} />
                        <div className="pointer-events-none absolute inset-0 rounded-2xl bg-sky-500/30 mix-blend-overlay opacity-35" />
                        <DocumentTextIcon className="relative h-5 w-5 text-ui-text" />
                      </div>
                      <div>
                        <h3 className="text-lg font-semibold text-gray-900 flex items-center">
                          Source Text #{tutorialTasks.indexOf(task) + 1}
                          {JSON.parse(localStorage.getItem('user') || '{}').role === 'admin' && selectedWeek >= 4 && (
                            <span className="ml-2 inline-flex items-center space-x-1">
                              <button
                                className="px-2 py-1 text-xs bg-gray-100 rounded hover:bg-gray-200"
                                onClick={() => moveTask(task._id, 'up')}
                                title="Move up"
                              >↑</button>
                              <button
                                className="px-2 py-1 text-xs bg-gray-100 rounded hover:bg-gray-200"
                                onClick={() => moveTask(task._id, 'down')}
                                title="Move down"
                              >↓</button>
                            </span>
                          )}
                        </h3>
                      </div>
                    </div>
                    {JSON.parse(localStorage.getItem('user') || '{}').role === 'admin' && (
                      <div className="flex items-center space-x-2">
                        {editingTask === task._id ? (
                          <>
                            <button
                              onClick={saveTask}
                              disabled={saving}
                              className="bg-green-100 hover:bg-green-200 text-green-700 px-3 py-1 rounded-lg transition-colors duration-200"
                            >
                              {saving ? (
                                <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-green-600"></div>
                              ) : (
                                <CheckIcon className="h-4 w-4" />
                              )}
                            </button>
                            <button
                              onClick={cancelEditing}
                              className="bg-red-100 hover:bg-red-200 text-red-700 px-3 py-1 rounded-lg transition-colors duration-200"
                            >
                              <XMarkIcon className="h-4 w-4" />
                            </button>
                          </>
                        ) : (
                          <>
                            <button
                              onClick={() => startEditing(task)}
                              className="bg-gray-100 hover:bg-gray-200 text-gray-700 px-3 py-1 rounded-md transition-colors duration-200 text-sm"
                            >
                              <PencilIcon className="h-4 w-4" />
                            </button>
                            <button
                              onClick={() => deleteTask(task._id)}
                              className="bg-red-100 hover:bg-red-200 text-red-700 px-3 py-1 rounded-lg transition-colors duration-200"
                            >
                              <TrashIcon className="h-4 w-4" />
                            </button>
                          </>
                        )}
                      </div>
                    )}
                  </div>

                  {/* Content - Gradient underlay + glass overlay */}
                  <div className="relative rounded-xl mb-6 p-0 border border-indigo-200">
                    <div className="absolute inset-0 rounded-xl bg-gradient-to-r from-sky-200/60 via-blue-200/50 to-indigo-200/60" />
                    <div className="relative rounded-xl bg-white/10 backdrop-blur-md ring-1 ring-inset ring-white/30 shadow-[inset_0_0.5px_0_rgba(255,255,255,0.5),inset_0_-1px_1.5px_rgba(0,0,0,0.12)] p-6">
                      <div className="pointer-events-none absolute inset-0 rounded-xl opacity-50 [background:linear-gradient(to_bottom,rgba(255,255,255,0.3),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.28),rgba(255,255,255,0)_28%)]" />
                      <div className="pointer-events-none absolute inset-0 rounded-xl bg-gradient-to-tr from-white/30 via-white/10 to-transparent opacity-45" />
                      <div className="pointer-events-none absolute inset-0 rounded-xl" style={{ background: 'radial-gradient(120% 120% at 50% 55%, rgba(0,0,0,0.03), rgba(0,0,0,0) 60%)' }} />
                      <div className="pointer-events-none absolute inset-0 rounded-xl bg-sky-500/10 mix-blend-overlay opacity-30" />
                    {editingTask === task._id ? (
                      <div className="space-y-4">
                        <div className="flex items-center justify-end space-x-2 mb-2">
                          <button onClick={() => applyInlineFormat('tutorial-newtask-input', editForm.content, v => setEditForm({ ...editForm, content: v }), '**')} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded">B</button>
                          <button onClick={() => applyInlineFormat('tutorial-newtask-input', editForm.content, v => setEditForm({ ...editForm, content: v }), '*')} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded italic">I</button>
                          <button onClick={() => applyLinkFormat('tutorial-newtask-input', editForm.content || '', v => setEditForm({ ...editForm, content: v }))} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded">Link</button>
                        </div>
                        <textarea
                          id="tutorial-newtask-input"
                          value={editForm.content}
                          onChange={(e) => setEditForm({...editForm, content: e.target.value})}
                          className="w-full px-4 py-3 border border-indigo-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white"
                          rows={5}
                          placeholder="Enter source text..."
                        />
                        <div className="space-y-4">
                          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                            <div>
                              <label className="block text-sm font-medium text-gray-700 mb-2">Image URL</label>
                              <input
                                type="url"
                                value={editForm.imageUrl}
                                onChange={(e) => setEditForm({...editForm, imageUrl: e.target.value})}
                                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-ui-neonBlue focus:border-ui-neonBlue"
                                placeholder="https://example.com/image.jpg"
                              />
                            </div>
                            <div>
                              <label className="block text-sm font-medium text-gray-700 mb-2">Image Alt Text</label>
                              <input
                                type="text"
                                value={editForm.imageAlt}
                                onChange={(e) => setEditForm({...editForm, imageAlt: e.target.value})}
                                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-ui-neonBlue focus:border-ui-neonBlue"
                                placeholder="Description of the image"
                              />
                            </div>
                          </div>
                          
                          {/* File Upload Section - Only for Week 2+ */}
                          {selectedWeek >= 2 && (
                            <div className="border-t pt-4">
                              <label className="block text-sm font-medium text-gray-700 mb-2">
                                Upload Local Image (Optional)
                              </label>
                              <div className="space-y-2">
                                <input
                                  type="file"
                                  accept="image/*"
                                  onChange={handleFileChange}
                                  className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-ui-neonBlue focus:border-ui-neonBlue"
                                />
                                {selectedFile && (
                                  <div className="flex items-center space-x-2">
                                    <span className="text-sm text-gray-600">{selectedFile.name}</span>
                                    <button
                                      type="button"
                                      onClick={async () => {
                                        try {
                                          const imageUrl = await handleFileUpload(selectedFile);
                                          console.log('Uploaded image URL:', imageUrl);
                                          setEditForm({ ...editForm, imageUrl });
                                          console.log('Updated editForm:', { ...editForm, imageUrl });
                                          
                                          // Save the task with the new image URL
                                          if (editingTask) {
                                            console.log('Saving task with image URL:', imageUrl);
                                            const response = await api.put(`/api/auth/admin/tutorial-tasks/${editingTask}`, {
                                              ...editForm,
                                              imageUrl,
                                              weekNumber: selectedWeek
                                            });
                                            console.log('Task save response:', response.data);
                                            
                                            if (response.status >= 200 && response.status < 300) {
                                              await fetchTutorialTasks(false); // Refresh tasks
                                            }
                                          }
                                          
                                          setSelectedFile(null);
                                        } catch (error) {
                                          console.error('Upload error:', error);
                                        }
                                      }}
                                      disabled={uploading}
                                      className="bg-green-500 hover:bg-green-600 disabled:bg-gray-400 text-white px-3 py-1 rounded text-sm"
                                    >
                                      {uploading ? 'Uploading...' : 'Upload'}
                                    </button>
                                  </div>
                                )}
                              </div>
                            </div>
                          )}
                        </div>
                      </div>
                    ) : (
                      <div className="space-y-4">
                        {task.imageUrl ? (
                          task.imageAlignment === 'portrait-split' && selectedWeek >= 4 ? (
                            // Portrait split layout
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-6 items-start">
                              <div className="w-full flex justify-center">
                                <div className="inline-block rounded-lg shadow-md overflow-hidden">
                                  <img src={task.imageUrl} alt={task.imageAlt || 'Uploaded image'} className="w-auto h-auto" style={{ maxHeight: '520px', maxWidth: '100%', objectFit: 'contain' }} />
                                </div>
                              </div>
                              <div className="w-full">
                                <div className="bg-indigo-50 rounded-lg p-4 mb-4 border border-indigo-200">
                                  <h5 className="text-indigo-900 font-semibold mb-2">Source Text (from image)</h5>
                                  <div
                                    id={`tutorial-source-${task._id}`}
                                    className="text-blue-800 leading-relaxed text-lg font-source-text whitespace-pre-wrap"
                                  >{renderFormatted(task.content)}</div>
                                </div>
                                {localStorage.getItem('token') && (
                                  <div className="bg-white rounded-lg p-4 border border-gray-200">
                                    <h5 className="text-gray-900 font-semibold mb-2">Your Group's Translation</h5>
                                    {/* Group selection (same as bottom block), shown here for portrait-split */}
                                    <div className="mb-2">
                                      <label className="block text-xs font-medium text-gray-700 mb-1">Select Your Group</label>
                                      <select
                                        value={selectedGroups[task._id] || ''}
                                        onChange={(e) => {
                                          const v = parseInt(e.target.value);
                                          setSelectedGroups({ ...selectedGroups, [task._id]: Number.isNaN(v) ? ('' as any) : v });
                                        }}
                                        className="w-40 px-2 py-1 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white text-xs"
                                      >
                                        <option value="">Choose...</option>
                                        {[1,2,3,4,5,6,7,8].map((g) => (<option key={g} value={g}>Group {g}</option>))}
                                      </select>
                                    </div>
                                    <div className="flex items-center justify-end space-x-2 mb-2">
                                      <button onClick={() => applyInlineFormat(`tutorial-translation-${task._id}`, translationText[task._id] || '', v => setTranslationText({ ...translationText, [task._id]: v }), '**')} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded">B</button>
                                      <button onClick={() => applyInlineFormat(`tutorial-translation-${task._id}`, translationText[task._id] || '', v => setTranslationText({ ...translationText, [task._id]: v }), '*')} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded italic">I</button>
                                      <button onClick={() => applyLinkFormat(`tutorial-translation-${task._id}`, translationText[task._id] || '', v => setTranslationText({ ...translationText, [task._id]: v }))} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded">Link</button>
                                    </div>
                                      <textarea
                                        id={`tutorial-translation-${task._id}`}
                                        value={translationText[task._id] || ''}
                                       
                                      onChange={(e) => {
                                        const value = e.target.value;
                                        setTranslationText({ ...translationText, [task._id]: value });
                                      }}
                                        className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white"
                                      style={{ height: '150px' }}
                                        rows={4}
                                        placeholder="Enter your group's translation here..."
                                      />
                                    <div className="flex justify-end mt-2">
                                      <button onClick={() => handleSubmitTranslation(task._id)} disabled={submitting[task._id]} className="btn-primary disabled:bg-gray-400 text-white px-4 py-2 rounded-lg text-sm">{submitting[task._id] ? 'Submitting...' : 'Submit Translation'}</button>
                                    </div>
                                  </div>
                                )}
                              </div>
                            </div>
                          ) : task.content === 'Image-based task' ? (
                            // Image-only layout with dynamic sizing and alignment
                            <div className={`flex flex-col md:flex-row gap-6 items-start ${
                              task.imageAlignment === 'left' ? 'md:flex-row' : 
                              task.imageAlignment === 'right' ? 'md:flex-row-reverse' : 
                              'md:flex-col'
                            }`}>
                              {/* Image section */}
                              <div className={`${
                                task.imageAlignment === 'left' ? 'w-full md:w-1/2' :
                                task.imageAlignment === 'right' ? 'w-full md:w-1/2' :
                                'w-full'
                              } flex ${
                                task.imageAlignment === 'left' ? 'justify-start' :
                                task.imageAlignment === 'right' ? 'justify-end' :
                                'justify-center'
                              }`}>
                                <div className="inline-block rounded-lg shadow-md overflow-hidden">
                                  <img src={task.imageUrl} alt={task.imageAlt || 'Uploaded image'} className="w-full h-auto" style={{ height: `${task.imageSize || 200}px`, width: 'auto', objectFit: 'contain' }} onError={(e) => { console.error('Image failed to load:', e); (e.currentTarget as HTMLImageElement).style.display = 'none'; }} />
                                  {task.imageAlt && (<div className="text-xs text-gray-500 mt-2 text-center">Alt: {task.imageAlt}</div>)}
                                </div>
                              </div>
                            </div>
                          ) : (
                            // Regular task layout - use grid for stability like image-only layout
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-6 items-start">
                              <div className="w-full flex justify-center">
                                {task.imageUrl && task.imageUrl.startsWith('data:') ? (
                                  <div className="inline-block rounded-lg shadow-md overflow-hidden">
                                    <img src={task.imageUrl} alt={task.imageAlt || 'Uploaded image'} className="w-full h-auto" style={{ height: '200px', width: 'auto', objectFit: 'contain' }} onError={(e) => { console.error('Image failed to load:', e); (e.currentTarget as HTMLImageElement).style.display = 'none'; }} />
                                  </div>
                                ) : task.imageUrl ? (
                                  <div className="inline-block rounded-lg shadow-md bg-green-500 text-white p-6 text-center">
                                    <div className="text-3xl mb-2">📷</div>
                                    <div className="font-semibold">Image Uploaded</div>
                                    <div className="text-sm opacity-75">{task.imageUrl}</div>
                                  </div>
                                ) : (
                                  <div className="w-full h-48 bg-gray-100 rounded-lg flex items-center justify-center">
                                    <div className="text-gray-500">No image</div>
                                  </div>
                                )}
                              </div>
                              <div className="w-full">
                                <div className="text-indigo-900 leading-relaxed text-lg font-source-text whitespace-pre-wrap">{renderFormatted(task.content)}</div>
                              </div>
                            </div>
                          )
                        ) : (
                          // Text only when no image
                          <div>
                            <div className="text-indigo-900 leading-relaxed text-lg font-source-text whitespace-pre-wrap">{renderFormatted(task.content)}</div>
                          </div>
                        )}
                        {(() => { console.log('Task imageUrl check:', task._id, task.imageUrl, !!task.imageUrl); return null; })()}
                      </div>
                    )}
                    </div>
                  </div>


                </div>

                {/* All Submissions for this Task */}
                {userSubmissions[task._id] && userSubmissions[task._id].length > 0 && (
                  <div ref={(el) => { submissionsContainerRefs.current[task._id] = el; }} className="bg-gradient-to-r from-white to-indigo-50 rounded-xl p-6 mb-6 border border-stone-200" style={{ overflowAnchor: 'none' }}>
                    <div className="flex items-center justify-between mb-4">
                      <div className="flex items-center space-x-2">
                        <div className="bg-indigo-100 rounded-full p-1">
                          <CheckCircleIcon className="h-4 w-4 text-indigo-900" />
                        </div>
                        <h4 className="text-stone-900 font-semibold text-lg">All Submissions ({userSubmissions[task._id].length})</h4>
                      </div>
                      <button
                        onClick={() => toggleExpanded(task._id)}
                        className="flex items-center space-x-1 text-indigo-900 hover:text-indigo-900 text-sm font-medium"
                      >
                        <span>{expandedSections[task._id] ? 'Collapse' : 'Expand'}</span>
                        <svg
                          className={`w-4 h-4 transition-transform duration-200 ${expandedSections[task._id] ? 'rotate-180' : ''}`}
                          fill="none"
                          stroke="currentColor"
                          viewBox="0 0 24 24"
                        >
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
                        </svg>
                      </button>
                    </div>
                    <div ref={(el) => { submissionsGridRefs.current[task._id] = el; }} className={`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 ${
                      expandedSections[task._id] 
                        ? 'max-h-none overflow-visible' 
                        : 'max-h-0 overflow-hidden'
                    }`} data-grid-id={task._id}>
                      {userSubmissions[task._id].map((submission, index) => (
                        <div key={submission._id} className="bg-white rounded-lg p-3 border border-stone-200 flex flex-col justify-between h-full">
                          <div className="flex items-center justify-between mb-2">
                            <div className="flex items-center space-x-2">
                              {submission.isOwner && (
                                <span className="inline-block bg-purple-100 text-purple-800 text-xs px-1.5 py-0.5 rounded-full">
                                  Your Submission
                                </span>
                              )}
                            </div>
                            {getStatusIcon(submission.status)}
                          </div>
                          <p className="text-stone-800 leading-relaxed text-base mb-2 font-smiley whitespace-pre-wrap break-words">{renderFormatted(submission.transcreation || '')}</p>
                          <div className="flex items-center space-x-4 text-xs text-stone-700 mt-auto">
                            <div className="flex items-center space-x-1">
                              <span className="font-medium">Group:</span>
                              <span className="bg-indigo-100 px-1.5 py-0.5 rounded-full text-indigo-900 text-xs">
                                {submission.groupNumber}
                              </span>
                            </div>
                            <div className="flex items-center space-x-1">
                              <span className="font-medium">Votes:</span>
                              <span className="bg-indigo-100 px-1.5 py-0.5 rounded-full text-indigo-900 text-xs">
                                {(submission.voteCounts?.['1'] || 0) + (submission.voteCounts?.['2'] || 0) + (submission.voteCounts?.['3'] || 0)}
                              </span>
                            </div>
                          </div>
                          <div className="flex items-center space-x-2 mt-2">
                            {(submission.isOwner || (JSON.parse(localStorage.getItem('user') || '{}').role === 'admin')) && (
                              <button
                                onClick={() => handleEditSubmission(submission._id, submission.transcreation)}
                                className="text-indigo-900 hover:text-indigo-900 text-sm font-medium"
                              >
                                Edit
                              </button>
                            )}
                            {JSON.parse(localStorage.getItem('user') || '{}').role === 'admin' && (
                              <button
                                onClick={() => handleDeleteSubmission(submission._id, task._id)}
                                className="text-red-600 hover:text-red-800 text-sm font-medium"
                              >
                                Delete
                              </button>
                            )}
                          </div>
                        </div>
                      ))}
                    </div>
                    
                  </div>
                )}

                                  {/* Translation Input (always show if user is logged in, but hide for image-only content) */}
                {localStorage.getItem('token') && task.content !== 'Image-based task' && (
                  <TranslationSection
                    taskId={task._id}
                    selectedGroup={selectedGroups[task._id] || ''}
                    translation={translationText[task._id] || ''}
                    submitting={!!submitting[task._id]}
                    onGroupChange={(n) => setSelectedGroups(prev => ({ ...prev, [task._id]: n as number }))}
                    onTranslationChange={(v) => setTranslationText(prev => ({ ...prev, [task._id]: v }))}
                    onSubmit={(localText, localGroup) => handleSubmitTranslation(task._id, localText, localGroup)}
                    label="Select Your Group"
                    selectWidthClass="w-40"
                    containerClassName="bg-white rounded-lg p-4 border border-gray-200"
                  />
                )}

                {/* Show login message for visitors */}
                {!localStorage.getItem('token') && (
                  <div className="relative rounded-xl p-6 border border-gray-200">
                    <div className="absolute inset-0 rounded-xl bg-gradient-to-r from-gray-100/70 to-indigo-100/60" />
                    <div className="relative rounded-xl bg-white/10 backdrop-blur-md ring-1 ring-inset ring-white/30 shadow-[inset_0_0.5px_0_rgba(255,255,255,0.5),inset_0_-1px_1.5px_rgba(0,0,0,0.12)] p-6">
                      <div className="pointer-events-none absolute inset-0 rounded-xl opacity-50 [background:linear-gradient(to_bottom,rgba(255,255,255,0.3),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.28),rgba(255,255,255,0)_28%)]" />
                    <div className="flex items-center space-x-2 mb-4">
                        <div className="relative p-1.5 rounded-2xl bg-white/10 backdrop-blur-md ring-1 ring-inset ring-white/30 shadow-[inset_0_0.5px_0_rgba(255,255,255,0.5),inset_0_-1px_1.5px_rgba(0,0,0,0.12)]">
                          <div className="pointer-events-none absolute inset-0 rounded-2xl opacity-60 [background:linear-gradient(to_bottom,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%),linear-gradient(to_right,rgba(255,255,255,0.35),rgba(255,255,255,0)_28%)]" />
                          <DocumentTextIcon className="relative h-4 w-4 text-gray-700" />
                      </div>
                      <h4 className="text-gray-900 font-semibold text-lg">Login Required</h4>
                    </div>
                    <p className="text-gray-700 mb-4">
                      Please log in to submit translations for this tutorial task.
                    </p>
                      <button onClick={() => window.location.href = '/login'} className="relative inline-flex items-center justify-center gap-2 px-4 py-2 rounded-2xl text-sm font-medium text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 shadow-[inset_0_1px_0_rgba(255,255,255,0.6),inset_0_-1px_0_rgba(0,0,0,0.12)] bg-sky-600/70 transition-all duration-200">
                      Go to Login
                      <ArrowRightIcon className="h-4 w-4 ml-2" />
                    </button>
                    </div>
                  </div>
                )}
              </div>
            ))
          )}
          </div>
        </div>
        </>
        )}
      </div>

      {/* Edit Submission Modal */}
      {editingSubmission && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
          <div className="bg-white rounded-lg p-6 w-full max-w-2xl mx-4">
            <div className="flex items-center justify-between mb-4">
              <h3 className="text-lg font-semibold text-gray-900">Edit Translation</h3>
              <button
                onClick={cancelEditSubmission}
                className="text-gray-400 hover:text-gray-600"
              >
                <XMarkIcon className="h-6 w-6" />
              </button>
            </div>
            <div className="mb-4">
              <textarea
                value={editSubmissionText}
                onChange={(e) => setEditSubmissionText(e.target.value)}
                className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500"
                rows={6}
                placeholder="Enter your translation..."
              />
            </div>
            <div className="flex justify-end space-x-3">
              <button
                onClick={cancelEditSubmission}
                className="px-4 py-2 text-gray-600 hover:text-gray-800 border border-gray-300 rounded-lg"
              >
                Cancel
              </button>
              <button
                onClick={saveEditedSubmission}
                className="px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700"
              >
                Save Changes
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

const TranslationSection: React.FC<{
  taskId: string;
  selectedGroup: number | '';
  translation: string;
  submitting: boolean;
  onGroupChange: (n: number) => void;
  onTranslationChange: (v: string) => void;
  onSubmit: (localText: string, localGroup: number) => void;
  label?: string;
  selectWidthClass?: string;
  containerClassName?: string;
}> = React.memo(({ taskId, selectedGroup, translation, submitting, onGroupChange, onTranslationChange, onSubmit, label = 'Select Your Group *', selectWidthClass = 'w-48', containerClassName = 'bg-white rounded-lg p-6 border border-gray-200 shadow-sm safari-stable-form' }) => {
  const [localText, setLocalText] = React.useState<string>(translation || '');
  const [localGroup, setLocalGroup] = React.useState<number | ''>(selectedGroup || '');
  React.useEffect(() => { setLocalText(translation || ''); }, [taskId]);
  React.useEffect(() => { setLocalGroup(selectedGroup || ''); }, [taskId, selectedGroup]);
  const isSafariEnv = typeof navigator !== 'undefined' && /Safari\//.test(navigator.userAgent) && !/Chrome\//.test(navigator.userAgent) && !/CriOS\//.test(navigator.userAgent);
  const submitTriggeredRef = React.useRef(false);
  const triggerSubmitOnce = React.useCallback((e?: React.SyntheticEvent) => {
    if (submitTriggeredRef.current) { e?.preventDefault?.(); return; }
    submitTriggeredRef.current = true;
    if (localGroup) onSubmit(localText, localGroup as number);
    // Small cooldown to avoid duplicate fire from click after pointerdown
    setTimeout(() => { submitTriggeredRef.current = false; }, 400);
  }, [localText, localGroup, onSubmit]);
  const wrapSelection = (wrapper: '**' | '*') => {
    const el = document.getElementById(`tutorial-translation-${taskId}`) as HTMLTextAreaElement | null;
    const current = localText || '';
    if (!el) { const next = current + wrapper + wrapper; setLocalText(next); return; }
    const start = el.selectionStart ?? current.length;
    const end = el.selectionEnd ?? current.length;
    const before = current.slice(0, start);
    const selection = current.slice(start, end);
    const after = current.slice(end);
    const next = `${before}${wrapper}${selection}${wrapper}${after}`;
    setLocalText(next);
    setTimeout(() => { try { el.focus(); el.setSelectionRange(before.length + wrapper.length + selection.length + wrapper.length, before.length + wrapper.length + selection.length + wrapper.length); } catch {} }, 0);
  };
  const insertLink = () => {
    const urlRaw = window.prompt('Enter URL', 'https://') || '';
    let url = urlRaw.trim();
    if (!url) return;
    url = url.replace(/["'>)\s]+$/g, '');
    const el = document.getElementById(`tutorial-translation-${taskId}`) as HTMLTextAreaElement | null;
    const current = localText || '';
    if (!el) { const next = `${current}[link](${url})`; setLocalText(next); return; }
    const start = el.selectionStart ?? current.length;
    const end = el.selectionEnd ?? current.length;
    const before = current.slice(0, start);
    const sel = current.slice(start, end) || 'link';
    const after = current.slice(end);
    const next = `${before}[${sel}](${url})${after}`;
    setLocalText(next);
    setTimeout(() => { try { el.focus(); const newPos = before.length + sel.length + 4 + url.length + 2; el.setSelectionRange(newPos, newPos); } catch {} }, 0);
  };
  return (
    <div className={containerClassName}>
      <div className="flex items-center space-x-3 mb-4">
        <div className="bg-gray-100 rounded-lg p-2">
          <DocumentTextIcon className="h-4 w-4 text-gray-600" />
        </div>
        <h4 className="text-gray-900 font-semibold text-lg">Group Translation</h4>
      </div>
      <div className="mb-4">
        <label className="block text-sm font-medium text-gray-700 mb-2">{label}</label>
        <select
          value={localGroup || ''}
          onChange={(e) => {
            const value = parseInt(e.target.value);
            const next = Number.isNaN(value) ? ('' as any) : value;
            setLocalGroup(next);
            // Parent sync deferred to submit; no immediate parent state update to minimize re-renders
          }}
          className={`${selectWidthClass} px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white text-sm`}
          required
        >
          <option value="">Choose your group...</option>
          {[1, 2, 3, 4, 5, 6, 7, 8].map((group) => (
            <option key={group} value={group}>Group {group}</option>
          ))}
        </select>
      </div>
      <div className="flex items-center justify-end space-x-2 mb-2">
        <button onClick={() => wrapSelection('**')} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded">B</button>
        <button onClick={() => wrapSelection('*')} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded italic">I</button>
        <button onClick={insertLink} className="px-2 py-1 text-xs bg-indigo-100 text-indigo-900 rounded">Link</button>
      </div>
      <textarea
        id={`tutorial-translation-${taskId}`}
        value={localText || ''}
        onChange={(e) => { setLocalText(e.target.value); }}
        className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-white"
        style={{ height: '150px' }}
        rows={4}
        placeholder="Enter your group's translation here..."
      />
      <button
        type="button"
        onClick={!isSafariEnv ? (e) => { e.preventDefault(); triggerSubmitOnce(e); } : undefined}
        onPointerDown={isSafariEnv ? (e) => { e.preventDefault(); triggerSubmitOnce(e as unknown as React.SyntheticEvent); } : undefined}
        disabled={submitting}
        className="relative inline-flex items-center justify-center gap-2 px-4 py-2 rounded-2xl text-sm font-medium text-white ring-1 ring-inset ring-white/50 backdrop-blur-md backdrop-brightness-110 backdrop-saturate-150 shadow-[inset_0_1px_0_rgba(255,255,255,0.6),inset_0_-1px_0_rgba(0,0,0,0.12)] bg-sky-600/70 disabled:bg-gray-400 mt-2"
        style={{ touchAction: 'manipulation' as any }}
      >
        {submitting ? (
          <>
            <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
            <span>Submitting...</span>
          </>
        ) : (
          <>
            <CheckIcon className="h-4 w-4" />
            <span>Submit Translation</span>
          </>
        )}
      </button>
    </div>
  );
}, (a, b) => (
  a.selectedGroup === b.selectedGroup &&
  a.translation === b.translation &&
  a.submitting === b.submitting &&
  a.taskId === b.taskId
));

export default TutorialTasks; 