// Components for IT Service Kalmar — sysadmin command center aesthetic
const { useState, useEffect, useRef, useMemo } = React;

// ─── Live clock ────────────────────────────────────────────────────────────
function useNow(intervalMs = 1000) {
  const [now, setNow] = useState(() => new Date());
  useEffect(() => {
    const id = setInterval(() => setNow(new Date()), intervalMs);
    return () => clearInterval(id);
  }, [intervalMs]);
  return now;
}

function fmtTime(d) {
  const pad = (n) => String(n).padStart(2, "0");
  return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
}
function fmtDate(d) {
  const pad = (n) => String(n).padStart(2, "0");
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
}

// ─── Status Bar ────────────────────────────────────────────────────────────
function StatusBar({ accent }) {
  const now = useNow();
  const [uptime, setUptime] = useState(0);
  useEffect(() => {
    const start = Date.now();
    const id = setInterval(() => setUptime(Math.floor((Date.now() - start) / 1000)), 1000);
    return () => clearInterval(id);
  }, []);

  const items = [
    { k: "SYS", v: "itsk.local", live: true },
    { k: "TZ", v: "Europe/Kalmar" },
    { k: "DATE", v: fmtDate(now) },
    { k: "TIME", v: fmtTime(now) },
    { k: "UPTIME", v: `${String(Math.floor(uptime / 60)).padStart(2,"0")}:${String(uptime % 60).padStart(2,"0")}` },
    { k: "BUILD", v: "v40.6.2" },
    { k: "STATUS", v: "OPERATIONAL", ok: true },
  ];

  return (
    <div className="statusbar">
      <div className="statusbar-inner">
        {items.map((it, i) => (
          <span key={i} className="sb-item">
            <span className="sb-k">{it.k}</span>
            <span className="sb-sep">:</span>
            <span className={`sb-v ${it.ok ? "ok" : ""}`} style={it.ok ? { color: accent } : null}>
              {it.live && <span className="sb-dot" style={{ background: accent }} />}
              {it.v}
            </span>
          </span>
        ))}
      </div>
    </div>
  );
}

// ─── Boot sequence ─────────────────────────────────────────────────────────
const BOOT_LINES = [
  ["[  OK  ]", "BIOS POST complete — 40 years of muscle memory loaded"],
  ["[  OK  ]", "Mounting /dev/expertise … 40y, 312k tickets, 0 panics"],
  ["[  OK  ]", "Loading kernel module: pc.ko"],
  ["[  OK  ]", "Loading kernel module: mac.ko"],
  ["[  OK  ]", "Loading kernel module: server.ko"],
  ["[  OK  ]", "Loading kernel module: personal_service.ko"],
  ["[ INFO ]", "Coffee daemon process shutdown — removing daemon"],
  ["[ INFO ]", "ÖL daemon up (på flaska, iskall)"],
  ["[  OK  ]", "Network: kalmar-fiber up @ 10 Gbps · ping 0.3 ms"],
  ["[  OK  ]", "Diagnostics ready · drop your machine off any time"],
];

function BootLog({ accent }) {
  const [shown, setShown] = useState(0);
  useEffect(() => {
    if (shown >= BOOT_LINES.length) return;
    const id = setTimeout(() => setShown((n) => n + 1), shown === 0 ? 200 : 180);
    return () => clearTimeout(id);
  }, [shown]);
  return (
    <pre className="boot-log">
      {BOOT_LINES.slice(0, shown).map((l, i) => (
        <div key={i} className="boot-line">
          <span className="boot-tag" style={{ color: l[0].includes("OK") ? accent : "var(--fg-dim)" }}>{l[0]}</span>
          <span className="boot-msg">{l[1]}</span>
        </div>
      ))}
      {shown < BOOT_LINES.length && <span className="caret" style={{ background: accent }} />}
    </pre>
  );
}

// ─── Sparkline (procedural sine + noise) ───────────────────────────────────
function Spark({ w = 240, h = 36, seed = 1, accent = "#5eead4" }) {
  const [t, setT] = useState(0);
  useEffect(() => {
    let raf;
    const tick = () => { setT((x) => x + 1); raf = requestAnimationFrame(tick); };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);
  const n = 60;
  const pts = [];
  for (let i = 0; i < n; i++) {
    const x = (i / (n - 1)) * w;
    const phase = t * 0.04 + seed * 13;
    const y = h / 2
      + Math.sin(i * 0.3 + phase) * (h * 0.22)
      + Math.sin(i * 0.11 + phase * 1.7) * (h * 0.12)
      + Math.sin(i * 0.55 + phase * 0.5 + seed) * (h * 0.08);
    pts.push([x, y]);
  }
  const d = pts.map((p, i) => `${i ? "L" : "M"}${p[0].toFixed(1)},${p[1].toFixed(1)}`).join(" ");
  const last = pts[pts.length - 1];
  return (
    <svg viewBox={`0 0 ${w} ${h}`} className="spark" preserveAspectRatio="none">
      <defs>
        <linearGradient id={`sg${seed}`} x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor={accent} stopOpacity="0.3" />
          <stop offset="100%" stopColor={accent} stopOpacity="0" />
        </linearGradient>
      </defs>
      <path d={`${d} L ${w},${h} L 0,${h} Z`} fill={`url(#sg${seed})`} />
      <path d={d} stroke={accent} strokeWidth="1.25" fill="none" />
      <circle cx={last[0]} cy={last[1]} r="2" fill={accent} />
    </svg>
  );
}

// ─── Metric tile ───────────────────────────────────────────────────────────
function Metric({ label, value, unit, sub, seed, accent }) {
  return (
    <div className="metric">
      <div className="metric-head">
        <span className="metric-label">{label}</span>
        <span className="metric-dot" style={{ background: accent }} />
      </div>
      <div className="metric-value">
        <span className="metric-num">{value}</span>
        {unit && <span className="metric-unit">{unit}</span>}
      </div>
      <Spark seed={seed} accent={accent} />
      <div className="metric-sub">{sub}</div>
    </div>
  );
}

// ─── Service card with ASCII art per service ───────────────────────────────
const SERVICES = [
  {
    id: "pc",
    code: "01",
    title: "PC & Windows",
    tag: "x86_64 · Intel/AMD",
    blurb: "Felsökning, uppgraderingar, ominstallation, datarekonstruktion. Allt från knäpp BSOD till en gammal stationär som ska få nytt liv.",
    bullets: ["Hårdvarudiagnostik", "Win 10/11 ominstall", "Datarekonstruktion (HDD/SSD/NVMe)", "RAM/SSD/GPU-uppgradering", "Virusrensning utan placebo"],
    art: [
      "┌────────────────────┐",
      "│  ░▒▓ POST: PASS ▓▒░│",
      "│  CPU  ████████ 87% │",
      "│  MEM  ██████░░ 71% │",
      "│  SSD  ███████░ 92% │",
      "└────────────────────┘",
    ],
  },
  {
    id: "mac",
    code: "02",
    title: "Mac & Apple",
    tag: "Apple Silicon · Intel",
    blurb: "M-serien till gamla iMac G5. Logic boards, batteribyten, recovery, migration assistant och allt däremellan.",
    bullets: ["macOS-installation från scratch", "Apple Silicon-migration", "Tangentbord & batteri", "Time Machine-recovery", "iCloud / Apple ID-knutar"],
    art: [
      "  ╭───────────────╮",
      "  │   ◉           │",
      "  │  macOS 15.4   │",
      "  │   ▌           │",
      "  ╰──┬─────────┬──╯",
      "     └─────────┘",
    ],
  },
  {
    id: "srv",
    code: "03",
    title: "Servrar & Nätverk",
    tag: "Linux · Windows Server · VMware",
    blurb: "Active Directory som inte beter sig, RAID som klagar, brandväggar som blockerar fel saker. Fysiskt eller i molnet.",
    bullets: ["AD / GPO / Exchange", "RAID-rebuild & backup-strategi", "VLAN, VPN, brandvägg", "Linux server-administration", "Övervakning & larm dygnet runt"],
    art: [
      "║▓▓▓║▓▓▓║▓▓▓║   srv-01",
      "║▓▓▓║▓▓▓║▓▓▓║   srv-02",
      "║▓▓▓║▒░░║▓▓▓║   srv-03 ⚠",
      "║▓▓▓║▓▓▓║▓▓▓║   srv-04",
      " └───┴───┴───┘  RAID6 OK",
    ],
  },
  {
    id: "ps",
    code: "04",
    title: "Personlig Service",
    tag: "Mänsklig · på riktigt",
    blurb: "Du pratar med samma person varje gång. Inget callcenter, inga manus. Hembesök i Kalmar med omnejd om du vill.",
    bullets: ["Samma tekniker varje gång", "Hembesök eller fjärrhjälp", "Pris innan vi börjar — inte efter", "Förklaring på svenska, inte buzzword", "Inget under 20 min faktureras"],
    art: [
      "  ☕  ──→   🛠   ──→   ✓",
      "  hej     fix it    klart",
      "       ──── 40 år ────",
    ],
  },
];

function ServiceCard({ s, accent, idx }) {
  const [open, setOpen] = useState(idx === 0);
  return (
    <article className={`svc ${open ? "open" : ""}`} onClick={() => setOpen((o) => !o)}>
      <header className="svc-head">
        <span className="svc-code" style={{ color: accent }}>SVC.{s.code}</span>
        <span className="svc-tag">{s.tag}</span>
        <span className="svc-toggle">{open ? "[ − ]" : "[ + ]"}</span>
      </header>
      <h3 className="svc-title">{s.title}</h3>
      <p className="svc-blurb">{s.blurb}</p>
      {open && (
        <div className="svc-body">
          <ul className="svc-list">
            {s.bullets.map((b, i) => (
              <li key={i}>
                <span className="svc-bullet" style={{ color: accent }}>▸</span> {b}
              </li>
            ))}
          </ul>
          <pre className="svc-art" style={{ color: accent }}>{s.art.join("\n")}</pre>
        </div>
      )}
    </article>
  );
}

// ─── Timeline of 40 years ──────────────────────────────────────────────────
const TIMELINE = [
  { y: "1986", t: "Första lödkolven", d: "C64 + lödstation. En generation lärde sig programmera; jag lärde mig laga." },
  { y: "1992", t: "PC-bygget", d: "486-eran. Skruvade ihop maskiner åt halva grannskapet i Kalmar." },
  { y: "1998", t: "Nätverk på riktigt", d: "Novell NetWare, sedan NT4. Första företagsservern stod i ett städskåp." },
  { y: "2004", t: "Mac in i butiken", d: "Power Mac G5 ändrade mycket. Sedan dess servar jag bägge världar." },
  { y: "2011", t: "Virtualisering & moln", d: "VMware, Hyper-V, sedan AWS/Azure. Servrar slutade vara fysiska saker att sparka på." },
  { y: "2018", t: "Datarekonstruktion", d: "Antistatisk matta för HDD/SSD-recovery. Räddade allt från bröllopsbilder till bokföring." },
  { y: "2024", t: "Apple Silicon-eran", d: "M-serien betyder att en MacBook nu kan ersätta ett serverstativ från 2010." },
  { y: "2026", t: "Idag", d: "Samma person, samma butik, samma princip: säg sanningen och fixa det." },
];

function Timeline({ accent }) {
  return (
    <div className="timeline">
      <div className="tl-axis">
        <span className="tl-axis-line" style={{ background: `linear-gradient(180deg, ${accent}, transparent)` }} />
      </div>
      <ol className="tl-items">
        {TIMELINE.map((it, i) => (
          <li key={i} className="tl-item">
            <span className="tl-year" style={{ color: accent }}>{it.y}</span>
            <span className="tl-node" style={{ borderColor: accent }}>
              <span style={{ background: accent }} />
            </span>
            <div className="tl-body">
              <h4>{it.t}</h4>
              <p>{it.d}</p>
            </div>
          </li>
        ))}
      </ol>
    </div>
  );
}

// ─── Diagnostic command line (interactive) ─────────────────────────────────
const COMMANDS = {
  help: () => [
    "Tillgängliga kommandon:",
    "  status      visar systemstatus",
    "  services    listar tjänster",
    "  contact     visar kontaktuppgifter",
    "  pris        visar prislista",
    "  whoami      vem är teknikern",
    "  uptime      hur länge butiken funnits",
    "  clear       rensar terminal",
  ],
  status: () => [
    "● butik         OPEN   mån–fre 09:00–17:00",
    "● fjärrsupport  ONLINE 24/7 vid avtal",
    "● kö            2 ärenden · est. 1 dag",
    "● coffee.daemon RUNNING (espresso)",
  ],
  services: () => SERVICES.map(s => `  ${s.code}  ${s.title.padEnd(22)} ${s.tag}`),
  contact: () => [
    "  tel    073-726 51 63",
    "  mail   itservice-kalmar@gmx.net",
    "  adr    Magistratsgatan 6 A, Kalmar",
    "  hours  09:00–17:00 vardagar",
  ],
  pris: () => [
    "  diagnos              0 kr  (alltid gratis)",
    "  arbete               895 kr/h ex moms",
    "  hembesök Kalmar      +295 kr",
    "  fjärrsupport         pris per ärende",
    "  datarekonstruktion   offert",
  ],
  whoami: () => [
    "  user    carl tunell",
    "  groups  pc, mac, server, människa",
    "  since   1986",
    "  shell   /bin/svenska",
  ],
  uptime: () => [
    `  ${new Date().toLocaleString("sv-SE")} up 40 years, 0 panics, load avg: 0.4 0.3 0.2`,
  ],
  clear: () => null,
};

function Terminal({ accent }) {
  const [history, setHistory] = useState([
    { kind: "out", lines: ["Diagnostic shell v40.6 — typ 'help' för kommandon."] },
  ]);
  const [val, setVal] = useState("");
  const inputRef = useRef(null);
  const bodyRef = useRef(null);

  useEffect(() => {
    if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
  }, [history]);

  const run = (raw) => {
    const cmd = raw.trim().toLowerCase();
    if (!cmd) return;
    const fn = COMMANDS[cmd];
    let next = [...history, { kind: "in", lines: [raw] }];
    if (cmd === "clear") {
      setHistory([]);
      return;
    }
    if (fn) next.push({ kind: "out", lines: fn() });
    else next.push({ kind: "err", lines: [`'${cmd}': okänt kommando. Prova 'help'.`] });
    setHistory(next);
  };

  return (
    <div className="term" onClick={() => inputRef.current?.focus()}>
      <header className="term-head">
        <span className="term-dot" />
        <span className="term-dot" style={{ background: "#facc15" }} />
        <span className="term-dot" style={{ background: accent }} />
        <span className="term-title">— diagnostic@itsk:~ —</span>
      </header>
      <div className="term-body" ref={bodyRef}>
        {history.map((h, i) => (
          <div key={i} className={`term-row term-${h.kind}`}>
            {h.lines.map((l, j) => (
              <div key={j}>
                {h.kind === "in" && <span className="term-prompt" style={{ color: accent }}>$ </span>}
                {l}
              </div>
            ))}
          </div>
        ))}
        <form
          className="term-row term-input"
          onSubmit={(e) => { e.preventDefault(); run(val); setVal(""); }}
        >
          <span className="term-prompt" style={{ color: accent }}>$ </span>
          <input
            ref={inputRef}
            value={val}
            onChange={(e) => setVal(e.target.value)}
            spellCheck={false}
            autoComplete="off"
            autoFocus
          />
          <span className="caret" style={{ background: accent }} />
        </form>
      </div>
      <footer className="term-foot">
        <span>tips:</span>
        {["help", "status", "pris", "contact", "whoami"].map((c) => (
          <button key={c} className="term-chip" onClick={() => run(c)} style={{ borderColor: accent, color: accent }}>
            {c}
          </button>
        ))}
      </footer>
    </div>
  );
}

// ─── Diagnostic readout (fake live system) ─────────────────────────────────
function DiagnosticPanel({ accent }) {
  const [tick, setTick] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setTick((t) => t + 1), 1500);
    return () => clearInterval(id);
  }, []);
  const rand = (seed, max = 100) => {
    const s = Math.sin(seed * 9999 + tick * 1.3) * 0.5 + 0.5;
    return Math.floor(s * max);
  };
  const rows = [
    { name: "ws-anders.local",     os: "Win 11 24H2",   cpu: 12 + rand(1, 8), mem: 41 + rand(2, 12), st: "ok" },
    { name: "imac-redaktion",      os: "macOS 15.4",    cpu: 22 + rand(3, 10), mem: 58 + rand(4, 9), st: "ok" },
    { name: "srv-fileshare",       os: "Win Srv 2022",  cpu: 8 + rand(5, 5),  mem: 71 + rand(6, 6), st: "ok" },
    { name: "srv-backup-01",       os: "Debian 12",     cpu: 67 + rand(7, 20), mem: 83 + rand(8, 8), st: "warn" },
    { name: "mbp-konsult-04",      os: "macOS 15.3",    cpu: 5 + rand(9, 4),  mem: 33 + rand(10, 6), st: "ok" },
    { name: "ws-ekonomi",          os: "Win 10 22H2",   cpu: 14 + rand(11, 7), mem: 49 + rand(12, 8), st: "ok" },
    { name: "fw-edge",             os: "OPNsense 24",   cpu: 3 + rand(13, 2),  mem: 22 + rand(14, 4), st: "ok" },
  ];
  return (
    <div className="diag">
      <header className="diag-head">
        <span className="diag-title">live · övervakning</span>
        <span className="diag-meta"><span className="sb-dot" style={{ background: accent }} /> {rows.length} noder · uppdatering 1.5s</span>
      </header>
      <div className="diag-grid diag-grid-h">
        <span>NOD</span><span>OS</span><span>CPU</span><span>MEM</span><span>STATUS</span>
      </div>
      {rows.map((r, i) => (
        <div key={i} className="diag-grid diag-row">
          <span className="diag-name">{r.name}</span>
          <span className="diag-os">{r.os}</span>
          <span className="diag-bar">
            <span className="diag-bar-fill" style={{ width: `${r.cpu}%`, background: r.cpu > 80 ? "#fb923c" : accent }} />
            <span className="diag-bar-num">{r.cpu}%</span>
          </span>
          <span className="diag-bar">
            <span className="diag-bar-fill" style={{ width: `${r.mem}%`, background: r.mem > 80 ? "#fb923c" : accent }} />
            <span className="diag-bar-num">{r.mem}%</span>
          </span>
          <span className={`diag-st diag-st-${r.st}`} style={r.st === "ok" ? { color: accent } : null}>
            {r.st === "ok" ? "● OK" : "▲ WARN"}
          </span>
        </div>
      ))}
    </div>
  );
}

// ─── Skill matrix (radar-ish bar chart) ────────────────────────────────────
const SKILLS = [
  { k: "Windows / PC",            v: 99 },
  { k: "macOS / Apple Silicon",   v: 96 },
  { k: "Linux / *BSD",            v: 92 },
  { k: "Active Directory",        v: 95 },
  { k: "Nätverk & brandvägg",     v: 94 },
  { k: "Virtualisering",          v: 91 },
  { k: "Datarekonstruktion",      v: 97 },
  { k: "Lödning & hårdvara",      v: 98 },
  { k: "Backup-strategi",         v: 99 },
  { k: "Förklara utan jargong",   v: 100 },
];

function SkillMatrix({ accent }) {
  return (
    <div className="skills">
      {SKILLS.map((s, i) => (
        <div key={i} className="skill">
          <span className="skill-k">{s.k}</span>
          <span className="skill-bar">
            <span className="skill-fill" style={{ width: `${s.v}%`, background: accent }} />
          </span>
          <span className="skill-v">{s.v}</span>
        </div>
      ))}
    </div>
  );
}

// ─── Hero typewriter heading ───────────────────────────────────────────────
function Typewriter({ text, speed = 35, className }) {
  const [n, setN] = useState(0);
  useEffect(() => {
    if (n >= text.length) return;
    const id = setTimeout(() => setN(n + 1), speed);
    return () => clearTimeout(id);
  }, [n, text, speed]);
  return <span className={className}>{text.slice(0, n)}</span>;
}

// ─── Hero Video Slider ─────────────────────────────────────────────────────
const HERO_SLIDES = [
  {
    src: "assets/videos/PC-case wood.mp4",
    tag: "01 / CUSTOM BUILD",
    title: "Trä möter aluminium.",
    sub: "Custom-byggd PC i trä, vattenkyld, tystgång. För dig som inte nöjer sig med beige plåt."
  },
  {
    src: "assets/videos/pc-case-black.mp4",
    tag: "02 / WORKSHOP",
    title: "Inifrån verkstaden.",
    sub: "Skruv för skruv. Kabel för kabel. Vi bygger inte snabbt — vi bygger rätt."
  },
  {
    src: "assets/videos/pc-case-black 02.mp4",
    tag: "03 / PRECISION",
    title: "Allt i sitt rätta ställe.",
    sub: "Cable management som inte är i vägen. Airflow som faktiskt funkar."
  },
  {
    src: "assets/videos/rack-server.mp4",
    tag: "04 / SERVERS",
    title: "Servrar i racket.",
    sub: "AD, RAID, backup. På riktigt — inte bara på papper. Inklusive 24/7-larm vid avtal."
  },
  {
    src: "assets/videos/hikvision-camera.mp4",
    tag: "05 / OVERVAKNING",
    title: "Kameror som faktiskt rör sig.",
    sub: "Hikvision, Axis, Ubiquiti. Vi installerar, konfigurerar och larmar."
  },
];

function HeroVideoSlider({ accent }) {
  const [idx, setIdx] = useState(0);
  const [manual, setManual] = useState(false);
  useEffect(() => {
    if (manual) return;
    const id = setInterval(() => setIdx(i => (i + 1) % HERO_SLIDES.length), 7800);
    return () => clearInterval(id);
  }, [manual]);
  const goto = (i) => { setManual(true); setIdx(i); };
  const cur = HERO_SLIDES[idx];
  return (
    <section className="hslide" aria-label="Hero video carousel">
      {HERO_SLIDES.map((s, i) => (
        <video
          key={i}
          src={s.src}
          autoPlay
          muted
          loop
          playsInline
          preload={i === 0 ? "auto" : "metadata"}
          className={`hslide-vid ${i === idx ? "on" : ""}`}
          aria-hidden={i !== idx}
        />
      ))}
      <div className="hslide-scrim" aria-hidden="true" />
      <div className="hslide-overlay">
        <div className="hslide-cap-wrap">
          {HERO_SLIDES.map((s, i) => (
            <div key={i} className={`hslide-cap ${i === idx ? "on" : ""}`}>
              <span className="hslide-tag" style={{ borderColor: accent, color: accent }}>
                <span className="kicker-dot" style={{ background: accent }} />
                {s.tag}
              </span>
              <h2 className="hslide-title">{s.title}</h2>
              <p className="hslide-sub">{s.sub}</p>
            </div>
          ))}
        </div>
        <div className="hslide-cta">
          <a className="btn btn-primary" href="#contact" style={{ borderColor: accent, color: accent }}>
            <span className="btn-dot" style={{ background: accent }} /> boka in din maskin
          </a>
          <a className="btn btn-ghost" href="#svc">./tjänster</a>
        </div>
      </div>
      <div className="hslide-rail" aria-hidden="true">
        {HERO_SLIDES.map((_, i) => (
          <button
            key={i}
            className={`hslide-tick ${i === idx ? "on" : ""}`}
            onClick={() => goto(i)}
            style={i === idx ? { background: accent } : null}
            aria-label={`Gå till slide ${i + 1}`}
          />
        ))}
      </div>
      <div className="hslide-counter mono">
        <span style={{ color: accent }}>{String(idx + 1).padStart(2, "0")}</span>
        <span className="hslide-sep">/</span>
        <span>{String(HERO_SLIDES.length).padStart(2, "0")}</span>
      </div>
    </section>
  );
}

Object.assign(window, {
  StatusBar, BootLog, Spark, Metric, ServiceCard, SERVICES,
  Timeline, Terminal, DiagnosticPanel, SkillMatrix, Typewriter, useNow, fmtTime, fmtDate,
  HeroVideoSlider, HERO_SLIDES,
});
