// Tidvattnaren — main App.

const { useState, useEffect, useRef } = React;

const SETTINGS_KEY = 'tidvattnaren.settings.v1';

function loadSettings() {
  try {
    const raw = localStorage.getItem(SETTINGS_KEY);
    if (raw) return { theme: 'skog', density: 'regular', name: '', ...JSON.parse(raw) };
  } catch {}
  return { theme: 'skog', density: 'regular', name: '' };
}
function saveSettings(s) {
  try { localStorage.setItem(SETTINGS_KEY, JSON.stringify(s)); } catch {}
}

// Mobil bottom-nav (göms via CSS på desktop)
function BottomNav({ active, onPick }) {
  const items = [
    { id: 'home',   label: 'Hem',     Icon: Icon.Home },
    { id: 'plants', label: 'Växter',  Icon: Icon.Plants },
    { id: 'chat',   label: 'Chat',    Icon: Icon.Chat },
  ];
  return (
    <div className="bnav">
      {items.map(it => {
        const isActive = active === it.id;
        return (
          <button key={it.id} className={`bnav-btn ${isActive?'active':''}`} onClick={() => onPick(it.id)}>
            <it.Icon size={22} filled={isActive}/>
            <span>{it.label}</span>
          </button>
        );
      })}
    </div>
  );
}

// Desktop-sidebar (göms via CSS på mobil)
function DesktopSidebar({ tab, onTab, zones, plants, activeZone, onZone, onAddZone, onEditZone, onSettings, onAddPlant }) {
  return (
    <aside className="app-sidebar">
      <div className="sidebar-brand">
        <span style={{ color: 'var(--primary)' }}><Icon.Drop size={22}/></span>
        <span className="serif">Tidvattnaren</span>
      </div>

      <button className={`sidebar-item ${tab === 'home' ? 'active' : ''}`}
              onClick={() => onTab('home')}>
        <Icon.Home size={18} filled={tab === 'home'}/>
        <span>Hem</span>
      </button>
      <button className={`sidebar-item ${tab === 'plants' ? 'active' : ''}`}
              onClick={() => onTab('plants')}>
        <Icon.Plants size={18} filled={tab === 'plants'}/>
        <span>Växter</span>
        <span className="count">{plants.length}</span>
      </button>
      <button className={`sidebar-item ${tab === 'chat' ? 'active' : ''}`}
              onClick={() => onTab('chat')}>
        <Icon.Chat size={18} filled={tab === 'chat'}/>
        <span>Chat</span>
      </button>

      <div className="sidebar-section">Zoner</div>
      <button className={`sidebar-item ${tab === 'plants' && activeZone === 'all' ? 'active' : ''}`}
              onClick={() => { onTab('plants'); onZone('all'); }}>
        <Icon.Sprout size={16}/>
        <span>Alla</span>
        <span className="count">{plants.length}</span>
      </button>
      {zones.map(z => {
        const count = plants.filter(p => p.zone === z.id).length;
        const need = plants.filter(p => p.zone === z.id && ['today','overdue'].includes(TV.statusOf(p).kind)).length;
        const isActive = tab === 'plants' && activeZone === z.id;
        return (
          <button key={z.id}
                  className={`sidebar-item ${isActive ? 'active' : ''}`}
                  onClick={() => { onTab('plants'); onZone(z.id); }}>
            <span style={{ fontSize: 16, lineHeight: 1 }}>{z.emoji}</span>
            <span style={{ minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
              {z.name}
            </span>
            {need > 0 && !isActive && <span className="badge"/>}
            <span className="count">{count}</span>
          </button>
        );
      })}
      <button className="sidebar-add" onClick={onAddZone}>
        <Icon.Plus size={14}/> Ny zon
      </button>

      <div className="sidebar-spacer"/>

      <button className="sidebar-add" onClick={onAddPlant} style={{
        borderColor: 'var(--primary)', color: 'var(--primary-deep)',
        background: 'var(--primary-wash)',
      }}>
        <Icon.Plus size={14}/> Ny planta
      </button>
      <button className="sidebar-item" onClick={onSettings} style={{ marginTop: 6 }}>
        <Icon.Settings size={16}/>
        <span>Inställningar</span>
      </button>
    </aside>
  );
}

function DropBurst({ x, y }) {
  return (
    <div style={{ position: 'fixed', left: x - 7, top: y - 9, pointerEvents: 'none', zIndex: 9999 }}>
      {[0, 1, 2].map(i => (
        <svg key={i} className="drop-burst" width="14" height="18" viewBox="0 0 14 18" style={{
          left: (i - 1) * 14,
          animationDelay: `${i * 80}ms`,
        }}>
          <path d="M7 1 C 4 6, 2 9, 2 12 a 5 5 0 0 0 10 0 c 0 -3 -2 -6 -5 -11 z" fill="#5093B5"/>
        </svg>
      ))}
    </div>
  );
}

function SettingsSheet({ settings, onChange, onClose }) {
  return (
    <Sheet title="Inställningar" onClose={onClose}>
      <div className="form-group">
        <label className="form-label">Ditt namn</label>
        <input className="form-input" value={settings.name || ''}
               placeholder="t.ex. Thomas"
               onChange={e => onChange({ name: e.target.value })}/>
        <div className="form-help">Används i hälsningen på Hem-sidan.</div>
      </div>

      <div className="card" style={{ padding: '4px 14px' }}>
        <div className="settings-row">
          <span className="settings-label">Färgtema</span>
          <div className="settings-segment">
            {[
              { v: 'skog',     l: 'Skog' },
              { v: 'ang',      l: 'Äng' },
              { v: 'kust',     l: 'Kust' },
              { v: 'skymning', l: 'Skymning' },
            ].map(o => (
              <button key={o.v}
                      className={settings.theme === o.v ? 'active' : ''}
                      onClick={() => onChange({ theme: o.v })}>{o.l}</button>
            ))}
          </div>
        </div>
        <div className="settings-row">
          <span className="settings-label">Densitet</span>
          <div className="settings-segment">
            {[
              { v: 'compact', l: 'Kompakt' },
              { v: 'regular', l: 'Lagom' },
              { v: 'airy',    l: 'Luftig' },
            ].map(o => (
              <button key={o.v}
                      className={settings.density === o.v ? 'active' : ''}
                      onClick={() => onChange({ density: o.v })}>{o.l}</button>
            ))}
          </div>
        </div>
      </div>

      <p style={{ fontSize: 12.5, color: 'var(--ink-subtle)', marginTop: 14, textAlign: 'center' }}>
        Tidvattnaren — vattningstracker för din trädgård.
      </p>
    </Sheet>
  );
}

// Visas när API:t svarar 401 — användaren behöver logga in via OAuth.
function LoginView() {
  const [providers, setProviders] = useState({ google: false, microsoft: false });

  useEffect(() => {
    fetch('/auth/providers', { credentials: 'include' })
      .then(r => r.json())
      .then(setProviders)
      .catch(() => {});
  }, []);

  return (
    <div style={{
      minHeight: '100vh',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      padding: 24,
    }}>
      <div className="card" style={{
        padding: '32px 28px', maxWidth: 380, width: '100%',
        textAlign: 'center',
      }}>
        <div style={{
          width: 64, height: 64, borderRadius: '50%',
          background: 'var(--primary-wash)', color: 'var(--primary)',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          margin: '0 auto 18px',
        }}>
          <Icon.Drop size={32}/>
        </div>
        <h1 className="serif" style={{ fontSize: 28, marginBottom: 6 }}>Tidvattnaren</h1>
        <p style={{ fontSize: 14, color: 'var(--ink-muted)', marginBottom: 24, lineHeight: 1.5 }}>
          Logga in för att komma åt din trädgård.
        </p>

        {providers.google && (
          <a href="/auth/google" style={{
            display: 'block', width: '100%', height: 48,
            background: 'var(--ink)', color: 'var(--bg-card)',
            borderRadius: 12, textDecoration: 'none',
            fontFamily: 'Geist, system-ui, sans-serif', fontWeight: 600, fontSize: 14.5,
            display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
            marginBottom: 10,
          }}>
            <svg width="18" height="18" viewBox="0 0 24 24">
              <path fill="#fff" d="M21.6 12.23c0-.79-.07-1.54-.2-2.27H12v4.29h5.4c-.23 1.25-.94 2.3-2 3.02v2.5h3.24c1.9-1.74 2.96-4.32 2.96-7.54z"/>
              <path fill="#fff" d="M12 22c2.7 0 4.96-.9 6.6-2.43l-3.24-2.5c-.9.6-2.04.96-3.36.96-2.6 0-4.8-1.74-5.58-4.1H3.06v2.58A10 10 0 0012 22z" opacity="0.82"/>
              <path fill="#fff" d="M6.42 13.93a6 6 0 010-3.86V7.49H3.06a10 10 0 000 9.02l3.36-2.58z" opacity="0.64"/>
              <path fill="#fff" d="M12 5.96c1.46 0 2.78.5 3.82 1.5l2.86-2.87A10 10 0 003.06 7.49l3.36 2.58C7.2 7.7 9.4 5.96 12 5.96z" opacity="0.5"/>
            </svg>
            Logga in med Google
          </a>
        )}

        {providers.microsoft && (
          <a href="/auth/microsoft" style={{
            display: 'flex', width: '100%', height: 48,
            background: 'var(--bg-card)', color: 'var(--ink)',
            border: '1px solid var(--line-strong)',
            borderRadius: 12, textDecoration: 'none',
            fontFamily: 'Geist, system-ui, sans-serif', fontWeight: 600, fontSize: 14.5,
            alignItems: 'center', justifyContent: 'center', gap: 10,
          }}>
            <svg width="18" height="18" viewBox="0 0 24 24">
              <rect x="2" y="2" width="9" height="9" fill="#F25022"/>
              <rect x="13" y="2" width="9" height="9" fill="#7FBA00"/>
              <rect x="2" y="13" width="9" height="9" fill="#00A4EF"/>
              <rect x="13" y="13" width="9" height="9" fill="#FFB900"/>
            </svg>
            Logga in med Microsoft
          </a>
        )}

        {!providers.google && !providers.microsoft && (
          <div style={{ fontSize: 13, color: 'var(--ink-subtle)' }}>
            Ingen inloggningsmetod är konfigurerad på servern.
          </div>
        )}
      </div>
    </div>
  );
}

function App() {
  const [settings, setSettings] = useState(loadSettings);
  const [tab, setTab] = useState('home');
  const [activeZone, setActiveZone] = useState('all');
  const [zones, setZones] = useState([]);
  const [plants, setPlants] = useState([]);
  const [history, setHistory] = useState([]);
  const [openPlantId, setOpenPlantId] = useState(null);
  const [editingPlant, setEditingPlant] = useState(null);  // 'new' | plant-object
  const [editingZone, setEditingZone] = useState(null);     // 'new' | zone-object
  const [chatScopePlant, setChatScopePlant] = useState(null);  // null = global, plant-object = per planta
  const [burst, setBurst] = useState(null);
  const [busyId, setBusyId] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [needsLogin, setNeedsLogin] = useState(false);
  const [showSettings, setShowSettings] = useState(false);

  useEffect(() => {
    document.documentElement.setAttribute('data-theme', settings.theme);
    document.documentElement.setAttribute('data-density', settings.density);
    saveSettings(settings);
  }, [settings.theme, settings.density]);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const state = await TV.apiGet('/api/state');
        if (cancelled) return;
        setZones(state.zones);
        setPlants(state.plants);
        setHistory(state.history);
      } catch (e) {
        if (cancelled) return;
        if (e.status === 401) setNeedsLogin(true);
        else setError(e.message);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, []);

  // Väder — laddas i bakgrunden, faller tillbaka till mockdata om SMHI inte svarar.
  // Bumpar en counter så komponenter som läser TV.WEATHER renderar om när datan kommer.
  const [weatherTick, setWeatherTick] = useState(0);
  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const w = await TV.apiGet('/api/weather');
        if (cancelled || !Array.isArray(w)) return;
        TV.setWeather(w);
        setWeatherTick(n => n + 1);
      } catch (e) {
        console.warn('Kunde inte ladda väder, använder fallback:', e.message);
      }
    })();
    return () => { cancelled = true; };
  }, []);

  const refreshHistory = async () => {
    try {
      const h = await TV.apiGet('/api/history?limit=200');
      setHistory(h);
    } catch {}
  };

  const water = async (id, evt) => {
    if (busyId) return;
    setBusyId(id);
    if (evt && evt.clientX) {
      setBurst({ x: evt.clientX, y: evt.clientY, key: Date.now() });
      setTimeout(() => setBurst(null), 950);
    }
    const now = Date.now();
    setPlants(prev => prev.map(p => p.id === id ? { ...p, last: now, snoozedUntil: null } : p));
    try {
      const updated = await TV.apiPost(`/api/plants/${id}/water`);
      setPlants(prev => prev.map(p => p.id === id ? updated : p));
      refreshHistory();
    } catch (e) {
      setError(e.message);
    } finally {
      setBusyId(null);
    }
  };

  const snooze = async (id) => {
    try {
      const updated = await TV.apiPost(`/api/plants/${id}/snooze`);
      setPlants(prev => prev.map(p => p.id === id ? updated : p));
    } catch (e) {
      setError(e.message);
    }
  };

  // Edit-callbacks
  const onPlantSaved = (updated) => {
    setPlants(prev => {
      const i = prev.findIndex(p => p.id === updated.id);
      if (i === -1) return [...prev, updated];
      const next = [...prev];
      next[i] = updated;
      return next;
    });
    setEditingPlant(null);
  };
  const onPlantDeleted = (id) => {
    setPlants(prev => prev.filter(p => p.id !== id));
    setEditingPlant(null);
    setOpenPlantId(null);
  };
  const onZoneSaved = (updated) => {
    setZones(prev => {
      const i = prev.findIndex(z => z.id === updated.id);
      if (i === -1) return [...prev, updated];
      const next = [...prev];
      next[i] = updated;
      return next;
    });
    setEditingZone(null);
  };
  const onZoneDeleted = (id) => {
    setZones(prev => prev.filter(z => z.id !== id));
    if (activeZone === id) setActiveZone('all');
    setEditingZone(null);
  };

  const openPlant = openPlantId ? plants.find(p => p.id === openPlantId) : null;

  if (loading) {
    return <div className="app-shell"><div className="loader">Laddar trädgården…</div></div>;
  }
  if (needsLogin) return <LoginView/>;
  if (error && !plants.length) {
    return (
      <div className="app-shell">
        <div className="loader" style={{ flexDirection: 'column', textAlign: 'center', padding: 24 }}>
          <div className="serif" style={{ fontSize: 22, color: 'var(--warn)', marginBottom: 8 }}>Något gick fel</div>
          <div style={{ fontSize: 14 }}>{error}</div>
        </div>
      </div>
    );
  }

  // Default: när "Växter" öppnas första gången på mobil, fall tillbaka till första zonen.
  // På desktop bra att default-visa "Alla".
  const effectiveZone = activeZone || (zones[0]?.id ?? 'all');

  return (
    <div className="app-shell">
      <DesktopSidebar
        tab={tab} onTab={(t) => { if (t === 'chat') setChatScopePlant(null); setTab(t); }}
        zones={zones} plants={plants}
        activeZone={effectiveZone} onZone={setActiveZone}
        onAddZone={() => setEditingZone('new')}
        onEditZone={(id) => setEditingZone(zones.find(z => z.id === id))}
        onAddPlant={() => setEditingPlant('new')}
        onSettings={() => setShowSettings(true)}
      />

      <div className="app-main">
        {/* Mobil-topbar (göms på desktop via CSS) */}
        <div className="app-topbar-mobile" style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '14px 18px 6px', flexShrink: 0,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <span style={{ color: 'var(--primary)' }}><Icon.Drop size={20}/></span>
            <span className="serif" style={{ fontSize: 19, letterSpacing: '-0.01em' }}>Tidvattnaren</span>
          </div>
          <button onClick={() => setShowSettings(true)} aria-label="Inställningar" style={{
            appearance: 'none', border: 0, cursor: 'pointer',
            width: 36, height: 36, borderRadius: '50%',
            background: 'var(--bg-card)', color: 'var(--ink-muted)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            boxShadow: 'var(--shadow-card)',
          }}>
            <Icon.Settings size={16}/>
          </button>
        </div>

        <div style={{ flex: 1, overflowY: 'auto', overflowX: 'hidden', position: 'relative' }}>
          {tab === 'home' && (
            <div className="home-wrap">
              <HomeScreen
                plants={plants} zones={zones} history={history}
                onWater={water} onOpen={(id) => setOpenPlantId(id)}
                onGoPlants={() => { setTab('plants'); setActiveZone('all'); }}
                busyId={busyId} userName={settings.name}
              />
            </div>
          )}
          {tab === 'plants' && (
            <PlantsScreen
              plants={plants} zones={zones} activeZone={effectiveZone} onZone={setActiveZone}
              onWater={water} onOpen={(id) => setOpenPlantId(id)} onSnooze={snooze}
              onAddPlant={() => setEditingPlant('new')}
              onEditZone={(id) => setEditingZone(zones.find(z => z.id === id))}
              busyId={busyId}
            />
          )}
          {tab === 'chat' && (
            <ChatScreen
              scopeType={chatScopePlant ? 'plant' : 'global'}
              scopePlant={chatScopePlant}
              onClearScope={() => setChatScopePlant(null)}
            />
          )}
        </div>

        <div style={{ flexShrink: 0, paddingBottom: 'env(safe-area-inset-bottom, 0px)' }}>
          <BottomNav active={tab} onPick={(t) => { if (t === 'chat') setChatScopePlant(null); setTab(t); }}/>
        </div>
      </div>

      {openPlant && (
        <PlantSheet plant={openPlant} zones={zones} history={history}
                    onClose={() => setOpenPlantId(null)}
                    onWater={water} onSnooze={snooze}
                    onEdit={(id) => setEditingPlant(plants.find(p => p.id === id))}
                    onChat={(plant) => { setChatScopePlant(plant); setTab('chat'); }}
                    busy={busyId === openPlant.id}/>
      )}

      {editingPlant && (
        <PlantForm
          initialPlant={editingPlant === 'new' ? null : editingPlant}
          zones={zones}
          onSave={onPlantSaved}
          onDelete={onPlantDeleted}
          onClose={() => setEditingPlant(null)}/>
      )}

      {editingZone && (
        <ZoneForm
          initialZone={editingZone === 'new' ? null : editingZone}
          plants={plants}
          onSave={onZoneSaved}
          onDelete={onZoneDeleted}
          onClose={() => setEditingZone(null)}/>
      )}

      {showSettings && (
        <SettingsSheet
          settings={settings}
          onChange={(patch) => setSettings(s => ({ ...s, ...patch }))}
          onClose={() => setShowSettings(false)}
        />
      )}

      {burst && <DropBurst x={burst.x} y={burst.y} key={burst.key}/>}
    </div>
  );
}

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