/* global React */
// Data layer — loads /data.json with mock fallback so the design renders
// in any environment. Exports `useHyttenData` returning a normalized shape.

const { useState, useEffect, useMemo } = React;

// ---- Mock fixtures (used when /data.json is unreachable) ------------------
const MOCK = {
  config: {
    occupancySource: 'unifi',
    occupancyThreshold: 1,
    videoEmbedUrl: '',
    videoPosterUrl: '',
  },
  occupancy: {
    dates: (() => {
      const out = {};
      const start = new Date();
      start.setDate(start.getDate() - 60);
      for (let i = 0; i < 60; i++) {
        const d = new Date(start);
        d.setDate(start.getDate() + i);
        const k = d.toISOString().slice(0, 10);
        const occ = [3, 4, 5, 6, 12, 13, 19, 20, 21, 26, 27, 33, 34, 40, 41, 42, 47, 48, 54, 55, 56].includes(i);
        out[k] = {
          occupied: occ,
          score: occ ? 65 + Math.round(Math.random() * 25) : Math.round(Math.random() * 35),
          temperature: 14 + Math.round(Math.random() * 10),
          scoreBreakdown: {
            doorActivity: occ ? 80 : 20,
            temp1: occ ? 70 : 25,
            temp2: occ ? 65 : 30,
            bandwidth: occ ? 75 : 10,
          },
        };
      }
      return out;
    })(),
    currentClientCount: 5,
    lastFetch: new Date().toISOString(),
    occupancyThreshold: 1,
  },
  planned: {
    entries: (() => {
      const today = new Date();
      const mk = (offsetStart, days, label) => {
        const from = new Date(today);
        from.setDate(today.getDate() + offsetStart);
        const to = new Date(from);
        to.setDate(from.getDate() + days - 1);
        return { from: from.toISOString().slice(0, 10), to: to.toISOString().slice(0, 10), label };
      };
      return [mk(8, 3, 'Påske med familien'), mk(22, 4, 'Pinsehelg'), mk(40, 7, 'Sommeruke')];
    })(),
  },
  weatherOutdoor: {
    configured: true,
    temperature: 7,
    temperatureUnit: '°C',
    symbolCode: 'partlycloudy_day',
    windSpeed: 4.2,
    windDirection: 'NV',
  },
  climateIndoor: {
    configured: true,
    rooms: [
      { label: 'Hovedstue', temperature: 18.4, humidity: 42, unit: '°C' },
      { label: 'Sovebu',    temperature: 14.2, humidity: 48, unit: '°C' },
      { label: 'Badehus',   temperature: 11.8, humidity: 62, unit: '°C' },
      { label: 'Toalett',   temperature: 13.6, humidity: 55, unit: '°C' },
    ],
  },
  weatherSummary: {
    configured: true,
    summary: 'Skyet morgen, oppholdsvær gjennom dagen. Lett bris fra nordvest. Kvelden klarner opp og temperaturen synker mot null.',
  },
  weatherForecast: (() => {
    const codes = ['partlycloudy_day', 'cloudy', 'lightrain', 'rain', 'partlycloudy_day', 'fair_day', 'clearsky_day'];
    const out = [];
    for (let i = 0; i < 7; i++) {
      const d = new Date();
      d.setDate(d.getDate() + i);
      out.push({
        date: d.toISOString().slice(0, 10),
        symbolCode: codes[i],
        tempMax: [8, 7, 5, 4, 6, 9, 11][i],
        tempMin: [1, 0, -1, -2, -1, 2, 4][i],
        precip: [0.4, 1.2, 4.5, 6.8, 0.8, 0, 0][i],
      });
    }
    return out;
  })(),
};

// ---- Sun/moon — calculated client-side for cabin coords ------------------
const DEFAULT_LAT = 59.55;
const DEFAULT_LON = 8.4;

function sunTimes(date, lat = DEFAULT_LAT, lon = DEFAULT_LON) {
  const rad = Math.PI / 180;
  const dayOfYear = Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 86400000);
  const decl = 23.44 * Math.sin(rad * (360 / 365) * (dayOfYear - 81));
  const cosH = (Math.sin(-0.83 * rad) - Math.sin(lat * rad) * Math.sin(decl * rad))
             / (Math.cos(lat * rad) * Math.cos(decl * rad));
  if (cosH > 1)  return { sunrise: null, sunset: null, daylightMin: 0, polar: 'night' };
  if (cosH < -1) return { sunrise: null, sunset: null, daylightMin: 1440, polar: 'day' };
  const H = Math.acos(cosH) / rad;
  const solarNoon = 12 - lon / 15;
  const sunriseUtc = solarNoon - H / 15;
  const sunsetUtc  = solarNoon + H / 15;
  const offsetH = -date.getTimezoneOffset() / 60;
  const toClock = (h) => {
    let local = (h + offsetH + 24) % 24;
    const hh = Math.floor(local);
    const mm = Math.round((local - hh) * 60);
    return `${String(hh).padStart(2, '0')}:${String(mm).padStart(2, '0')}`;
  };
  return {
    sunrise: toClock(sunriseUtc),
    sunset: toClock(sunsetUtc),
    daylightMin: Math.round((sunsetUtc - sunriseUtc) * 60),
    polar: null,
  };
}

window.sunTimes = sunTimes;

function useHyttenData() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    let cancelled = false;
    fetch('/data.json')
      .then((r) => (r.ok ? r.json() : null))
      .then((d) => {
        if (cancelled) return;
        if (d && d.occupancy) {
          setData({
            ...MOCK,
            ...d,
            weatherForecast: (d.weatherForecast && d.weatherForecast.length > 0)
              ? d.weatherForecast
              : MOCK.weatherForecast,
          });
        } else {
          setData(MOCK);
        }
      })
      .catch(() => { if (!cancelled) setData(MOCK); });
    return () => { cancelled = true; };
  }, []);

  const plannedMap = useMemo(() => {
    if (!data?.planned?.entries) return new Map();
    const m = new Map();
    for (const e of data.planned.entries) {
      const label = e.label || null;
      if (e.date) m.set(e.date, { label, from: e.date, to: e.date });
      else if (e.from && e.to) {
        const end = new Date(e.to);
        for (let d = new Date(e.from); d <= end; d.setDate(d.getDate() + 1)) {
          m.set(d.toISOString().slice(0, 10), { label, from: e.from, to: e.to });
        }
      }
    }
    return m;
  }, [data]);

  return { data, error, plannedMap };
}

window.useHyttenData = useHyttenData;
window.HYTTEN_MOCK = MOCK;
