/* global React, Icon, IconBtn, db */
const { useState, useEffect, useMemo, useCallback } = React;

// ============================================================
// Habit tracker — daily check-ins for a small list of habits.
// State: a single kv record { habits: [...], completions: { [id]: { [YYYY-MM-DD]: true } } }
// ============================================================
const HABIT_DAYS_SHOWN = 28; // ~4 weeks of cells per habit
const HABIT_DEFAULT_STATE = { habits: [], completions: {} };
const HABIT_ICONS = ['fitness_center','self_improvement','book','water_drop','restaurant','spa','directions_run','dark_mode','language','code','brush','music_note','medication','phone_iphone','park','psychology','sunny','bed','sports_esports','savings'];
const HABIT_COLORS = ['hsl(8, 78%, 58%)','hsl(28, 90%, 60%)','hsl(45, 90%, 55%)','hsl(108, 50%, 50%)','hsl(168, 60%, 50%)','hsl(192, 70%, 55%)','hsl(212, 85%, 60%)','hsl(258, 70%, 65%)','hsl(290, 60%, 60%)','hsl(330, 65%, 60%)'];

function toDateKey(ts) {
  const d = new Date(ts);
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
}
function todayKey() { return toDateKey(Date.now()); }
function dayKeysBefore(n) {
  const out = [];
  const today = new Date(); today.setHours(0,0,0,0);
  for (let i = 0; i < n; i++) {
    const d = new Date(today);
    d.setDate(today.getDate() - i);
    out.push(toDateKey(d.getTime()));
  }
  return out.reverse(); // oldest first
}
function dayLabel(key) {
  const [, , d] = key.split('-');
  return d;
}
function weekdayLabel(key) {
  const d = new Date(key + 'T00:00:00');
  return ['S','M','T','W','T','F','S'][d.getDay()];
}

function HabitsTool() {
  const [state, setState] = useState(HABIT_DEFAULT_STATE);
  const [loaded, setLoaded] = useState(false);
  const [adding, setAdding] = useState(false);
  const [editingId, setEditingId] = useState(null);

  useEffect(() => {
    db.kv.get('habitTracker').then(rec => {
      if (rec?.v) setState({ ...HABIT_DEFAULT_STATE, ...rec.v });
      setLoaded(true);
    });
  }, []);

  const save = useCallback((next) => {
    setState(next);
    db.kv.put({ k: 'habitTracker', v: next });
  }, []);

  const addHabit = ({ name, icon, color }) => {
    const id = 'h_' + Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
    const next = {
      ...state,
      habits: [...state.habits, { id, name, icon, color, createdAt: Date.now(), archived: false }],
    };
    save(next);
    setAdding(false);
  };

  const updateHabit = (id, patch) => {
    save({
      ...state,
      habits: state.habits.map(h => h.id === id ? { ...h, ...patch } : h),
    });
  };

  const removeHabit = async (id) => {
    const h = state.habits.find(x => x.id === id);
    if (!h) return;
    const ok = await window.lhDialog.confirm({
      title: `Delete "${h.name}"?`,
      message: 'Removes the habit and all its history. Can\'t be undone.',
      confirmLabel: 'Delete',
      danger: true,
      icon: 'delete',
    });
    if (!ok) return;
    const { [id]: _, ...rest } = state.completions;
    save({
      ...state,
      habits: state.habits.filter(h => h.id !== id),
      completions: rest,
    });
    setEditingId(null);
  };

  const toggleDay = (habitId, dateKey) => {
    const cur = state.completions[habitId] || {};
    const nextDay = cur[dateKey] ? undefined : true;
    const nextHabit = { ...cur };
    if (nextDay === undefined) delete nextHabit[dateKey];
    else nextHabit[dateKey] = true;
    save({
      ...state,
      completions: { ...state.completions, [habitId]: nextHabit },
    });
  };

  const days = useMemo(() => dayKeysBefore(HABIT_DAYS_SHOWN), []);
  const today = todayKey();
  const activeHabits = state.habits.filter(h => !h.archived);

  if (!loaded) return <div className="habit-tool habit-loading" />;

  return (
    <div className="habit-tool">
      <header className="habit-head">
        <div>
          <h1>Habits</h1>
          <p>Tap a day to mark it done. Streaks count consecutive days ending today.</p>
        </div>
        <button className="lh-btn primary" onClick={() => setAdding(true)}>
          <Icon name="add" />New habit
        </button>
      </header>

      {adding && (
        <HabitForm
          onSave={addHabit}
          onCancel={() => setAdding(false)}
        />
      )}

      {activeHabits.length === 0 && !adding ? (
        <div className="habit-empty">
          <Icon name="check_circle" />
          <div className="title">No habits yet</div>
          <div className="sub">Start tiny — one thing you'd be proud to do every day.</div>
          <button className="lh-btn primary" onClick={() => setAdding(true)}>
            <Icon name="add" />Add your first habit
          </button>
        </div>
      ) : (
        <div className="habit-list">
          {activeHabits.map(h => (
            <HabitRow
              key={h.id}
              habit={h}
              completions={state.completions[h.id] || {}}
              days={days}
              today={today}
              onToggleDay={(d) => toggleDay(h.id, d)}
              editing={editingId === h.id}
              onEdit={() => setEditingId(h.id === editingId ? null : h.id)}
              onUpdate={(patch) => updateHabit(h.id, patch)}
              onDelete={() => removeHabit(h.id)}
            />
          ))}
        </div>
      )}
    </div>
  );
}

// ============================================================
// HabitRow — one habit + its calendar strip + stats
// ============================================================
function HabitRow({ habit, completions, days, today, onToggleDay, editing, onEdit, onUpdate, onDelete }) {
  // Streak = consecutive days ending today (or yesterday — count today optional).
  const stats = useMemo(() => {
    let streak = 0;
    // Walk backwards from today; if today is empty, allow yesterday to still count.
    const todayDone = !!completions[today];
    let cur = new Date(today + 'T00:00:00');
    if (!todayDone) cur.setDate(cur.getDate() - 1);
    while (true) {
      const k = toDateKey(cur.getTime());
      if (completions[k]) { streak++; cur.setDate(cur.getDate() - 1); }
      else break;
    }
    const done28 = days.filter(d => completions[d]).length;
    return { streak, pct: Math.round((done28 / days.length) * 100), done28 };
  }, [completions, today, days]);

  return (
    <article className="habit-row" style={{ '--habit-color': habit.color }}>
      <div className="habit-row-head">
        <button className="habit-row-icon" onClick={onEdit} title="Edit">
          <Icon name={habit.icon || 'check_circle'} />
        </button>
        <div className="habit-row-meta">
          <div className="habit-row-name">{habit.name}</div>
          <div className="habit-row-stats">
            <span className="habit-stat-streak">
              <Icon name="local_fire_department" />{stats.streak} day{stats.streak === 1 ? '' : 's'}
            </span>
            <span className="habit-stat-dot">·</span>
            <span>{stats.done28} / {days.length} last 4 weeks</span>
            <span className="habit-stat-dot">·</span>
            <span>{stats.pct}%</span>
          </div>
        </div>
        <button
          className={`habit-today ${completions[today] ? 'is-done' : ''}`}
          onClick={() => onToggleDay(today)}
          title={completions[today] ? 'Done today' : 'Mark today done'}
        >
          {completions[today] ? <Icon name="check_circle" /> : <Icon name="radio_button_unchecked" />}
          <span>{completions[today] ? 'Done today' : 'Mark today'}</span>
        </button>
      </div>

      <div className="habit-grid">
        {days.map(k => {
          const done = !!completions[k];
          const isToday = k === today;
          return (
            <button
              key={k}
              className={`habit-cell ${done ? 'is-done' : ''} ${isToday ? 'is-today' : ''}`}
              title={`${k} — ${done ? 'done' : 'not yet'}`}
              onClick={() => onToggleDay(k)}
            >
              <span className="habit-cell-weekday">{weekdayLabel(k)}</span>
              <span className="habit-cell-day">{dayLabel(k)}</span>
            </button>
          );
        })}
      </div>

      {editing && (
        <HabitEditor habit={habit} onUpdate={onUpdate} onDelete={onDelete} onClose={onEdit} />
      )}
    </article>
  );
}

// ============================================================
// HabitForm + HabitEditor — share the icon/color pickers
// ============================================================
function HabitForm({ onSave, onCancel }) {
  const [name, setName] = useState('');
  const [icon, setIcon] = useState(HABIT_ICONS[0]);
  const [color, setColor] = useState(HABIT_COLORS[3]);

  const submit = () => {
    if (!name.trim()) return;
    onSave({ name: name.trim(), icon, color });
  };

  return (
    <div className="habit-form" style={{ '--habit-color': color }}>
      <div className="habit-form-head">
        <Icon name={icon} className="habit-form-icon" />
        <input
          autoFocus
          className="lh-input habit-form-name"
          placeholder="Habit name — e.g. Drink 2L water"
          value={name}
          onChange={e => setName(e.target.value)}
          onKeyDown={e => { if (e.key === 'Enter') submit(); if (e.key === 'Escape') onCancel(); }}
        />
      </div>

      <div className="habit-form-row">
        <div className="habit-form-row-label">Icon</div>
        <div className="habit-form-icons">
          {HABIT_ICONS.map(ic => (
            <button key={ic} className={`habit-pick-icon ${icon === ic ? 'is-active' : ''}`} onClick={() => setIcon(ic)} title={ic}>
              <Icon name={ic} />
            </button>
          ))}
        </div>
      </div>

      <div className="habit-form-row">
        <div className="habit-form-row-label">Color</div>
        <div className="habit-form-colors">
          {HABIT_COLORS.map(c => (
            <button key={c} className={`habit-pick-color ${color === c ? 'is-active' : ''}`} style={{ background: c }} onClick={() => setColor(c)} />
          ))}
        </div>
      </div>

      <div className="habit-form-actions">
        <button className="lh-btn ghost" onClick={onCancel}>Cancel</button>
        <button className="lh-btn primary" disabled={!name.trim()} onClick={submit}>
          <Icon name="add" />Create habit
        </button>
      </div>
    </div>
  );
}

function HabitEditor({ habit, onUpdate, onDelete, onClose }) {
  return (
    <div className="habit-editor">
      <div className="habit-editor-row">
        <label>Name</label>
        <input className="lh-input" value={habit.name} onChange={e => onUpdate({ name: e.target.value })} />
      </div>
      <div className="habit-editor-row">
        <label>Icon</label>
        <div className="habit-form-icons">
          {HABIT_ICONS.map(ic => (
            <button key={ic} className={`habit-pick-icon ${habit.icon === ic ? 'is-active' : ''}`} onClick={() => onUpdate({ icon: ic })}>
              <Icon name={ic} />
            </button>
          ))}
        </div>
      </div>
      <div className="habit-editor-row">
        <label>Color</label>
        <div className="habit-form-colors">
          {HABIT_COLORS.map(c => (
            <button key={c} className={`habit-pick-color ${habit.color === c ? 'is-active' : ''}`} style={{ background: c }} onClick={() => onUpdate({ color: c })} />
          ))}
        </div>
      </div>
      <div className="habit-editor-actions">
        <button className="lh-btn danger" onClick={onDelete}><Icon name="delete" />Delete habit</button>
        <button className="lh-btn ghost" onClick={onClose}><Icon name="close" />Close</button>
      </div>
    </div>
  );
}

window.HabitsTool = HabitsTool;
