/* global React,
   FolderIcon, BrowserIcon, ContactsIcon, NotesIcon, AboutIcon,
   WorkIcon, GearIcon, ChevronLeftIcon, ChevronRightIcon, SearchIcon,
   WORK, SIDE, POSTS, RATES, ABOUT, CASSETTES,
   WorkDetail, SideDetail, BlogPostView, AboutApp,
   useClock */

const { useState, useEffect, useMemo } = React;

/* =========================================================================
   iOS-only app icons (Music, Phone) — Mac doesn't use these
   ========================================================================= */
function MusicIosIcon({ size = 48 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 48 48">
      <defs>
        <linearGradient id="ios-mu-bg" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor="#ff5fa3"/>
          <stop offset="1" stopColor="#c41353"/>
        </linearGradient>
      </defs>
      <rect x="4" y="4" width="40" height="40" rx="9" fill="url(#ios-mu-bg)"/>
      <g transform="translate(-0.75 0.75)">
        <path d="M21 14 L33 12 L33 28 a3.5 3.5 0 1 1 -2.5-3.4 V19 L23 20.5 V31 a3.5 3.5 0 1 1 -2.5-3.4 z"
              fill="#fff"/>
      </g>
    </svg>
  );
}

function PhoneIosIcon({ size = 48 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 48 48">
      <defs>
        <linearGradient id="ios-ph-bg" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor="#6be36b"/>
          <stop offset="1" stopColor="#1f9b1f"/>
        </linearGradient>
      </defs>
      <rect x="4" y="4" width="40" height="40" rx="9" fill="url(#ios-ph-bg)"/>
      {/* Classic tilted handset glyph */}
      <path d="M17.7 13.5 c-1.7 0-3 1.3-3 3 c0 11.6 9.4 21 21 21 c1.7 0 3-1.3 3-3 v-3.5
               c0-1.4-0.9-2.6-2.2-2.9 l-4-1 c-1.1-0.3-2.3 0.1-3 1 l-1.2 1.6
               c-3.1-1.4-5.6-3.9-7-7 l1.6-1.2 c0.9-0.7 1.3-1.9 1-3 l-1-4
               c-0.3-1.3-1.5-2.2-2.9-2.2 z"
            fill="#fff"/>
    </svg>
  );
}

/* =========================================================================
   Status bar (20pt) — signal · carrier · time · battery
   ========================================================================= */
function IOSStatusBar() {
  const now = useClock();
  const h = now.getHours();
  const m = now.getMinutes().toString().padStart(2, '0');
  const hh = h % 12 === 0 ? 12 : h % 12;
  const time = `${hh}:${m} ${h >= 12 ? 'PM' : 'AM'}`;

  return (
    <div className="ios-statusbar">
      <div className="ios-sb-left">
        <span className="ios-sig">
          <i className="ios-sig-bar"/><i className="ios-sig-bar"/><i className="ios-sig-bar"/>
          <i className="ios-sig-bar"/><i className="ios-sig-bar"/>
        </span>
        <span className="ios-carrier">makOS</span>
      </div>
      <div className="ios-sb-center">{time}</div>
      <div className="ios-sb-right">
        <span className="ios-batt-pct">100%</span>
        <span className="ios-batt-icon"><i/></span>
      </div>
    </div>
  );
}

/* =========================================================================
   Home screen — grid + page dots + dock
   ========================================================================= */
/* The icon click reports the tile's center as a 0..1 fraction of the screen
   canvas so the parent can use it as transform-origin for the open animation
   (icon → fullscreen). Falls back to the screen center if measurement fails. */
function IOSAppIcon({ icon, label, onClick, hideLabel = false }) {
  const handleClick = (e) => {
    const root = e.currentTarget;
    const tile = root.querySelector('.ios-app-tile') || root;
    const canvas = root.closest('.ios-screen-canvas');
    let origin = { x: 0.5, y: 0.5 };
    if (canvas) {
      const cb = canvas.getBoundingClientRect();
      const tb = tile.getBoundingClientRect();
      origin = {
        x: ((tb.left + tb.width  / 2) - cb.left) / cb.width,
        y: ((tb.top  + tb.height / 2) - cb.top)  / cb.height,
      };
    }
    onClick(origin);
  };
  return (
    <div className="ios-app-icon" onClick={handleClick}>
      <div className="ios-app-tile">
        <div className="ios-app-glyph">{icon}</div>
        <div className="ios-app-gloss"/>
      </div>
      {!hideLabel && <div className="ios-app-label">{label}</div>}
    </div>
  );
}

function IOSHomeScreen({ onOpen }) {
  const apps = [
    { id: 'work',     label: 'Work',     icon: <WorkIcon/> },
    { id: 'side',     label: 'Side',     icon: <FolderIcon/> },
    { id: 'writing',  label: 'Writing',  icon: <NotesIcon/> },
    { id: 'about',    label: 'About',    icon: <AboutIcon/> },
    { id: 'browser',  label: 'Resume',   icon: <BrowserIcon/> },
  ];
  const dock = [
    { id: 'contacts', label: 'Phone',    icon: <PhoneIosIcon/> },
    { id: 'music',    label: 'Music',    icon: <MusicIosIcon/> },
    { id: 'settings', label: 'Settings', icon: <GearIcon/> },
  ];

  return (
    <div className="ios-home">
      <div className="ios-home-grid">
        {apps.map(app => (
          <IOSAppIcon key={app.id} icon={app.icon} label={app.label}
                      onClick={(origin) => onOpen(app.id, origin)}/>
        ))}
      </div>
      <div className="ios-page-dots"><span className="active"/></div>
      <div className="ios-dock">
        {dock.map(app => (
          <IOSAppIcon key={app.id} icon={app.icon} label={app.label}
                      onClick={(origin) => onOpen(app.id, origin)} hideLabel/>
        ))}
      </div>
    </div>
  );
}

/* =========================================================================
   App shell — status bar already rendered above; this is just nav bar + body
   ========================================================================= */
function IOSNavBar({ title, onBack, backLabel = 'Back', rightAction }) {
  return (
    <div className="ios-navbar">
      {onBack && (
        <button className="ios-nav-back" onClick={onBack}>
          <span className="ios-nav-back-arrow"/>
          <span>{backLabel}</span>
        </button>
      )}
      <div className="ios-nav-title">{title}</div>
      <div className="ios-nav-right">{rightAction}</div>
    </div>
  );
}

function IOSAppShell({ title, onBack, backLabel, rightAction, children }) {
  return (
    <div className="ios-app-shell">
      <IOSNavBar title={title} onBack={onBack} backLabel={backLabel} rightAction={rightAction}/>
      <div className="ios-app-body">{children}</div>
    </div>
  );
}

/* =========================================================================
   Grouped list — UITableView grouped style
   ========================================================================= */
function IOSGroupedList({ groups }) {
  return (
    <div className="ios-grouped-list">
      {groups.map((g, gi) => (
        <div key={gi} className="ios-group-section">
          {g.header && <div className="ios-group-header">{g.header}</div>}
          <div className="ios-group">
            {g.items.map((it, ii) => {
              const accessory = it.accessory !== undefined
                ? it.accessory
                : (it.onClick ? <span className="ios-row-chevron"/> : null);
              return (
                <div key={it.id || ii} className={`ios-row ${it.onClick ? 'tappable' : ''}`}
                     onClick={it.onClick}>
                  {it.icon && <div className="ios-row-icon">{it.icon}</div>}
                  <div className="ios-row-text">
                    <div className="ios-row-primary">{it.primary}</div>
                    {it.secondary && <div className="ios-row-secondary">{it.secondary}</div>}
                  </div>
                  {accessory}
                </div>
              );
            })}
          </div>
          {g.footer && <div className="ios-group-footer">{g.footer}</div>}
        </div>
      ))}
    </div>
  );
}

function IOSToggle({ on, onChange }) {
  return (
    <button type="button" className="ios-toggle" data-on={on ? '1' : '0'}
            role="switch" aria-checked={!!on}
            onClick={(e) => { e.stopPropagation(); onChange(!on); }}>
      <i/>
    </button>
  );
}

/* =========================================================================
   Per-app: Work / Side / Writing — list -> detail (existing detail bodies)
   ========================================================================= */
function IOSWorkApp({ stack, onPushDetail, onPopDetail }) {
  const item = stack[stack.length - 1];
  if (!item) {
    return (
      <IOSAppShell title="Work">
        <IOSGroupedList groups={[{
          header: `${WORK.length} entries`,
          items: WORK.map(w => ({
            id: w.id,
            primary: w.name,
            secondary: `${w.role} · ${w.when}`,
            onClick: () => onPushDetail(w),
          })),
        }]}/>
      </IOSAppShell>
    );
  }
  return (
    <IOSAppShell title={item.name} onBack={onPopDetail} backLabel="Work">
      <WorkDetail item={item}/>
    </IOSAppShell>
  );
}

function IOSSideApp({ stack, onPushDetail, onPopDetail }) {
  const item = stack[stack.length - 1];
  if (!item) {
    return (
      <IOSAppShell title="Side Projects">
        <IOSGroupedList groups={[{
          header: `${SIDE.length} projects`,
          items: SIDE.map(s => ({
            id: s.id,
            primary: s.name,
            secondary: `${s.when} · ${s.summary.split('.')[0]}.`,
            onClick: () => onPushDetail(s),
          })),
        }]}/>
      </IOSAppShell>
    );
  }
  return (
    <IOSAppShell title={item.name} onBack={onPopDetail} backLabel="Side">
      <SideDetail item={item}/>
    </IOSAppShell>
  );
}

function IOSWritingApp({ stack, onPushDetail, onPopDetail }) {
  const item = stack[stack.length - 1];
  // Group posts by year for the index
  const groups = useMemo(() => {
    const byYear = {};
    POSTS.forEach(p => {
      const y = (p.date || '').slice(0, 4);
      (byYear[y] = byYear[y] || []).push(p);
    });
    return Object.keys(byYear).sort().reverse().map(year => ({
      header: year,
      items: byYear[year].map(p => ({
        id: p.id,
        primary: p.title,
        secondary: `${p.read} · ${p.kind}`,
        onClick: () => onPushDetail(p),
      })),
    }));
  }, []);

  if (!item) {
    return (
      <IOSAppShell title="Writing">
        <IOSGroupedList groups={groups}/>
      </IOSAppShell>
    );
  }
  return (
    <IOSAppShell title={item.kind} onBack={onPopDetail} backLabel="Writing">
      <BlogPostView item={item}/>
    </IOSAppShell>
  );
}

/* =========================================================================
   About — single page using the shared AboutApp body
   ========================================================================= */
function IOSAboutApp() {
  return (
    <IOSAppShell title="About">
      <AboutApp/>
    </IOSAppShell>
  );
}

/* =========================================================================
   Resume — Mobile Safari toolbar + the same resume content as the Mac
   ========================================================================= */
function IOSResumeApp() {
  return (
    <IOSAppShell title="Resume">
      <div className="ios-safari-bar">
        <div className="ios-safari-pill">
          <SearchIcon size={11}/>
          <span>portfolio.timofeymakhlay.com/resume</span>
        </div>
      </div>
      <div className="detail-pane ios-detail">
        <h1>Timofey Makhlay</h1>
        <div className="subhead">Founding / full-stack engineer · Berlin · San Francisco</div>
        <div className="meta-row">
          <span>tmakhlay2@gmail.com</span>
          <span className="dot"/>
          <span>EN · RU · IT</span>
        </div>
        <p>10+ years building product at the seam between infra, web, and mobile.
           Founding-engineer DNA. Trades architecture for velocity on purpose,
           then pays the debt down before it compounds.</p>

        <h2>Selected experience</h2>
        {WORK.map(w => (
          <div key={w.id} style={{marginBottom: 14}}>
            <h3 style={{marginBottom: 2}}>
              {w.name}
              <span style={{fontWeight:500, color:'var(--mac-text-3)'}}> — {w.role}</span>
            </h3>
            <div style={{fontSize:11, color:'var(--mac-text-3)', marginBottom: 4}}>
              {w.when} · {w.where}
            </div>
            <p style={{marginBottom:4}}>{w.summary}</p>
          </div>
        ))}

        <h2>Selected side projects</h2>
        <ul>
          {SIDE.map(s => (
            <li key={s.id}>
              <strong>{s.name}</strong>
              <span style={{color:'var(--mac-text-3)'}}> · {s.when}</span> — {s.summary.split('.')[0]}.
            </li>
          ))}
        </ul>

        <h2>Writing</h2>
        <ul>{POSTS.map(p => <li key={p.id}>{p.title}
          <span style={{color:'var(--mac-text-3)'}}> · {p.date}</span></li>)}</ul>

        <h2>Education</h2>
        <ul>
          <li>Make School — B.A.S. Computer Science (2017 — 2020)</li>
          <li>Y Combinator Startup School (2020)</li>
        </ul>
      </div>
    </IOSAppShell>
  );
}

/* =========================================================================
   Contacts — single contact card + rates, iOS-styled
   ========================================================================= */
function IOSContactsApp() {
  return (
    <IOSAppShell title="Contacts">
      <div className="ios-contact">
        <div className="ios-contact-hero">
          <div className="ios-contact-avatar">TM</div>
          <div className="ios-contact-name">Timofey Makhlay</div>
          <div className="ios-contact-role">Founding / full-stack engineer</div>
          <div className="ios-contact-actions">
            <a href="mailto:tmakhlay2@gmail.com" className="ios-contact-btn">message</a>
            <a href="mailto:tmakhlay2@gmail.com" className="ios-contact-btn">email</a>
          </div>
        </div>

        <IOSGroupedList groups={[
          {
            items: [
              { id: 'email', primary: 'tmakhlay2@gmail.com', secondary: 'email',
                onClick: () => navigator.clipboard?.writeText('tmakhlay2@gmail.com') },
              { id: 'li',    primary: 'linkedin.com/in/timofeymakhlay', secondary: 'linkedin' },
              { id: 'loc',   primary: 'Berlin / San Francisco',         secondary: 'based in' },
              { id: 'lang',  primary: 'English · Russian · Italian',    secondary: 'languages' },
              { id: 'avail', primary: 'Booking Q3 2026 — one slot left',secondary: 'availability' },
            ],
          },
          {
            header: 'Rates',
            items: RATES.map(r => ({
              id: r.who, primary: r.who, secondary: r.desc,
              accessory: <div className="ios-rate-price">
                <div className="ios-rate-num">{r.price}</div>
                <div className="ios-rate-unit">{r.unit}</div>
              </div>,
            })),
          },
          {
            header: 'Notes',
            footer: 'makOS Contacts',
            items: [
              { id: 'note', primary: 'Reply with the shape of the problem and I\'ll tell you whether I\'m the right person for it.' },
            ],
          },
        ]}/>
      </div>
    </IOSAppShell>
  );
}

/* =========================================================================
   Settings — grouped switches mirroring the Mac System Settings
   ========================================================================= */
const ACCENTS = [
  {v:'#0a84ff', n:'Blue'},
  {v:'#bf5af2', n:'Purple'},
  {v:'#ff375f', n:'Pink'},
  {v:'#ff9f0a', n:'Orange'},
  {v:'#30d158', n:'Green'},
  {v:'#5e5ce6', n:'Indigo'},
];

function IOSSettingsApp({ tweaks, setTweak, onRestart }) {
  return (
    <IOSAppShell title="Settings">
      <IOSGroupedList groups={[
        {
          header: 'Appearance',
          items: [
            { id: 'theme', primary: 'Dark Mode',
              accessory: <IOSToggle on={tweaks.darkMode}
                                    onChange={(v) => setTweak('darkMode', v)}/> },
            { id: 'accent', primary: 'Accent Color',
              accessory: <div className="ios-accent-row">
                {ACCENTS.map(c => (
                  <button key={c.v} title={c.n}
                          onClick={(e) => { e.stopPropagation(); setTweak('accent', c.v); }}
                          className={`ios-accent-swatch ${tweaks.accent === c.v ? 'on' : ''}`}
                          style={{ background: c.v }}/>
                ))}
              </div> },
          ],
        },
        {
          header: 'Boot',
          items: [
            { id: 'skip', primary: 'Skip Intro',
              secondary: 'Skip the iPhone power-on animation',
              accessory: <IOSToggle on={tweaks.skipIntro}
                                    onChange={(v) => setTweak('skipIntro', v)}/> },
            { id: 'restart', primary: 'Restart',
              onClick: onRestart,
              accessory: <span className="ios-row-chevron"/> },
          ],
        },
        {
          header: 'About',
          footer: 'makOS Mobile · build 26.04.26',
          items: [
            { id: 'ver',   primary: 'Version', accessory: <span className="ios-row-aux">15.2</span> },
            { id: 'model', primary: 'Model',   accessory: <span className="ios-row-aux">iPhone 3GS</span> },
            { id: 'sn',    primary: 'Serial',  accessory: <span className="ios-row-aux">TM-26-04-26</span> },
          ],
        },
      ]}/>
    </IOSAppShell>
  );
}

/* =========================================================================
   Music app — list of cassettes, then a player view (auto-plays on push)
   ========================================================================= */
function IOSMusicApp({ stack, onPushDetail, onPopDetail, audioApi }) {
  const cassette = stack[stack.length - 1];

  // Auto-play when entering a cassette's player page.
  useEffect(() => {
    if (cassette && (!audioApi.active || audioApi.active.id !== cassette.id)) {
      audioApi.pick(cassette);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [cassette && cassette.id]);

  if (!cassette) {
    return (
      <IOSAppShell title="Music">
        <IOSGroupedList groups={[{
          header: 'Your favorites',
          footer: audioApi.active ? `Now playing — ${audioApi.active.title}` : null,
          items: CASSETTES.map(c => {
            const isActive = audioApi.active && audioApi.active.id === c.id;
            const artStyle = c.cover
              ? { backgroundImage: `url("${c.cover}")`, backgroundSize: 'cover', backgroundPosition: 'center', backgroundColor: c.color }
              : { background: c.color };
            return {
              id: c.id,
              primary: c.title,
              secondary: c.artist,
              icon: <div className="ios-music-art" style={artStyle}/>,
              onClick: () => onPushDetail(c),
              accessory: isActive
                ? <span className={`ios-music-bars ${audioApi.paused ? '' : 'on'}`}>
                    <i/><i/><i/>
                  </span>
                : <span className="ios-row-chevron"/>,
            };
          }),
        }]}/>
      </IOSAppShell>
    );
  }
  return (
    <IOSAppShell title={cassette.title} onBack={onPopDetail} backLabel="Music">
      <IOSPlayerView cassette={cassette} audioApi={audioApi}/>
    </IOSAppShell>
  );
}

function IOSPlayerView({ cassette, audioApi }) {
  const fmt = (t) => {
    if (!t || isNaN(t)) return '0:00';
    const m = Math.floor(t / 60);
    const s = Math.floor(t % 60).toString().padStart(2, '0');
    return `${m}:${s}`;
  };
  const pct = audioApi.duration ? (audioApi.progress / audioApi.duration) * 100 : 0;
  const isThis = audioApi.active && audioApi.active.id === cassette.id;

  return (
    <div className="ios-player" style={{
      '--np-color': cassette.color,
      background: `linear-gradient(180deg,
                     color-mix(in oklab, ${cassette.color}, black 30%) 0%,
                     #0a0a0c 100%)`,
    }}>
      <div
        className={`ios-player-art ${cassette.cover ? 'has-cover' : ''}`}
        style={cassette.cover ? { backgroundImage: `url("${cassette.cover}")` } : null}
      >
        <div className="ios-player-reels">
          <div className={`ios-player-reel ${isThis && !audioApi.paused ? 'spin' : ''}`}><div/></div>
          <div className={`ios-player-reel ${isThis && !audioApi.paused ? 'spin' : ''}`}><div/></div>
        </div>
      </div>

      <div className="ios-player-meta">
        <div className="ios-player-title">{cassette.title}</div>
        <div className="ios-player-sub">CHROME · 60 · {cassette.side}</div>
      </div>

      <div className="ios-player-progress">
        <div className="ios-player-bar">
          <div className="ios-player-fill" style={{ width: `${pct}%` }}/>
        </div>
        <div className="ios-player-times">
          <span>{fmt(audioApi.progress)}</span>
          <span>-{fmt(Math.max(0, (audioApi.duration || 0) - (audioApi.progress || 0)))}</span>
        </div>
      </div>

      <div className="ios-player-controls">
        <button className="ios-player-btn" onClick={() => audioApi.seek(Math.max(0, audioApi.progress - 15))}>
          ⏮
        </button>
        <button className="ios-player-btn ios-player-btn-big" onClick={audioApi.togglePlay}>
          {isThis && !audioApi.paused ? '❚❚' : '▶'}
        </button>
        <button className="ios-player-btn" onClick={() => audioApi.seek(audioApi.progress + 15)}>
          ⏭
        </button>
      </div>
    </div>
  );
}

Object.assign(window, {
  IOSStatusBar, IOSHomeScreen, IOSAppShell, IOSNavBar, IOSGroupedList, IOSToggle,
  IOSWorkApp, IOSSideApp, IOSWritingApp,
  IOSAboutApp, IOSResumeApp, IOSContactsApp,
  IOSSettingsApp, IOSMusicApp, IOSPlayerView,
  MusicIosIcon, PhoneIosIcon,
});
