/* global React, Icon, IconBtn, db */
/* global ttFmtDuration, ttSessionMs, ttEnsureCycle, ttArchiveCycle, ttRestoreCycle, ttDeleteCycle, TT_PALETTE */
const { useState, useEffect, useMemo } = React;

// ============================================================
// TtCycleModal — create or rename a cycle and pick its colour.
// ============================================================
function TtCycleModal({ cycle, onClose }) {
  const isEdit = !!cycle;
  const [name, setName] = useState(cycle?.name || '');
  const [color, setColor] = useState(cycle?.color || TT_PALETTE[0]);
  const [error, setError] = useState(null);

  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') { e.stopPropagation(); onClose(); } };
    document.addEventListener('keydown', onKey, true);
    return () => document.removeEventListener('keydown', onKey, true);
  }, [onClose]);

  const save = async () => {
    const clean = name.trim();
    if (!clean) { setError('Give the cycle a name.'); return; }
    await db.timeCycles.put({
      ...(isEdit ? cycle : { archived: false }),
      name: clean,
      color,
    });
    onClose();
  };

  return (
    <div className="trk-modal-overlay" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="trk-modal trk-cycle-modal" data-screen-label={isEdit ? 'Edit cycle' : 'New cycle'}>
        <div className="trk-modal-head">
          <Icon name="cycle"></Icon>
          <span>{isEdit ? 'Edit cycle' : 'New cycle'}</span>
          <div style={{ flex: 1 }}></div>
          <IconBtn name="close" title="Close" onClick={onClose}></IconBtn>
        </div>
        <div className="trk-modal-body">
          <input
            autoFocus
            className="lh-input trk-modal-desc"
            placeholder="Cycle name — e.g. June 2026 payrun"
            value={name}
            onChange={e => setName(e.target.value)}
            onKeyDown={e => { if (e.key === 'Enter') save(); }}
            maxLength={80}
          />
          <div className="trk-modal-field">
            <label>Colour</label>
            <div className="trk-cycle-swatches">
              {TT_PALETTE.map(c => (
                <button
                  key={c}
                  type="button"
                  className={`trk-cycle-swatch ${color === c ? 'is-on' : ''}`}
                  style={{ background: c }}
                  onClick={() => setColor(c)}
                  title={c}
                ></button>
              ))}
            </div>
          </div>
          {error && (
            <div className="trk-modal-error">
              <Icon name="error_outline"></Icon>
              <span>{error}</span>
            </div>
          )}
        </div>
        <div className="trk-modal-foot">
          <div style={{ flex: 1 }}></div>
          <button className="lh-btn ghost" onClick={onClose}>Cancel</button>
          <button className="lh-btn primary" onClick={save}>
            <Icon name="check"></Icon>{isEdit ? 'Save' : 'Create cycle'}
          </button>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// TtCyclesView — manage cycles: create, edit, archive/restore, delete.
// Each cycle shows its task count and total hours (archived work still
// counts toward the total — you archive a finished payrun, not its hours).
// ============================================================
function TtCyclesView({ cycles, tasks, sessions, settings, onViewTasks }) {
  const [showArchived, setShowArchived] = useState(false);
  const [editing, setEditing] = useState(null); // { cycle } | { new:true } | null
  const secs = settings.listSeconds;

  // taskId → cycleId, plus per-cycle rollups
  const stats = useMemo(() => {
    const taskCycle = new Map();
    const taskCount = new Map();
    for (const t of tasks || []) {
      if (t.cycleId) {
        taskCycle.set(t.id, t.cycleId);
        taskCount.set(t.cycleId, (taskCount.get(t.cycleId) || 0) + 1);
      }
    }
    const ms = new Map();
    for (const s of sessions || []) {
      const cid = taskCycle.get(s.taskId);
      if (cid) ms.set(cid, (ms.get(cid) || 0) + ttSessionMs(s));
    }
    return { taskCount, ms };
  }, [tasks, sessions]);

  const visible = useMemo(() => {
    return (cycles || [])
      .filter(c => showArchived || !c.archived)
      .sort((a, b) => Number(a.archived) - Number(b.archived) || (a.name || '').localeCompare(b.name || ''));
  }, [cycles, showArchived]);

  const archivedCount = (cycles || []).filter(c => c.archived).length;

  const archive = async (c) => {
    const n = stats.taskCount.get(c.id) || 0;
    const ok = await window.lhDialog.confirm({
      title: 'Archive cycle?',
      message: `“${c.name}” and its ${n} ${n === 1 ? 'task' : 'tasks'} will be archived and hidden from the tracker. Totals are kept; you can restore it any time.`,
      confirmLabel: 'Archive', icon: 'inventory_2',
    });
    if (ok) ttArchiveCycle(c.id);
  };
  const remove = async (c) => {
    const n = stats.taskCount.get(c.id) || 0;
    const ok = await window.lhDialog.confirm({
      title: 'Delete cycle?',
      message: `“${c.name}” will be deleted. Its ${n} ${n === 1 ? 'task' : 'tasks'} are kept but un-assigned from the cycle.`,
      confirmLabel: 'Delete', danger: true, icon: 'delete',
    });
    if (ok) ttDeleteCycle(c.id);
  };

  return (
    <div className="trk-cycles" data-screen-label="Cycles">
      <div className="trk-cycles-bar">
        <button className="lh-btn primary" onClick={() => setEditing({ new: true })}>
          <Icon name="add"></Icon>New cycle
        </button>
        {archivedCount > 0 && (
          <label className="trk-archive-toggle">
            <input type="checkbox" checked={showArchived} onChange={e => setShowArchived(e.target.checked)} />
            <span>Show archived ({archivedCount})</span>
          </label>
        )}
      </div>

      {visible.length === 0 ? (
        <div className="lh-empty trk-empty">
          <Icon name="cycle"></Icon>
          <div className="title">No cycles yet</div>
          <div className="sub">Create a cycle (like a payrun period) and assign tasks to it to roll up hours.</div>
          <button className="lh-btn primary" onClick={() => setEditing({ new: true })}>
            <Icon name="add"></Icon>New cycle
          </button>
        </div>
      ) : (
        <div className="trk-cycle-list">
          {visible.map(c => {
            const n = stats.taskCount.get(c.id) || 0;
            const total = stats.ms.get(c.id) || 0;
            return (
              <div className={`trk-cycle-card ${c.archived ? 'is-archived' : ''}`} key={c.id}>
                <span className="trk-cycle-dot" style={{ background: c.color || 'var(--text-faint)' }}></span>
                <div className="trk-cycle-main">
                  <div className="trk-cycle-name">
                    {c.name}
                    {c.archived && <span className="trk-archived-badge">Archived</span>}
                  </div>
                  <div className="trk-cycle-meta">
                    {n} {n === 1 ? 'task' : 'tasks'} · {ttFmtDuration(total, { seconds: secs })}
                  </div>
                </div>
                <div className="trk-cycle-actions">
                  {n > 0 && (
                    <IconBtn name="visibility" title="View tasks in tracker" onClick={() => onViewTasks(c.id)}></IconBtn>
                  )}
                  {!c.archived && <IconBtn name="edit" title="Edit cycle" onClick={() => setEditing({ cycle: c })}></IconBtn>}
                  {c.archived ? (
                    <IconBtn name="unarchive" title="Restore cycle and its tasks" onClick={() => ttRestoreCycle(c.id)}></IconBtn>
                  ) : (
                    <IconBtn name="inventory_2" title="Archive cycle and its tasks" onClick={() => archive(c)}></IconBtn>
                  )}
                  <IconBtn name="delete" tone="danger" title="Delete cycle" onClick={() => remove(c)}></IconBtn>
                </div>
              </div>
            );
          })}
        </div>
      )}

      {editing && (
        <TtCycleModal
          cycle={editing.cycle || null}
          onClose={() => setEditing(null)}
        ></TtCycleModal>
      )}
    </div>
  );
}

window.TtCyclesView = TtCyclesView;
window.TtCycleModal = TtCycleModal;
