// Tidvattnaren — färger, tider, väder, tips och statushjälpare.
// Plantor + zoner laddas från servern (se app.jsx).

const DAY = 86400000;
const HOUR = 3600000;

const HUES = {
  tomato:    { bg: '#F2C9A1', leaf: '#C0492A', accent: '#7AA850' },
  cucumber:  { bg: '#CFE3A8', leaf: '#3E7A2E', accent: '#A8C97F' },
  chili:     { bg: '#F0B8A0', leaf: '#B33B1F', accent: '#5C8A3A' },
  pea:       { bg: '#D8E8B5', leaf: '#5C8A3A', accent: '#9BBE6A' },
  herb:      { bg: '#C9DDA8', leaf: '#3F6627', accent: '#7AA850' },
  basil:     { bg: '#BCD49A', leaf: '#2F5A22', accent: '#5C8A3A' },
  root:      { bg: '#E8C8A0', leaf: '#8E5A2C', accent: '#C26B3A' },
  leafy:     { bg: '#CCDFA0', leaf: '#4F7727', accent: '#94B66E' },
  berry:     { bg: '#E8B7B0', leaf: '#A33B3B', accent: '#5C8A3A' },
  flower:    { bg: '#E5C2D9', leaf: '#9C4A82', accent: '#D27B3A' },
  mint:      { bg: '#B8DCC4', leaf: '#2D6A4A', accent: '#5C8A3A' },
  onion:     { bg: '#E8DCC0', leaf: '#7A8B3F', accent: '#C9A85B' },
};

// Fallback om SMHI inte svarar. Den live-prognosen kommer från /api/weather
// och fyller TV.WEATHER via setWeather() i app.jsx.
const WEATHER_FALLBACK = [
  { i: 0, dayLabel: 'Idag',    short: 'tor', date: '—', icon: 'CloudSun', tempH: 18, tempL: 10, rain: 0, pop: 10 },
  { i: 1, dayLabel: 'Imorgon', short: 'fre', date: '—', icon: 'Cloud',    tempH: 17, tempL: 10, rain: 0, pop: 20 },
  { i: 2, dayLabel: 'Lör',     short: 'lör', date: '—', icon: 'Cloud',    tempH: 17, tempL: 10, rain: 0, pop: 20 },
  { i: 3, dayLabel: 'Sön',     short: 'sön', date: '—', icon: 'Cloud',    tempH: 17, tempL: 10, rain: 0, pop: 20 },
  { i: 4, dayLabel: 'Mån',     short: 'mån', date: '—', icon: 'CloudSun', tempH: 18, tempL: 10, rain: 0, pop: 15 },
  { i: 5, dayLabel: 'Tis',     short: 'tis', date: '—', icon: 'Sun',      tempH: 19, tempL: 11, rain: 0, pop: 10 },
  { i: 6, dayLabel: 'Ons',     short: 'ons', date: '—', icon: 'Sun',      tempH: 19, tempL: 11, rain: 0, pop: 10 },
];
const WEATHER = [...WEATHER_FALLBACK];

const TIPS = [
  { title: 'Vattna gärna på morgonen', body: 'Då hinner bladen torka innan kvällen — det minskar risken för svampangrepp på dina tomater.' },
  { title: 'Mynta vill ha eget hem', body: 'Mynta sprider sig kraftigt med rotutskott. Ha den i egen kruka eller pallkrage så tar den inte över.' },
  { title: 'Djupare och mer sällan', body: 'En riktig genomvattning 2 ggr/vecka ger djupare rötter än lite vatten varje dag.' },
  { title: 'Knip toppskotten', body: 'På basilika och tomater: knip toppskotten regelbundet så blir plantan buskig istället för spretig.' },
  { title: 'Lavendel gillar det torrt', body: 'Lavendel mår bäst när jorden får torka helt mellan vattningarna. Övervattning är dess största fiende.' },
];

// Statushjälpare — ger "kind" som home/plants-vyerna grundar pills och sortering på.
function nextDue(plant) {
  if (plant.schedule.type === 'when_dry') return null;
  const now = Date.now();
  if (plant.snoozedUntil && plant.snoozedUntil > now) return plant.snoozedUntil;
  return plant.last + plant.schedule.days * DAY;
}

function statusOf(plant) {
  const now = Date.now();
  if (plant.schedule.type === 'when_dry') {
    const since = Math.floor((now - plant.last) / DAY);
    return { kind: 'manual', since };
  }
  const due = nextDue(plant);
  const diff = due - now;
  if (diff < -DAY) return { kind: 'overdue', days: Math.floor(-diff / DAY), due };
  if (diff < HOUR * 12) return { kind: 'today', due };
  return { kind: 'upcoming', days: Math.ceil(diff / DAY), due, hours: Math.round(diff / HOUR) };
}

function formatLast(ts) {
  const diff = Date.now() - ts;
  if (diff < HOUR) return 'för en stund sedan';
  if (diff < DAY) return `för ${Math.round(diff/HOUR)} h sedan`;
  const d = Math.floor(diff / DAY);
  if (d === 1) return 'igår';
  if (d < 7) return `för ${d} dagar sedan`;
  return `för ${Math.floor(d/7)} v sedan`;
}

const SVENSKA_DAGAR = ['Sön','Mån','Tis','Ons','Tor','Fre','Lör'];
const SVENSKA_MAN = ['jan','feb','mars','apr','maj','juni','juli','aug','sep','okt','nov','dec'];
function todayLabel() {
  const d = new Date();
  return `${SVENSKA_DAGAR[d.getDay()]} ${d.getDate()} ${SVENSKA_MAN[d.getMonth()]}`;
}

function greeting() {
  const h = new Date().getHours();
  if (h < 5)  return 'Sent på kvällen';
  if (h < 10) return 'God morgon';
  if (h < 12) return 'God förmiddag';
  if (h < 17) return 'Hej';
  if (h < 22) return 'God kväll';
  return 'God natt';
}

// API-klient — pratar med /api på samma origin. Fel-objekt får .status
// så App kan rendera LoginView vid 401 istället för generisk fel-screen.
async function apiGet(path) {
  const r = await fetch(path, { credentials: 'include' });
  if (!r.ok) {
    const err = new Error(`${path}: HTTP ${r.status}`);
    err.status = r.status;
    throw err;
  }
  return r.json();
}
async function apiPost(path, body, method = 'POST') {
  const r = await fetch(path, {
    method,
    credentials: 'include',
    headers: body ? { 'Content-Type': 'application/json' } : undefined,
    body: body ? JSON.stringify(body) : undefined,
  });
  if (!r.ok) {
    let msg = `HTTP ${r.status}`;
    try { const j = await r.json(); msg = j.error || msg; } catch {}
    const err = new Error(msg);
    err.status = r.status;
    throw err;
  }
  if (method === 'DELETE' || r.status === 204) return null;
  return r.json();
}

// Mutera arrayen in place så att alla komponenter som läser TV.WEATHER
// får färska siffror nästa render. App.jsx kallar denna efter /api/weather-fetch.
function setWeather(data) {
  if (!Array.isArray(data) || data.length === 0) return;
  WEATHER.splice(0, WEATHER.length, ...data);
}

window.TV = {
  DAY, HOUR, HUES, WEATHER, TIPS,
  nextDue, statusOf, formatLast, todayLabel, greeting,
  setWeather,
  apiGet, apiPost,
};
