// Taipei Clock with built-in alarm + secondary timezone display.
// Primary: Taipei (local browser time, with alarm).
// Secondary: Tokyo / New York / London — display only, via Intl.DateTimeFormat (DST-aware).
// Lives absolute-positioned on the right side of hero-v2, right edge aligned to hero padding
// (= same right rail as COVIA big letters for visual column alignment).
// Alarm is one-shot, Web Audio three-tone chime, localStorage 'covia-alarm'.

// Secondary cities — IANA timezone IDs so DST is handled by the browser
const COVIA_SECONDARY_CITIES = [
  { code: 'TYO', tz: 'Asia/Tokyo' },
  { code: 'NYC', tz: 'America/New_York' },
  { code: 'LON', tz: 'Europe/London' },
];

function formatCityTime(date, tz) {
  try {
    return new Intl.DateTimeFormat('en-US', {
      timeZone: tz, hour12: false, hour: '2-digit', minute: '2-digit',
    }).format(date);
  } catch (e) { return '--:--'; }
}

function formatCityOffset(date, tz) {
  try {
    const parts = new Intl.DateTimeFormat('en-US', {
      timeZone: tz, timeZoneName: 'shortOffset',
    }).formatToParts(date);
    const part = parts.find(function(p) { return p.type === 'timeZoneName'; });
    if (!part) return '';
    // "GMT+8" -> "+8", "GMT+09:30" -> "+9:30", "GMT" -> "±0"
    const off = part.value.replace('GMT', '');
    return off === '' ? '±0' : off;
  } catch (e) { return ''; }
}

function CoviaTaipeiClock() {
  const [now, setNow] = React.useState(() => new Date());
  const [alarm, setAlarm] = React.useState(() => {
    try {
      const s = JSON.parse(localStorage.getItem('covia-alarm') || 'null');
      return (s && typeof s.time === 'string' && /^\d{2}:\d{2}$/.test(s.time)) ? s : null;
    } catch (e) { return null; }
  });
  const [draft, setDraft] = React.useState('07:30');
  const [ringing, setRinging] = React.useState(false);
  const ringTimerRef = React.useRef(null);
  const audioCtxRef = React.useRef(null);
  const ringStartRef = React.useRef(0);  // unix ms — for volume escalation calc

  // Tick — 1s resolution is enough (colon blinker is CSS)
  React.useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(id);
  }, []);

  // Persist alarm
  React.useEffect(() => {
    try {
      if (alarm) localStorage.setItem('covia-alarm', JSON.stringify(alarm));
      else localStorage.removeItem('covia-alarm');
    } catch (e) { /* localStorage unavailable */ }
  }, [alarm]);

  // Fire when HH:MM matches; ringing state prevents re-entry within same minute
  React.useEffect(() => {
    if (!alarm || ringing) return;
    const hh = pad2(now.getHours());
    const mm = pad2(now.getMinutes());
    if (hh + ':' + mm === alarm.time) startRinging();
  }, [now, alarm, ringing]);

  // Cleanup on unmount
  React.useEffect(() => function cleanup() {
    if (ringTimerRef.current) clearInterval(ringTimerRef.current);
  }, []);

  function startRinging() {
    setRinging(true);
    ringStartRef.current = Date.now();
    playChime();
    ringTimerRef.current = setInterval(playChime, 1300);
  }
  function stopRinging() {
    setRinging(false);
    if (ringTimerRef.current) {
      clearInterval(ringTimerRef.current);
      ringTimerRef.current = null;
    }
  }
  function dismiss() {
    stopRinging();
    setAlarm(null);
  }
  function snooze() {
    stopRinging();
    const d = new Date();
    d.setMinutes(d.getMinutes() + 9);
    setAlarm({ time: pad2(d.getHours()) + ':' + pad2(d.getMinutes()) });
  }
  function commitAlarm() {
    if (!/^\d{2}:\d{2}$/.test(draft)) return;
    setAlarm({ time: draft });
  }
  function clearAlarm() { setAlarm(null); }

  function playChime() {
    try {
      if (!audioCtxRef.current) {
        audioCtxRef.current = new (window.AudioContext || window.webkitAudioContext)();
      }
      const ctx = audioCtxRef.current;
      if (ctx.state === 'suspended') ctx.resume();

      // Escalating volume for heavy sleepers:
      //   0-3s:   0.15 (gentle intro)
      //   3-22s:  linear 0.15 → 0.70 (ramp over ~20s)
      //   22s+:   0.70 hold (max without distortion on typical laptop speakers)
      const elapsed = ringStartRef.current ? (Date.now() - ringStartRef.current) / 1000 : 0;
      let volume;
      if (elapsed < 3)        volume = 0.15;
      else if (elapsed < 22)  volume = 0.15 + ((elapsed - 3) / 19) * 0.55;
      else                    volume = 0.70;

      // Three-tone chime: C5, E5, G5 (major triad arpeggio)
      [523.25, 659.25, 783.99].forEach(function(freq, i) {
        const t = ctx.currentTime + i * 0.14;
        const osc = ctx.createOscillator();
        const gain = ctx.createGain();
        osc.type = 'sine';
        osc.frequency.value = freq;
        gain.gain.setValueAtTime(0, t);
        gain.gain.linearRampToValueAtTime(volume, t + 0.04);
        gain.gain.exponentialRampToValueAtTime(0.001, t + 0.55);
        osc.connect(gain); gain.connect(ctx.destination);
        osc.start(t);
        osc.stop(t + 0.6);
      });
    } catch (err) { /* audio blocked / unavailable — fail silently */ }
  }

  const hh = pad2(now.getHours());
  const mm = pad2(now.getMinutes());
  const ss = pad2(now.getSeconds());
  const dateStr = now.getFullYear() + '-' + pad2(now.getMonth() + 1) + '-' + pad2(now.getDate());
  const dayStr = ['SUN','MON','TUE','WED','THU','FRI','SAT'][now.getDay()];

  const className = 'covia-clock' +
    (ringing ? ' is-ringing' : '') +
    (alarm && !ringing ? ' has-alarm' : '');

  var _t = window.COVIA_I18N ? window.COVIA_I18N.t : function(k) { return k; };
  return React.createElement('div', { className: className, 'aria-label': _t('clock.aria') },
    // Header
    React.createElement('div', { className: 'covia-clock-head' },
      React.createElement('span', { className: 'code' }, 'TPE'),
      React.createElement('span', { className: 'gmt' }, 'GMT+8'),
      React.createElement('span', { className: 'live-dot', 'aria-hidden': 'true' }),
    ),

    // Big time
    React.createElement('div', {
      className: 'covia-clock-time',
      'aria-label': _t('clock.aria.time') + ' ' + hh + ':' + mm + ':' + ss,
    },
      React.createElement('span', { className: 'hh' }, hh),
      React.createElement('span', { className: 'colon' }, ':'),
      React.createElement('span', { className: 'mm' }, mm),
      React.createElement('span', { className: 'ss' }, ':' + ss),
    ),

    // Date + day
    React.createElement('div', { className: 'covia-clock-date' },
      React.createElement('span', null, dateStr),
      React.createElement('span', { className: 'day' }, dayStr),
    ),

    // Secondary cities — compact stack
    React.createElement('div', { className: 'covia-clock-secondary' },
      COVIA_SECONDARY_CITIES.map(function(city) {
        return React.createElement('div', { key: city.code, className: 'covia-clock-secondary-row' },
          React.createElement('span', { className: 'code' }, city.code),
          React.createElement('span', { className: 'time' }, formatCityTime(now, city.tz)),
          React.createElement('span', { className: 'offset' }, formatCityOffset(now, city.tz)),
        );
      })
    ),

    React.createElement('div', { className: 'covia-clock-divider' }),

    // Alarm UI — state machine: ringing > set > idle
    ringing
      ? React.createElement('div', { className: 'covia-alarm-state is-ringing', role: 'alert' },
          React.createElement('div', { className: 'state-label' },
            React.createElement('span', { className: 'pulse-dot', 'aria-hidden': 'true' }),
            React.createElement('span', null, 'ALARM RINGING'),
          ),
          React.createElement('div', { className: 'state-time' }, alarm ? alarm.time : ''),
          React.createElement('div', { className: 'state-actions' },
            React.createElement('button', {
              type: 'button', onClick: snooze,
              className: 'covia-alarm-btn snooze',
              'aria-label': _t('clock.aria.snooze'),
            }, '+9 min'),
            React.createElement('button', {
              type: 'button', onClick: dismiss,
              className: 'covia-alarm-btn dismiss',
              'aria-label': _t('clock.aria.dismiss'),
            }, 'DISMISS'),
          ),
        )
      : alarm
      ? React.createElement('div', { className: 'covia-alarm-state is-set' },
          React.createElement('div', { className: 'state-label' },
            React.createElement('span', { className: 'icon' }, '◉'),
            React.createElement('span', null, 'ALARM SET'),
          ),
          React.createElement('div', { className: 'state-time' }, alarm.time),
          React.createElement('button', {
            type: 'button', onClick: clearAlarm,
            className: 'covia-alarm-btn clear',
            'aria-label': _t('clock.aria.clear'),
          }, '✕ CLEAR'),
        )
      : React.createElement('div', { className: 'covia-alarm-state is-idle' },
          React.createElement('div', { className: 'state-label' },
            React.createElement('span', { className: 'icon' }, '○'),
            React.createElement('span', null, 'SET ALARM'),
          ),
          React.createElement('div', { className: 'state-form' },
            React.createElement('input', {
              type: 'time',
              value: draft,
              onChange: function(e) { setDraft(e.target.value); },
              className: 'covia-alarm-input',
              'aria-label': _t('clock.aria.input'),
            }),
            React.createElement('button', {
              type: 'button', onClick: commitAlarm,
              className: 'covia-alarm-btn commit',
            }, 'SET'),
          ),
        )
  );
}

function pad2(n) { return String(n).padStart(2, '0'); }

/* ============ Styles ============ */
const coviaClockStyle = document.createElement('style');
coviaClockStyle.textContent = `
  .covia-clock {
    position: absolute;
    top: 42%;
    right: clamp(24px, 5vw, 80px);
    transform: translateY(-50%);
    z-index: 3;
    width: clamp(200px, 20vw, 260px);
    display: flex; flex-direction: column;
    gap: 6px;
    color: var(--text-1);
    font-family: var(--font-body);
    user-select: none;
    text-align: right;
  }

  /* Ringing — ambient glow behind the cluster */
  .covia-clock.is-ringing {
    filter: drop-shadow(0 0 40px oklch(0.78 0.16 75 / 0.3));
    animation: coviaClockPulse 1.8s ease-in-out infinite;
  }
  @keyframes coviaClockPulse {
    0%, 100% { filter: drop-shadow(0 0 40px oklch(0.78 0.16 75 / 0.2)); }
    50%      { filter: drop-shadow(0 0 70px oklch(0.78 0.16 75 / 0.45)); }
  }

  /* Header */
  .covia-clock-head {
    display: flex; align-items: center; gap: 10px;
    justify-content: flex-end;
    font-family: var(--font-mono); font-size: 10px;
    letter-spacing: 0.22em; text-transform: uppercase;
    color: var(--text-2);
    opacity: 0.6;
    transition: opacity 400ms;
  }
  .covia-clock:hover .covia-clock-head { opacity: 1; }
  .covia-clock-head .code {
    color: var(--gold);
    font-size: 11px;
    letter-spacing: 0.28em;
  }
  .covia-clock-head .gmt {
    font-variant-numeric: tabular-nums;
  }
  .covia-clock-head .live-dot {
    width: 5px; height: 5px;
    border-radius: 50%;
    background: oklch(0.72 0.18 150);
    box-shadow: 0 0 6px oklch(0.72 0.18 150 / 0.6);
    animation: coviaLiveBlink 2.4s ease-in-out infinite;
  }
  @keyframes coviaLiveBlink {
    0%, 100% { opacity: 0.35; }
    50%      { opacity: 1; }
  }

  /* Big time — the anchor element */
  .covia-clock-time {
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    gap: 0;
    font-family: var(--font-display);
    font-size: clamp(42px, 4.5vw, 64px);
    font-weight: 400;
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--text-0);
    font-variant-numeric: tabular-nums;
    opacity: 0.18;
    transition: opacity 600ms cubic-bezier(0.16, 1, 0.3, 1);
    text-shadow: 0 0 60px oklch(0.78 0.16 75 / 0.08);
  }
  .covia-clock:hover .covia-clock-time {
    opacity: 0.85;
    text-shadow: 0 0 40px oklch(0.78 0.16 75 / 0.15);
  }
  .covia-clock.is-ringing .covia-clock-time {
    opacity: 1;
    color: var(--gold);
    text-shadow: 0 0 50px oklch(0.78 0.16 75 / 0.35);
  }
  .covia-clock-time .colon {
    color: var(--gold);
    padding: 0 1px;
    opacity: 0.5;
    animation: coviaColonBlink 1s step-end infinite;
  }
  @keyframes coviaColonBlink {
    50% { opacity: 0.12; }
  }
  .covia-clock-time .ss {
    font-family: var(--font-mono);
    font-size: 0.32em;
    color: var(--text-2);
    letter-spacing: 0.02em;
    padding-left: 4px;
    padding-bottom: 6px;
    opacity: 0.6;
  }

  /* Date + day */
  .covia-clock-date {
    display: flex; align-items: baseline; justify-content: flex-end; gap: 12px;
    font-family: var(--font-mono); font-size: 10px;
    color: var(--text-2);
    letter-spacing: 0.1em;
    font-variant-numeric: tabular-nums;
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity 400ms 80ms, transform 400ms 80ms;
  }
  .covia-clock:hover .covia-clock-date {
    opacity: 0.7;
    transform: translateY(0);
  }
  .covia-clock-date .day {
    color: var(--text-1);
    letter-spacing: 0.22em;
  }

  /* Secondary cities */
  .covia-clock-secondary {
    display: flex; flex-direction: column;
    gap: 1px;
    margin-top: 2px;
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity 400ms 140ms, transform 400ms 140ms;
  }
  .covia-clock:hover .covia-clock-secondary {
    opacity: 1;
    transform: translateY(0);
  }
  .covia-clock-secondary-row {
    display: flex;
    align-items: baseline;
    justify-content: flex-end;
    gap: 10px;
    padding: 3px 0;
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
  }
  .covia-clock-secondary-row .code {
    font-size: 9px;
    color: var(--text-2);
    letter-spacing: 0.22em;
    font-weight: 700;
    text-transform: uppercase;
  }
  .covia-clock-secondary-row .time {
    font-size: 12px;
    color: var(--text-1);
    letter-spacing: 0.06em;
  }
  .covia-clock-secondary-row .offset {
    font-size: 8px;
    color: var(--text-2);
    letter-spacing: 0.08em;
    opacity: 0.5;
    min-width: 28px;
    text-align: right;
  }

  /* Divider — thin fade line */
  .covia-clock-divider {
    height: 1px;
    background: linear-gradient(to left,
      oklch(0.78 0.16 75 / 0.25),
      transparent 80%);
    margin: 4px 0 2px;
    opacity: 0;
    transition: opacity 400ms 180ms;
  }
  .covia-clock:hover .covia-clock-divider { opacity: 1; }

  /* Alarm block */
  .covia-alarm-state {
    display: flex; flex-direction: column;
    align-items: flex-end;
    gap: 6px;
    min-height: 56px;
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity 400ms 200ms, transform 400ms 200ms;
  }
  .covia-clock:hover .covia-alarm-state {
    opacity: 1;
    transform: translateY(0);
  }
  .covia-clock.is-ringing .covia-alarm-state {
    opacity: 1;
    transform: translateY(0);
  }
  .covia-alarm-state .state-label {
    display: flex; align-items: center; gap: 8px;
    font-family: var(--font-mono); font-size: 9px;
    letter-spacing: 0.22em; text-transform: uppercase;
    color: var(--text-2);
  }
  .covia-alarm-state .state-label .icon {
    color: var(--text-2);
    font-size: 10px;
    transition: color 320ms;
  }
  .covia-alarm-state.is-set .state-label .icon { color: var(--gold); }
  .covia-alarm-state.is-ringing .state-label { color: var(--gold); }
  .covia-alarm-state .pulse-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--gold);
    box-shadow: 0 0 8px var(--gold);
    animation: coviaPulseDot 500ms ease-in-out infinite alternate;
  }
  @keyframes coviaPulseDot {
    from { transform: scale(1); opacity: 0.8; }
    to   { transform: scale(1.4); opacity: 1; }
  }

  .covia-alarm-state .state-time {
    font-family: var(--font-display);
    font-size: 24px;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--text-0);
    font-variant-numeric: tabular-nums;
  }
  .covia-alarm-state.is-set .state-time { color: var(--gold); }
  .covia-alarm-state.is-ringing .state-time {
    color: var(--gold);
    font-size: 28px;
    animation: coviaAlarmNum 600ms ease-in-out infinite alternate;
  }
  @keyframes coviaAlarmNum {
    from { opacity: 1; }
    to   { opacity: 0.55; }
  }

  .covia-alarm-state .state-form {
    display: flex; align-items: stretch; gap: 6px;
  }
  .covia-alarm-state .state-actions {
    display: flex; gap: 6px;
  }

  .covia-alarm-input {
    flex: 1;
    min-width: 0;
    background: oklch(0.11 0.005 260 / 0.5);
    border: 1px solid oklch(0.3 0.008 260 / 0.5);
    color: var(--text-0);
    font-family: var(--font-mono);
    font-size: 13px;
    letter-spacing: 0.08em;
    padding: 5px 8px;
    border-radius: 6px;
    outline: none;
    font-variant-numeric: tabular-nums;
    color-scheme: dark;
    transition: border-color 200ms;
  }
  .covia-alarm-input:focus { border-color: var(--gold); }

  .covia-alarm-btn {
    background: transparent;
    border: 1px solid oklch(0.3 0.008 260 / 0.5);
    color: var(--text-1);
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    padding: 5px 10px;
    border-radius: 6px;
    cursor: pointer;
    transition: all 200ms cubic-bezier(0.22, 1, 0.36, 1);
    white-space: nowrap;
  }
  .covia-alarm-btn:hover {
    border-color: var(--gold);
    color: var(--gold);
  }
  .covia-alarm-btn:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
  }
  .covia-alarm-btn.commit {
    background: oklch(0.78 0.16 75 / 0.15);
    color: var(--gold);
    border-color: oklch(0.78 0.16 75 / 0.3);
  }
  .covia-alarm-btn.commit:hover {
    background: oklch(0.78 0.16 75 / 0.25);
  }
  .covia-alarm-btn.clear {
    color: var(--text-2);
    align-self: flex-end;
  }
  .covia-alarm-btn.clear:hover {
    border-color: oklch(0.6 0.14 22);
    color: oklch(0.76 0.14 22);
  }
  .covia-alarm-btn.dismiss {
    background: oklch(0.78 0.16 75 / 0.15);
    color: var(--gold);
    border-color: oklch(0.78 0.16 75 / 0.3);
    flex: 1;
  }
  .covia-alarm-btn.dismiss:hover {
    background: oklch(0.78 0.16 75 / 0.25);
  }
  .covia-alarm-btn.snooze { flex: 0 0 auto; }

  /* Responsive */
  @media (max-width: 900px) {
    .covia-clock {
      position: relative;
      top: auto; right: auto;
      transform: none;
      margin: 32px 0 0 auto;
      width: auto;
      max-width: 260px;
    }
    /* Show details on mobile since hover isn't reliable */
    .covia-clock-time { opacity: 0.35; }
    .covia-clock-date { opacity: 0.5; transform: none; }
    .covia-clock-secondary { opacity: 0.7; transform: none; }
    .covia-clock-divider { opacity: 0.6; }
    .covia-alarm-state { opacity: 1; transform: none; }
  }
  @media (max-width: 520px) {
    .covia-clock { display: none; }
  }

  /* Reduced motion */
  @media (prefers-reduced-motion: reduce) {
    .covia-clock.is-ringing { animation: none; }
    .covia-clock-time .colon,
    .covia-clock-head .live-dot,
    .covia-alarm-state .pulse-dot,
    .covia-alarm-state.is-ringing .state-time { animation: none; }
  }
`;
document.head.appendChild(coviaClockStyle);

window.CoviaTaipeiClock = CoviaTaipeiClock;
