// App shell + Tweaks panel + Windows chrome
const { useState, useEffect, useRef, useMemo } = window.React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accentHue": 88,
  "islandGap": 14,
  "islandRadius": 14,
  "grainOpacity": 0.035,
  "density": "comfy",
  "sidebarWidth": 260
}/*EDITMODE-END*/;

const HUE_PRESETS = [
  { name: 'Moss',    h: 88 },
  { name: 'Sea',     h: 200 },
  { name: 'Peat',    h: 60 },
  { name: 'Heather', h: 310 },
  { name: 'Rust',    h: 30 },
];

const TweaksPanel = ({ open, onClose, tweaks, setTweaks }) => {
  const update = (k, v) => {
    const next = { ...tweaks, [k]: v };
    setTweaks(next);
    try {
      window.parent.postMessage({ type: '__edit_mode_set_keys', edits: { [k]: v } }, '*');
    } catch (e) {}
  };
  return (
    <div className={`tweaks-panel ${open ? 'open' : ''}`}>
      <div className="tweaks-head">
        <div className="tweaks-title">Tweaks</div>
        <button className="tweaks-close" onClick={onClose}><Icon name="close" size={12} /></button>
      </div>

      <div style={{ marginBottom: 10 }}>
        <div className="tweak-row" style={{ paddingBottom: 4 }}>
          <span className="label">Accent</span>
          <span className="val">H {tweaks.accentHue}</span>
        </div>
        <div className="hue-swatches">
          {HUE_PRESETS.map((p) => (
            <div
              key={p.h}
              className={`hue-swatch ${tweaks.accentHue === p.h ? 'active' : ''}`}
              style={{ background: `oklch(58% 0.08 ${p.h})` }}
              title={p.name}
              onClick={() => update('accentHue', p.h)}
            />
          ))}
          <input
            type="range" min="0" max="360" step="1"
            value={tweaks.accentHue}
            onChange={(e) => update('accentHue', +e.target.value)}
            style={{ flex: 1, marginLeft: 6 }}
          />
        </div>
      </div>

      <div className="tweak-row">
        <span className="label">Gap</span>
        <input type="range" min="4" max="28" step="1" value={tweaks.islandGap}
               onChange={(e) => update('islandGap', +e.target.value)} />
        <span className="val">{tweaks.islandGap}px</span>
      </div>
      <div className="tweak-row">
        <span className="label">Radius</span>
        <input type="range" min="0" max="24" step="1" value={tweaks.islandRadius}
               onChange={(e) => update('islandRadius', +e.target.value)} />
        <span className="val">{tweaks.islandRadius}px</span>
      </div>
      <div className="tweak-row">
        <span className="label">Grain</span>
        <input type="range" min="0" max="0.12" step="0.005" value={tweaks.grainOpacity}
               onChange={(e) => update('grainOpacity', +e.target.value)} />
        <span className="val">{tweaks.grainOpacity.toFixed(3)}</span>
      </div>
      <div className="tweak-row">
        <span className="label">Sidebar</span>
        <input type="range" min="200" max="340" step="4" value={tweaks.sidebarWidth}
               onChange={(e) => update('sidebarWidth', +e.target.value)} />
        <span className="val">{tweaks.sidebarWidth}</span>
      </div>
      <div className="tweak-row">
        <span className="label">Density</span>
        <div className="density-toggle">
          <button className={tweaks.density === 'comfy' ? 'on' : ''} onClick={() => update('density', 'comfy')}>Comfy</button>
          <button className={tweaks.density === 'compact' ? 'on' : ''} onClick={() => update('density', 'compact')}>Compact</button>
        </div>
      </div>
    </div>
  );
};

// Windows chrome
const TitleBar = ({ search }) => {
  return (
    <div className="titlebar">
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          width: 16, height: 16, borderRadius: 4,
          background: 'linear-gradient(135deg, var(--moss), var(--sage))',
          display: 'grid', placeItems: 'center',
        }}>
          <svg width="9" height="9" viewBox="0 0 10 10" fill="none" stroke="#0a0e0c" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M2 5l2 2 4-4"/></svg>
        </div>
        <span className="titlebar-title">
          ClaudeDo <span className="bullet">·</span> Rider Island
        </span>
      </div>
      <div className="titlebar-controls">
        <button className="titlebar-btn"><Icon name="min" size={12} /></button>
        <button className="titlebar-btn"><Icon name="max" size={12} /></button>
        <button className="titlebar-btn close"><Icon name="close" size={12} /></button>
      </div>
    </div>
  );
};

const Taskbar = () => {
  const [clock, setClock] = useState(() => {
    const n = new Date();
    return {
      time: n.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
      date: n.toLocaleDateString([], { month: 'short', day: 'numeric', year: 'numeric' }),
    };
  });
  useEffect(() => {
    const id = setInterval(() => {
      const n = new Date();
      setClock({
        time: n.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
        date: n.toLocaleDateString([], { month: 'short', day: 'numeric', year: 'numeric' }),
      });
    }, 30000);
    return () => clearInterval(id);
  }, []);
  const icons = ['windows', 'search', 'folder', 'inbox', 'note', 'calendar'];
  return (
    <div className="taskbar">
      {icons.map((ic, i) => (
        <div key={i} className={`taskbar-icon ${ic === 'note' ? 'active' : ''}`}>
          <Icon name={ic} size={16} />
        </div>
      ))}
      <div className="taskbar-clock">
        <div>{clock.time}</div>
        <div>{clock.date}</div>
      </div>
    </div>
  );
};

// ---------- App ----------
const App = () => {
  const [tweaks, setTweaks] = useState(TWEAK_DEFAULTS);
  const [tweaksOpen, setTweaksOpen] = useState(false);
  const [editMode, setEditMode] = useState(false);

  const [tasks, setTasks] = useState(SEED_TASKS);
  const [activeList, setActiveList] = useState('myday');
  const [selectedId, setSelectedId] = useState('t1');
  const [search, setSearch] = useState('');
  const [showCompleted, setShowCompleted] = useState(true);
  const [leavingIds, setLeavingIds] = useState([]);
  const [enteringIds, setEnteringIds] = useState([]);
  const [diffTaskId, setDiffTaskId] = useState(null);
  const [worktreeTaskId, setWorktreeTaskId] = useState(null);

  // Apply CSS tweaks
  useEffect(() => {
    const r = document.documentElement;
    r.style.setProperty('--accent-h', tweaks.accentHue);
    r.style.setProperty('--island-gap', tweaks.islandGap + 'px');
    r.style.setProperty('--island-radius', tweaks.islandRadius + 'px');
    r.style.setProperty('--grain-opacity', tweaks.grainOpacity);
    r.style.setProperty('--sidebar-w', tweaks.sidebarWidth + 'px');
    r.style.setProperty('--density', tweaks.density === 'comfy' ? 1 : 0.82);
  }, [tweaks]);

  // Tweaks host protocol
  useEffect(() => {
    const onMsg = (e) => {
      const d = e.data;
      if (!d || typeof d !== 'object') return;
      if (d.type === '__activate_edit_mode') { setEditMode(true); setTweaksOpen(true); }
      if (d.type === '__deactivate_edit_mode') { setEditMode(false); setTweaksOpen(false); }
    };
    window.addEventListener('message', onMsg);
    try { window.parent.postMessage({ type: '__edit_mode_available' }, '*'); } catch (e) {}
    return () => window.removeEventListener('message', onMsg);
  }, []);

  // Counts per list
  const counts = useMemo(() => {
    const c = {};
    c.myday = tasks.filter((t) => t.myDay && !t.done).length;
    c.important = tasks.filter((t) => t.starred && !t.done).length;
    c.planned = tasks.filter((t) => t.due && !t.done).length;
    c.assigned = 0;
    c.flagged = 0;
    c.all = tasks.filter((t) => !t.done).length;
    SEED_USER_LISTS.forEach((l) => {
      c[l.id] = tasks.filter((t) => t.list === l.id && !t.done).length;
    });
    return c;
  }, [tasks]);

  // Filter tasks
  const visibleTasks = useMemo(() => {
    let ts = tasks;
    if (activeList === 'myday') ts = ts.filter((t) => t.myDay);
    else if (activeList === 'important') ts = ts.filter((t) => t.starred);
    else if (activeList === 'planned') ts = ts.filter((t) => t.due);
    else if (activeList === 'all') ts = ts;
    else if (activeList === 'assigned' || activeList === 'flagged') ts = [];
    else ts = ts.filter((t) => t.list === activeList);
    if (search) {
      const q = search.toLowerCase();
      ts = ts.filter((t) => t.title.toLowerCase().includes(q) || (t.notes || '').toLowerCase().includes(q));
    }
    return ts;
  }, [tasks, activeList, search]);

  const selected = tasks.find((t) => t.id === selectedId);

  // Actions
  const toggleTask = (id) => {
    setTasks((prev) => prev.map((t) =>
      t.id === id ? { ...t, done: !t.done, completedAt: !t.done ? new Date().toISOString() : null } : t
    ));
  };
  const starTask = (id) => {
    setTasks((prev) => prev.map((t) => t.id === id ? { ...t, starred: !t.starred } : t));
  };
  const updateTask = (next) => {
    setTasks((prev) => prev.map((t) => t.id === next.id ? next : t));
  };
  const deleteTask = (id) => {
    setLeavingIds((l) => [...l, id]);
    setTimeout(() => {
      setTasks((prev) => prev.filter((t) => t.id !== id));
      setLeavingIds((l) => l.filter((x) => x !== id));
      if (selectedId === id) setSelectedId(null);
    }, 280);
  };
  const addTask = (title) => {
    const id = 't' + Date.now();
    const newTask = {
      id, title,
      list: ['myday','important','planned','running','review','all'].includes(activeList) ? 'claudedo' : activeList,
      myDay: true,
      starred: false,
      due: new Date().toISOString(),
      notes: '',
      tags: [],
      subtasks: [],
      created: new Date().toISOString(),
      done: false,
      agent: {
        status: 'idle',
        model: 'claude-sonnet-4.5',
        worktree: `~/worktrees/${activeList}/new-task-${id.slice(1,6)}`,
        branch: `agent/new-task-${id.slice(1,6)}`,
        baseBranch: 'main',
        commits: 0,
        diff: { files: 0, additions: 0, deletions: 0 },
        turns: 0,
        tokens: 0,
        log: [{ t: new Date().toISOString(), k: 'sys', m: 'Worktree ready. Agent not yet dispatched.' }],
      },
    };
    setTasks((prev) => [newTask, ...prev]);
    setEnteringIds((l) => [...l, id]);
    setSelectedId(id);
    setTimeout(() => setEnteringIds((l) => l.filter((x) => x !== id)), 300);
  };

  const agentAction = (id, action) => {
    setTasks((prev) => prev.map((t) => {
      if (t.id !== id || !t.agent) return t;
      if (action === 'start') {
        return { ...t, agent: { ...t.agent, status: 'running', startedAt: new Date().toISOString(),
          log: [...(t.agent.log || []), { t: new Date().toISOString(), k: 'sys', m: 'Agent dispatched.' }] } };
      }
      if (action === 'stop') {
        return { ...t, agent: { ...t.agent, status: 'review', finishedAt: new Date().toISOString(),
          log: [...(t.agent.log || []), { t: new Date().toISOString(), k: 'sys', m: 'Stopped by operator.' }] } };
      }
      return t;
    }));
  };

  const agentInput = (id, msg) => {
    setTasks((prev) => prev.map((t) => {
      if (t.id !== id || !t.agent) return t;
      return { ...t, agent: { ...t.agent, log: [...(t.agent.log || []),
        { t: new Date().toISOString(), k: 'msg', m: '[you] ' + msg }] } };
    }));
  };

  return (
    <div className="desktop">
      <div className="window">
        <TitleBar />
        <div className="window-body">
          <ListsIsland
            activeList={activeList}
            setActiveList={(id) => { setActiveList(id); }}
            counts={counts}
            search={search}
            setSearch={setSearch}
          />
          <TasksIsland
            tasks={visibleTasks}
            selectedId={selectedId}
            setSelected={setSelectedId}
            onToggle={toggleTask}
            onStar={starTask}
            onAdd={addTask}
            leavingIds={leavingIds}
            enteringIds={enteringIds}
            activeList={activeList}
            showCompleted={showCompleted}
            setShowCompleted={setShowCompleted}
          />
          <div className="details-col">
          <DetailsIsland
            task={selected}
            onUpdate={updateTask}
            onDelete={deleteTask}
            onToggle={toggleTask}
            onStar={starTask}
            onAgentAction={agentAction}
            onAgentInput={agentInput}
            onOpenDiff={(id) => setDiffTaskId(id)}
            onOpenWorktree={(id) => setWorktreeTaskId(id)}
          />
          </div>
        </div>
      </div>
      <Taskbar />

      {diffTaskId && (
        <DiffModal
          task={tasks.find((t) => t.id === diffTaskId)}
          onClose={() => setDiffTaskId(null)}
        />
      )}
      {worktreeTaskId && (
        <WorktreeModal
          task={tasks.find((t) => t.id === worktreeTaskId)}
          onClose={() => setWorktreeTaskId(null)}
        />
      )}

      {/* Tweaks: FAB (when edit mode is off) or panel (when toggled) */}
      {editMode && (
        <TweaksPanel
          open={tweaksOpen}
          onClose={() => setTweaksOpen(false)}
          tweaks={tweaks}
          setTweaks={setTweaks}
        />
      )}
    </div>
  );
};

// The inner window shouldn't render TitleBar twice — fix:
// Actually we want ONE window with one titlebar. Remove the outer TitleBar.
const AppFixed = () => <App />;

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