/* ============================================
   APP — root component, layout, view routing
   ============================================ */

const VIEWS = [
  { id: 'kanban',    label: 'Board',     icon: 'kanban' },
  { id: 'list',      label: 'List',      icon: 'list' },
  { id: 'calendar',  label: 'Calendar',  icon: 'calendar' },
  { id: 'dashboard', label: 'Dashboard', icon: 'dashboard' },
];

const App = () => {
  // ── AUTH ──
  const [currentUserId, setCurrentUserId] = React.useState(() => {
    return localStorage.getItem('tasker_uid') || null;
  });

  // ── DATA ──
  const [tasks, setTasks] = React.useState(() => {
    const saved = localStorage.getItem('tasker_tasks_v2');
    if (saved) {
      try { return JSON.parse(saved); } catch (e) {}
    }
    return TASKS;
  });

  React.useEffect(() => {
    localStorage.setItem('tasker_tasks_v2', JSON.stringify(tasks));
  }, [tasks]);

  // ── GOOGLE SHEETS SYNC ──
  const [syncStatus, setSyncStatus] = React.useState('idle');
  const syncTimer = React.useRef(null);
  const sheetsLoaded = React.useRef(false);

  // Listen to API sync status
  React.useEffect(() => {
    if (!window.TaskerAPI) return;
    const unsub = window.TaskerAPI.onSyncStatus(setSyncStatus);
    return unsub;
  }, []);

  // Load from Sheets on first mount (if configured)
  React.useEffect(() => {
    if (sheetsLoaded.current || !window.TaskerAPI?.isConfigured()) return;
    sheetsLoaded.current = true;
    window.TaskerAPI.loadTasks().then(remoteTasks => {
      if (remoteTasks && Array.isArray(remoteTasks) && remoteTasks.length > 0) {
        setTasks(remoteTasks);
        toast.push('📡 โหลดข้อมูลจาก Google Sheets แล้ว');
      }
    });
  }, []);

  // Save to Sheets on tasks change (debounced 3 sec)
  React.useEffect(() => {
    if (!window.TaskerAPI?.isConfigured()) return;
    if (syncTimer.current) clearTimeout(syncTimer.current);
    syncTimer.current = setTimeout(() => {
      window.TaskerAPI.saveTasks(tasks);
    }, 3000);
    return () => { if (syncTimer.current) clearTimeout(syncTimer.current); };
  }, [tasks]);

  // ── USERS (mutable for admin/profile edits) ──
  const [users, setUsers] = React.useState(() => {
    const saved = localStorage.getItem('tasker_users_v2');
    if (saved) {
      try { return JSON.parse(saved); } catch (e) {}
    }
    return USERS;
  });
  React.useEffect(() => {
    window.USERS = users;
    localStorage.setItem('tasker_users_v2', JSON.stringify(users));
  }, [users]);

  // ── PREFERENCES ──
  const [prefs, setPrefs] = React.useState(() => {
    const saved = localStorage.getItem('tasker_prefs_v1');
    if (saved) {
      try { return JSON.parse(saved); } catch (e) {}
    }
    return DEFAULT_PREFS;
  });
  React.useEffect(() => {
    localStorage.setItem('tasker_prefs_v1', JSON.stringify(prefs));
  }, [prefs]);

  // ── THEME (Tweaks-controlled) ──
  const [tw, setTweak] = useTweaks(TWEAK_DEFAULTS);
  React.useEffect(() => {
    document.documentElement.setAttribute('data-theme', tw.theme);
    document.documentElement.style.setProperty('--brand-50',  tw.brand[0]);
    document.documentElement.style.setProperty('--brand-100', tw.brand[1]);
    document.documentElement.style.setProperty('--brand-300', tw.brand[2]);
    document.documentElement.style.setProperty('--brand-400', tw.brand[3]);
    document.documentElement.style.setProperty('--brand-500', tw.brand[4]);
    document.documentElement.style.setProperty('--brand-600', tw.brand[5]);
  }, [tw.theme, tw.brand]);

  // ── UI STATE ──
  const [page, setPage] = React.useState('tasks'); // tasks | inbox | team
  const [view, setView] = React.useState('kanban');
  const [sidebarCollapsed, setSidebarCollapsed] = React.useState(false);
  const [openTaskId, setOpenTaskId] = React.useState(null);
  const [showAddModal, setShowAddModal] = React.useState(false);
  const [scope, setScope] = React.useState('all'); // all | mine | project:{id}
  const [filters, setFilters] = React.useState({
    search: '', status: '', priority: '', workType: '', assignee: '', project: '',
  });
  const [groupBy, setGroupBy] = React.useState('status');
  const [showUserMenu, setShowUserMenu] = React.useState(false);
  const [showFilters, setShowFilters] = React.useState(false);

  const toast = useToast();

  const currentUser = getUser(currentUserId) || USERS[0];

  // ── FILTER (must run on every render — keep above early return) ──
  const filteredTasks = React.useMemo(() => {
    if (!currentUserId) return [];
    const f = filters;
    return tasks.filter(t => {
      // Archived tasks are hidden from all task views — they live in the Archived page
      if (t.status === 'Archived') return false;
      if (scope === 'mine' && t.assignee !== currentUser.id && t.pic !== currentUser.id) return false;
      if (scope.startsWith('project:') && t.project !== scope.slice(8)) return false;
      if (f.search) {
        const s = f.search.toLowerCase();
        if (!t.name.toLowerCase().includes(s) && !(t.id||'').toLowerCase().includes(s)) return false;
      }
      if (f.status && t.status !== f.status) return false;
      if (f.priority && t.priority !== f.priority) return false;
      if (f.workType && t.workType !== f.workType) return false;
      if (f.assignee && t.assignee !== f.assignee && t.pic !== f.assignee) return false;
      if (f.project && t.project !== f.project) return false;
      return true;
    });
  }, [tasks, filters, scope, currentUser.id, currentUserId]);

  if (!currentUserId) {
    return (
      <LoginScreen
        onLogin={(uid) => {
          localStorage.setItem('tasker_uid', uid);
          setCurrentUserId(uid);
        }}
      />
    );
  }

  // ── TASK ACTIONS ──
  const updateTask = (updated) => {
    setTasks(ts => ts.map(t => t.id === updated.id ? updated : t));
  };
  const deleteTask = (id) => {
    setTasks(ts => ts.filter(t => t.id !== id));
    setOpenTaskId(null);
    toast.push('Task deleted');
  };
  const moveTask = (id, status) => {
    setTasks(ts => ts.map(t => t.id === id ? { ...t, status } : t));
    toast.push(`Moved to ${getStatus(status)?.label}`);
  };
  const restoreTask = (id) => {
    setTasks(ts => ts.map(t => t.id === id ? { ...t, status: 'Backlog' } : t));
    toast.push('Restored to Backlog');
  };
  const toggleDone = (id) => {
    setTasks(ts => ts.map(t => t.id === id ? { ...t, status: t.status === 'Done' ? 'In progress' : 'Done' } : t));
  };
  const addTask = (data) => {
    const newId = `MT2026-NEW-${String(tasks.length + 1).padStart(4, '0')}`;
    const task = {
      id: newId,
      checklist: [], comments: [], attachments: [], tags: [],
      createdAt: new Date().toISOString().split('T')[0],
      ...data,
    };
    setTasks(ts => [task, ...ts]);
    toast.push('Task created');
    setOpenTaskId(newId);
    setShowAddModal(false);
  };

  const exportCSV = () => {
    const rows = [['ID','Name','Project','Status','Priority','Work Type','Assignee','Due Date','Start Date']];
    filteredTasks.forEach(t => {
      rows.push([
        t.id, t.name,
        getProject(t.project)?.name || '',
        t.status, t.priority, t.workType || '',
        getUser(t.assignee)?.name || '',
        t.dueDate || '', t.startDate || '',
      ]);
    });
    const csv = rows.map(r => r.map(c => `"${String(c).replace(/"/g, '""')}"`).join(',')).join('\n');
    const blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url; a.download = `tasks-${new Date().toISOString().split('T')[0]}.csv`;
    a.click(); URL.revokeObjectURL(url);
    toast.push('CSV exported');
  };

  const openTask = tasks.find(t => t.id === openTaskId);
  const myCount = tasks.filter(t => (t.assignee === currentUser.id || t.pic === currentUser.id) && !['Done','Cancel','Archived'].includes(t.status)).length;
  const archivedCount = tasks.filter(t => t.status === 'Archived').length;
  const inboxCount = React.useMemo(() => {
    // unread inbox items count (rough)
    if (!currentUser) return 0;
    let n = 0;
    tasks.forEach(t => {
      if (t.assignee === currentUser.id) {
        const days = daysFromToday(t.dueDate);
        if (days !== null && days <= 1 && !['Done','Cancel','Archived'].includes(t.status)) n++;
      }
      (t.comments || []).forEach(c => {
        if (c.author !== currentUser.id && (t.assignee === currentUser.id || t.pic === currentUser.id)) {
          if (daysFromToday(c.time) >= -3) n++;
        }
      });
    });
    return n;
  }, [tasks, currentUser.id]);

  // ── PAGE TITLE ──
  let viewTitle = 'All tasks';
  let viewCrumb = '';
  if (page === 'inbox') { viewTitle = 'Inbox'; viewCrumb = ''; }
  else if (page === 'team') { viewTitle = 'Team'; viewCrumb = ''; }
  else if (page === 'archived') { viewTitle = 'Archived'; viewCrumb = ''; }
  else if (page === 'profile') { viewTitle = 'Profile'; viewCrumb = 'Settings'; }
  else if (page === 'preferences') { viewTitle = 'Preferences'; viewCrumb = 'Settings'; }
  else if (page === 'admin') { viewTitle = 'Admin'; viewCrumb = 'Workspace'; }
  else if (scope === 'mine') { viewTitle = 'My tasks'; }
  else if (scope.startsWith('project:')) {
    const p = getProject(scope.slice(8));
    if (p) { viewTitle = p.name; viewCrumb = 'Projects'; }
  }

  return (
    <div className="app" data-sidebar={sidebarCollapsed ? 'collapsed' : 'expanded'}>
      {/* SIDEBAR */}
      <aside className="sidebar">
        <div className="sb-brand">
          <div className="sb-logo">T</div>
          {!sidebarCollapsed && (
            <div>
              <div className="sb-name">Tasker <span>· DTGO</span></div>
            </div>
          )}
          <button className="sb-collapse" onClick={() => setSidebarCollapsed(s => !s)} title="Toggle sidebar">
            <Icon name="panelLeft" size={15} />
          </button>
        </div>

        <div style={{ overflowY: 'auto', flex: 1 }}>
          <div className="sb-section">
            {!sidebarCollapsed && <div className="sb-section-title">Workspace</div>}
            <div className="sb-nav">
              <button className={`sb-item${page === 'tasks' && scope === 'all' ? ' active' : ''}`} onClick={() => { setPage('tasks'); setScope('all'); setView('kanban'); }}>
                <Icon name="home" size={16} />
                <span className="label">Home</span>
              </button>
              <button className={`sb-item${page === 'tasks' && scope === 'mine' ? ' active' : ''}`} onClick={() => { setPage('tasks'); setScope('mine'); }}>
                <Icon name="user" size={16} />
                <span className="label">My tasks</span>
                {myCount > 0 && <span className="badge">{myCount}</span>}
              </button>
              <button className={`sb-item${page === 'inbox' ? ' active' : ''}`} onClick={() => setPage('inbox')}>
                <Icon name="inbox" size={16} />
                <span className="label">Inbox</span>
                {inboxCount > 0 && <span className="badge">{inboxCount}</span>}
              </button>
              <button className={`sb-item${page === 'team' ? ' active' : ''}`} onClick={() => setPage('team')}>
                <Icon name="users" size={16} />
                <span className="label">Team</span>
              </button>
              <button className={`sb-item${page === 'archived' ? ' active' : ''}`} onClick={() => setPage('archived')}>
                <Icon name="folder" size={16} />
                <span className="label">Archived</span>
                {archivedCount > 0 && <span className="badge">{archivedCount}</span>}
              </button>
            </div>
          </div>

          <div className="sb-section">
            {!sidebarCollapsed && (
              <div className="sb-section-title">
                <span>Projects</span>
                <button title="New project"><Icon name="plus" size={12} /></button>
              </div>
            )}
            <div className="sb-nav">
              {PROJECTS.filter(p => p.favorite).map(p => (
                <button
                  key={p.id}
                  className={`sb-item${page === 'tasks' && scope === `project:${p.id}` ? ' active' : ''}`}
                  onClick={() => { setPage('tasks'); setScope(`project:${p.id}`); }}
                >
                  <span className="dot" style={{ background: p.color }} />
                  <span className="label">{p.name}</span>
                </button>
              ))}
              {!sidebarCollapsed && (
                <details style={{ marginTop: 2 }}>
                  <summary className="sb-item" style={{ listStyle: 'none', fontSize: 12, color: 'var(--text-subtle)' }}>
                    <Icon name="folder" size={14} />
                    <span className="label">Show all ({PROJECTS.length})</span>
                  </summary>
                  <div style={{ paddingLeft: 4 }}>
                    {PROJECTS.filter(p => !p.favorite).map(p => (
                      <button
                        key={p.id}
                        className={`sb-item${page === 'tasks' && scope === `project:${p.id}` ? ' active' : ''}`}
                        onClick={() => { setPage('tasks'); setScope(`project:${p.id}`); }}
                      >
                        <span className="dot" style={{ background: p.color }} />
                        <span className="label">{p.name}</span>
                      </button>
                    ))}
                  </div>
                </details>
              )}
            </div>
          </div>
        </div>

        <div className="sb-footer">
          <button className="sb-user" onClick={() => setShowUserMenu(s => !s)} style={{ position: 'relative' }}>
            <Avatar user={currentUser} size="md" />
            {!sidebarCollapsed && (
              <div className="sb-user-text" style={{ flex: 1, textAlign: 'left', minWidth: 0 }}>
                <div className="sb-user-name" style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{currentUser.short}</div>
                <div className="sb-user-role">{currentUser.role}</div>
              </div>
            )}
            <Icon name="chevronDown" size={14} />
            {showUserMenu && (
              <div className="popover" style={{ bottom: 56, left: 12, right: 12, minWidth: 0 }}>
                <div style={{ padding: '8px 10px', fontSize: 12 }}>
                  <div style={{ fontWeight: 700, color: 'var(--text)' }}>{currentUser.name}</div>
                  <div style={{ color: 'var(--text-subtle)' }}>{currentUser.email}</div>
                </div>
                <div className="pop-sep" />
                <button className="pop-item" onClick={() => { setPage('profile'); setShowUserMenu(false); }}>
                  <Icon name="user" size={14} /> Profile settings
                </button>
                <button className="pop-item" onClick={() => setTweak('theme', tw.theme === 'dark' ? 'light' : 'dark')}>
                  <Icon name={tw.theme === 'dark' ? 'sun' : 'moon'} size={14} />
                  {tw.theme === 'dark' ? 'Light mode' : 'Dark mode'}
                </button>
                <button className="pop-item" onClick={() => { setPage('preferences'); setShowUserMenu(false); }}>
                  <Icon name="settings" size={14} /> Preferences
                </button>
                {currentUser.access === 'Admin' && (
                  <button className="pop-item" onClick={() => { setPage('admin'); setShowUserMenu(false); }}>
                    <Icon name="users" size={14} /> Admin · workspace
                  </button>
                )}
                <div className="pop-sep" />
                <button className="pop-item danger" onClick={() => { localStorage.removeItem('tasker_uid'); setCurrentUserId(null); }}>
                  <Icon name="logout" size={14} /> Sign out
                </button>
              </div>
            )}
          </button>
        </div>
      </aside>

      {/* MAIN */}
      <div className="main" style={page !== 'tasks' ? { gridTemplateRows: 'var(--topbar-h) 1fr' } : undefined}>
        {/* TOPBAR */}
        <header className="topbar">
          <div className="tb-title">
            {viewCrumb && <><span className="crumb">{viewCrumb}</span><span style={{ color: 'var(--text-subtle)' }}>/</span></>}
            <span>{viewTitle}</span>
            {page === 'tasks' && scope.startsWith('project:') && (
              <span style={{ width: 10, height: 10, borderRadius: '50%', background: getProject(scope.slice(8))?.color, marginLeft: 4 }} />
            )}
          </div>
          <div className="tb-spacer" />
          {window.TaskerAPI?.isConfigured() && (
            <div className="sync-badge" title={
              syncStatus === 'error'   ? 'Sync failed — check connection' :
              syncStatus === 'syncing' ? 'Syncing to Google Sheets…' : 'Synced with Google Sheets'
            }>
              <div className={`sync-dot ${syncStatus}`} />
              <span style={{ fontSize: 11, color: 'var(--text-muted)' }}>
                {syncStatus === 'syncing' ? 'Syncing…' : syncStatus === 'error' ? 'Sync error' : 'Sheets ✓'}
              </span>
            </div>
          )}
          <div className="tb-search">
            <Icon name="search" size={14} />
            <input
              placeholder={page === 'team' ? 'Search members…' : 'Search tasks…'}
              value={filters.search}
              onChange={(e) => setFilters(f => ({ ...f, search: e.target.value }))}
            />
            <span className="kbd">⌘K</span>
          </div>
          <IconBtn icon="bell" hasDot title="Notifications" onClick={() => setPage('inbox')} />
          <IconBtn
            icon={tw.theme === 'dark' ? 'sun' : 'moon'}
            title="Toggle theme"
            onClick={() => setTweak('theme', tw.theme === 'dark' ? 'light' : 'dark')}
          />
          <Btn kind="primary" icon="plus" onClick={() => setShowAddModal(true)}>New task</Btn>
        </header>

        {/* SUBBAR — only for tasks page */}
        {page === 'tasks' && (
        <div className="subbar">
          <div className="view-tabs">
            {VIEWS.map(v => (
              <button
                key={v.id}
                className={`view-tab${view === v.id ? ' active' : ''}`}
                onClick={() => setView(v.id)}
              >
                <Icon name={v.icon} size={13} />
                {v.label}
              </button>
            ))}
          </div>

          {view === 'list' && (
            <select
              className="filter-chip"
              value={groupBy}
              onChange={(e) => setGroupBy(e.target.value)}
              style={{ appearance: 'none', cursor: 'pointer' }}
            >
              <option value="status">Group by: Status</option>
              <option value="priority">Group by: Priority</option>
              <option value="project">Group by: Project</option>
            </select>
          )}

          <button
            className={`filter-chip${Object.values(filters).some(v => v && v !== filters.search) ? ' active' : ''}`}
            onClick={() => setShowFilters(s => !s)}
          >
            <Icon name="filter" size={12} />
            Filters
            {Object.values(filters).filter(v => v && v !== filters.search).length > 0 && (
              <span style={{ background: 'currentColor', color: 'var(--bg-elevated)', borderRadius: 99, padding: '0 5px', fontSize: 10, marginLeft: 4 }}>
                {Object.values(filters).filter(v => v && v !== filters.search).length}
              </span>
            )}
          </button>

          {showFilters && (
            <>
              <select className="filter-chip" value={filters.priority} onChange={(e) => setFilters(f => ({ ...f, priority: e.target.value }))}>
                <option value="">Any priority</option>
                {PRIORITIES.map(p => <option key={p} value={p}>{p}</option>)}
              </select>
              <select className="filter-chip" value={filters.status} onChange={(e) => setFilters(f => ({ ...f, status: e.target.value }))}>
                <option value="">Any status</option>
                {STATUSES.map(s => <option key={s.key} value={s.key}>{s.label}</option>)}
              </select>
              <select className="filter-chip" value={filters.assignee} onChange={(e) => setFilters(f => ({ ...f, assignee: e.target.value }))}>
                <option value="">Anyone</option>
                {USERS.map(u => <option key={u.id} value={u.id}>{u.short}</option>)}
              </select>
              <select className="filter-chip" value={filters.workType} onChange={(e) => setFilters(f => ({ ...f, workType: e.target.value }))}>
                <option value="">Any work type</option>
                {WORK_TYPES.map(w => <option key={w} value={w}>{w}</option>)}
              </select>
              {Object.values(filters).some(v => v && v !== filters.search) && (
                <button className="filter-chip" onClick={() => setFilters({ search: filters.search, status: '', priority: '', workType: '', assignee: '', project: '' })}>
                  <Icon name="x" size={11} /> Clear
                </button>
              )}
            </>
          )}

          <div className="sub-right">
            <span className="result-pill">{filteredTasks.length} task{filteredTasks.length !== 1 ? 's' : ''}</span>
            <IconBtn icon="download" title="Export CSV" onClick={exportCSV} />
            <div style={{ width: 1, height: 18, background: 'var(--border)' }} />
            <span style={{ display: 'inline-flex' }}>
              <AvatarStack users={USERS.slice(0, 5)} max={5} size="sm" />
            </span>
          </div>
        </div>
        )}

        {/* MAIN BODY */}
        <div className="main-body">
          {page === 'inbox' && (
            <InboxView tasks={tasks} currentUser={currentUser} onOpenTask={setOpenTaskId} />
          )}
          {page === 'team' && (
            <TeamView
              tasks={tasks}
              currentUser={currentUser}
              onOpenTask={setOpenTaskId}
              onScopeToMember={(uid) => { setPage('tasks'); setFilters(f => ({ ...f, assignee: uid })); setScope('all'); }}
            />
          )}
          {page === 'archived' && (
            <ArchivedView
              tasks={tasks}
              onOpenTask={setOpenTaskId}
              onUpdate={updateTask}
              onRestore={restoreTask}
              onDelete={deleteTask}
            />
          )}
          {page === 'profile' && (
            <ProfileView
              currentUser={currentUser}
              onUpdateUser={(u) => setUsers(us => us.map(x => x.id === u.id ? u : x))}
            />
          )}
          {page === 'preferences' && (
            <PreferencesView
              tw={tw} setTweak={setTweak}
              prefs={prefs}
              onUpdatePrefs={setPrefs}
            />
          )}
          {page === 'admin' && (
            <AdminView
              users={users}
              currentUser={currentUser}
              onUpdateUser={(u) => setUsers(us => us.map(x => x.id === u.id ? u : x))}
              onInvite={() => toast.push('Invitations sent ✉️')}
              onRemove={(id) => setUsers(us => us.filter(x => x.id !== id))}
            />
          )}
          {page === 'tasks' && view === 'kanban' && (
            <KanbanView
              tasks={filteredTasks}
              onOpenTask={setOpenTaskId}
              onMoveTask={moveTask}
              onAddInColumn={(status) => { setShowAddModal(true); /* could prefill */ }}
            />
          )}
          {page === 'tasks' && view === 'list' && (
            <ListView
              tasks={filteredTasks}
              onOpenTask={setOpenTaskId}
              onToggleDone={toggleDone}
              groupBy={groupBy}
            />
          )}
          {page === 'tasks' && view === 'calendar' && (
            <CalendarView tasks={filteredTasks} onOpenTask={setOpenTaskId} />
          )}
          {page === 'tasks' && view === 'dashboard' && (
            <Dashboard tasks={filteredTasks} currentUser={currentUser} onOpenTask={setOpenTaskId} />
          )}
        </div>
      </div>

      {/* TASK DETAIL */}
      <TaskDetail
        task={openTask}
        open={!!openTask}
        onClose={() => setOpenTaskId(null)}
        onUpdate={updateTask}
        onDelete={deleteTask}
        currentUser={currentUser}
        allTasks={tasks}
      />

      {/* ADD TASK MODAL */}
      <AddTaskModal
        open={showAddModal}
        onClose={() => setShowAddModal(false)}
        onAdd={addTask}
        currentUser={currentUser}
      />

      {/* TWEAKS */}
      <TweaksPanel title="Tweaks">
        <TweakSection label="Appearance">
          <TweakRadio
            label="Theme"
            value={tw.theme}
            options={[{ value: 'light', label: 'Light' }, { value: 'dark', label: 'Dark' }]}
            onChange={(v) => setTweak('theme', v)}
          />
          <TweakColor
            label="Brand"
            value={tw.brand}
            options={[
              ['#F3F0FF','#E5DEFF','#A990FF','#8B6CFF','#6D49F2','#5B36DC'],
              ['#FFF1F2','#FFE4E6','#FB7185','#F43F5E','#E11D48','#BE123C'],
              ['#ECFEFF','#CFFAFE','#67E8F9','#22D3EE','#06B6D4','#0891B2'],
              ['#FEF3C7','#FDE68A','#FCD34D','#FBBF24','#F59E0B','#D97706'],
              ['#DCFCE7','#BBF7D0','#86EFAC','#4ADE80','#22C55E','#16A34A'],
            ]}
            onChange={(v) => setTweak('brand', v)}
          />
        </TweakSection>
        <TweakSection label="Layout">
          <TweakToggle label="Compact cards" value={tw.compactCards} onChange={(v) => setTweak('compactCards', v)} />
          <TweakToggle label="Show progress bars" value={tw.showCardProgress} onChange={(v) => setTweak('showCardProgress', v)} />
        </TweakSection>
        <TweakSection label="Data">
          <TweakButton
            label="Reset to demo data"
            onClick={() => {
              if (confirm('Reset all tasks to demo data?')) {
                setTasks(TASKS);
                toast.push('Demo data restored');
              }
            }}
          />
        </TweakSection>
      </TweaksPanel>

      {toast.ui}
    </div>
  );
};

/* ============================================
   ADD TASK MODAL
   ============================================ */
const AddTaskModal = ({ open, onClose, onAdd, currentUser }) => {
  const [form, setForm] = React.useState({
    name: '', project: '', workType: '', priority: 'Medium', status: 'Backlog',
    assignee: currentUser?.id || '', pic: '', startDate: '', dueDate: '',
    description: '', recurring: null,
  });
  React.useEffect(() => {
    if (open) setForm({
      name: '', project: '', workType: '', priority: 'Medium', status: 'Backlog',
      assignee: currentUser?.id || '', pic: '', startDate: '', dueDate: '',
      description: '', recurring: null,
    });
  }, [open]);

  const submit = () => {
    if (!form.name.trim()) { alert('Please enter a task name'); return; }
    onAdd(form);
  };

  const set = (patch) => setForm(f => ({ ...f, ...patch }));

  return (
    <Modal
      open={open}
      onClose={onClose}
      title="New task"
      footer={<>
        <Btn kind="ghost" onClick={onClose}>Cancel</Btn>
        <Btn kind="primary" icon="check" onClick={submit}>Create task</Btn>
      </>}
    >
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        <div className="fg">
          <label className="fl">Task name *</label>
          <input className="fi" placeholder="What needs to be done?" value={form.name} onChange={(e) => set({ name: e.target.value })} autoFocus />
        </div>
        <div className="fg">
          <label className="fl">Description</label>
          <textarea className="fta" placeholder="Add details…" value={form.description} onChange={(e) => set({ description: e.target.value })} />
        </div>
        <div className="form-grid">
          <div className="fg">
            <label className="fl">Project</label>
            <select className="fs" value={form.project} onChange={(e) => set({ project: e.target.value })}>
              <option value="">Select project…</option>
              {PROJECTS.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
            </select>
          </div>
          <div className="fg">
            <label className="fl">Work type</label>
            <select className="fs" value={form.workType} onChange={(e) => set({ workType: e.target.value })}>
              <option value="">Select…</option>
              {WORK_TYPES.map(w => <option key={w} value={w}>{w}</option>)}
            </select>
          </div>
          <div className="fg">
            <label className="fl">Assignee</label>
            <select className="fs" value={form.assignee} onChange={(e) => set({ assignee: e.target.value })}>
              <option value="">Unassigned</option>
              {USERS.map(u => <option key={u.id} value={u.id}>{u.name}</option>)}
            </select>
          </div>
          <div className="fg">
            <label className="fl">Priority</label>
            <select className="fs" value={form.priority} onChange={(e) => set({ priority: e.target.value })}>
              {PRIORITIES.map(p => <option key={p} value={p}>{p}</option>)}
            </select>
          </div>
          <div className="fg">
            <label className="fl">Start date</label>
            <input type="date" className="fi" value={form.startDate} onChange={(e) => set({ startDate: e.target.value })} />
          </div>
          <div className="fg">
            <label className="fl">Due date</label>
            <input type="date" className="fi" value={form.dueDate} onChange={(e) => set({ dueDate: e.target.value })} />
          </div>
          <div className="fg">
            <label className="fl">Status</label>
            <select className="fs" value={form.status} onChange={(e) => set({ status: e.target.value })}>
              {STATUSES.map(s => <option key={s.key} value={s.key}>{s.label}</option>)}
            </select>
          </div>
          <div className="fg">
            <label className="fl">Recurring</label>
            <select
              className="fs"
              value={form.recurring?.freq || ''}
              onChange={(e) => {
                const v = e.target.value;
                if (!v) set({ recurring: null });
                else set({ recurring: { freq: v, label: ({ daily:'Every day', weekly:'Every week', monthly:'Every month', quarterly:'Every quarter' })[v] } });
              }}
            >
              <option value="">Doesn't repeat</option>
              <option value="daily">Every day</option>
              <option value="weekly">Every week</option>
              <option value="monthly">Every month</option>
              <option value="quarterly">Every quarter</option>
            </select>
          </div>
        </div>
      </div>
    </Modal>
  );
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "brand": ["#F3F0FF","#E5DEFF","#A990FF","#8B6CFF","#6D49F2","#5B36DC"],
  "compactCards": false,
  "showCardProgress": true
}/*EDITMODE-END*/;

const DEFAULT_PREFS = {
  density: 'regular',
  sidebarCollapsedDefault: false,
  defaultView: 'kanban',
  defaultScope: 'all',
  defaultGroupBy: 'status',
  dateFormat: 'short',
  firstDayOfWeek: 'sun',
  timeFormat: '12',
  notif: {
    assigned:     { app: true,  email: true,  push: true  },
    mentioned:    { app: true,  email: true,  push: true  },
    comment:      { app: true,  email: false, push: false },
    dueSoon:      { app: true,  email: true,  push: true  },
    overdue:      { app: true,  email: true,  push: false },
    statusChange: { app: false, email: false, push: false },
    weeklyDigest: { app: false, email: true,  push: false },
  },
};

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
