'use client';

import { useEffect, useState, useRef, useCallback } from 'react';
import { getRecommendation, sendFeedback, getVapidPublicKey, subscribePush } from '@/lib/api';
import type { Tip } from '@oo/shared-types';

type State = 'loading' | 'tip' | 'empty' | 'actions' | 'done';

// Fade wrapper — children fade in when `visible`, fade out when not
function Fade({ visible, children, style }: {
  visible: boolean;
  children: React.ReactNode;
  style?: React.CSSProperties;
}) {
  return (
    <div style={{
      opacity: visible ? 1 : 0,
      transition: visible ? 'opacity 3.5s ease' : 'opacity 0.3s ease',
      pointerEvents: visible ? 'auto' : 'none',
      ...style,
    }}>
      {children}
    </div>
  );
}

export default function TipPage() {
  const [tip, setTip] = useState<Tip | null>(null);
  const [state, setState] = useState<State>('loading');
  const [visible, setVisible] = useState(false);
  const holdTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const [pressed, setPressed] = useState(false);
  const [pushState, setPushState] = useState<'idle' | 'subscribed' | 'denied'>('idle');

  // Fade in after state change settles
  useEffect(() => {
    if (state === 'loading' || state === 'done') {
      setVisible(false);
    } else {
      const t = setTimeout(() => setVisible(true), 30);
      return () => clearTimeout(t);
    }
  }, [state]);

  const loadTip = useCallback(async () => {
    setVisible(false);
    setState('loading');
    try {
      const rec = await getRecommendation();
      if (!rec) {
        setState('empty');
        return;
      }
      setTip(rec.tip);
      setState('tip');
    } catch (err: any) {
      console.error('[tip] loadTip error', err?.status, err?.message);
      setState('empty');
    }
  }, []);

  useEffect(() => { loadTip(); }, [loadTip]);

  // Check existing push permission on mount
  useEffect(() => {
    if (typeof Notification !== 'undefined' && Notification.permission === 'granted') {
      setPushState('subscribed');
    } else if (typeof Notification !== 'undefined' && Notification.permission === 'denied') {
      setPushState('denied');
    }
  }, []);

  const requestPush = useCallback(async () => {
    if (!('serviceWorker' in navigator) || !('PushManager' in window)) return;
    const permission = await Notification.requestPermission();
    if (permission !== 'granted') { setPushState('denied'); return; }
    try {
      const reg = await navigator.serviceWorker.register('/sw.js');
      const vapidKey = await getVapidPublicKey();
      const sub = await reg.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: vapidKey,
      });
      await subscribePush(sub.toJSON());
      setPushState('subscribed');
    } catch { setPushState('denied'); }
  }, []);

  const react = async (action: 'done' | 'dismiss' | 'snooze' | 'helpful' | 'not_helpful') => {
    if (!tip) return;
    const isNavigating = ['done', 'dismiss', 'snooze'].includes(action);
    if (isNavigating) {
      setVisible(false);
      setState('done');
    } else {
      setState('tip');
    }
    await sendFeedback(tip.id, { action });
    if (isNavigating) setTimeout(() => loadTip(), 700);
  };

  const onPointerDown = () => {
    if (state !== 'tip') return;
    setPressed(true);
    holdTimer.current = setTimeout(() => {
      setState('actions');
      setVisible(true);
      setPressed(false);
    }, 600);
  };

  const onPointerUp = () => {
    setPressed(false);
    if (holdTimer.current) {
      clearTimeout(holdTimer.current);
      holdTimer.current = null;
    }
  };

  return (
    <>

      <style>{`
        @keyframes breathe {
          0%, 100% { opacity: 0.3; }
          50%       { opacity: 1;   }
        }
      `}</style>

      <main
        onPointerDown={onPointerDown}
        onPointerUp={onPointerUp}
        onPointerLeave={onPointerUp}
        style={{
          height: '100dvh',
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          justifyContent: 'center',
          userSelect: 'none',
          WebkitUserSelect: 'none',
          cursor: state === 'tip' ? 'default' : 'auto',
          position: 'relative',
          overflow: 'hidden',
        }}
      >
        {/* Ambient glow — breathes while loading */}
        <div style={{
          position: 'absolute',
          inset: 0,
          background: 'radial-gradient(ellipse at center, rgba(255,255,255,0.06) 0%, transparent 65%)',
          animation: state === 'loading' ? 'breathe 4s ease-in-out infinite' : undefined,
          opacity: state === 'loading' ? undefined : pressed ? 0.3 : 0,
          transition: state !== 'loading' ? 'opacity 0.4s ease' : undefined,
          pointerEvents: 'none',
        }} />

        {/* Loading label */}
        {(state === 'loading' || state === 'done') && (
          <p style={{
            margin: 0,
            color: 'rgba(255,255,255,0.55)',
            fontSize: '0.7rem',
            letterSpacing: '0.18em',
            textTransform: 'uppercase',
            animation: 'breathe 4s ease-in-out infinite',
          }}>
            reading you…
          </p>
        )}

        {/* Tip */}
        {(state === 'tip' || state === 'actions') && tip && (
          <Fade visible={visible && state !== 'actions'} style={{ textAlign: 'center', maxWidth: '420px', padding: '0 2rem' }}>
            <p style={{
              fontSize: 'clamp(1.25rem, 4vw, 1.75rem)',
              fontWeight: 300,
              lineHeight: 1.45,
              letterSpacing: '-0.01em',
              color: 'rgba(255,255,255,1)',
              transition: 'opacity 0.2s ease',
              opacity: pressed ? 0.5 : 1,
            }}>
              {tip.content}
            </p>
            <p style={{
              marginTop: '2rem',
              color: 'rgba(255,255,255,0.18)',
              fontSize: '0.65rem',
              letterSpacing: '0.12em',
              textTransform: 'uppercase',
            }}>
              hold to act
            </p>
            {pushState === 'idle' && (
              <button
                onClick={(e) => { e.stopPropagation(); requestPush(); }}
                style={{
                  marginTop: '2.5rem',
                  background: 'transparent',
                  border: 'none',
                  color: 'rgba(255,255,255,0.18)',
                  fontSize: '0.65rem',
                  letterSpacing: '0.12em',
                  textTransform: 'uppercase',
                  cursor: 'pointer',
                  padding: 0,
                }}
              >
                notify me
              </button>
            )}
          </Fade>
        )}

        {/* Empty */}
        {state === 'empty' && (
          <Fade visible={visible} style={{ textAlign: 'center' }}>
            <p style={{ fontSize: '1.1rem', fontWeight: 300, color: 'rgba(255,255,255,0.35)' }}>
              All clear.
            </p>
            <button
              onClick={loadTip}
              style={{
                marginTop: '2rem',
                background: 'transparent',
                border: '1px solid rgba(255,255,255,0.1)',
                color: 'rgba(255,255,255,0.35)',
                borderRadius: '0.375rem',
                padding: '0.5rem 1rem',
                fontSize: '0.8rem',
                cursor: 'pointer',
              }}
            >
              Check again
            </button>
          </Fade>
        )}

        {/* Action sheet */}
        {state === 'actions' && (
          <>
            <div
              onClick={() => { setState('tip'); }}
              style={{
                position: 'fixed',
                inset: 0,
                background: 'rgba(0,0,0,0.5)',
                animation: 'none',
              }}
            />
            <div style={{
              position: 'fixed',
              bottom: 0,
              left: 0,
              right: 0,
              background: '#111',
              borderRadius: '1rem 1rem 0 0',
              padding: '1.5rem 1.5rem 2.5rem',
              display: 'flex',
              flexDirection: 'column',
              gap: '0.75rem',
              transform: 'translateY(0)',
              transition: 'transform 0.3s ease',
            }}>
              {tip && (
                <p style={{
                  color: 'rgba(255,255,255,0.35)',
                  fontSize: '0.8rem',
                  marginBottom: '0.5rem',
                  lineHeight: 1.4,
                }}>
                  {tip.content}
                </p>
              )}
              <ActionButton label="Done ✓" onClick={() => react('done')} primary />
              <ActionButton label="Helpful" onClick={() => react('helpful')} />
              <ActionButton label="Not helpful" onClick={() => react('not_helpful')} />
              <ActionButton label="Snooze" onClick={() => react('snooze')} />
              <ActionButton label="Dismiss" onClick={() => react('dismiss')} />
              <button
                onClick={() => setState('tip')}
                style={{
                  background: 'transparent',
                  border: 'none',
                  color: 'rgba(255,255,255,0.25)',
                  padding: '0.5rem',
                  fontSize: '0.8rem',
                  cursor: 'pointer',
                  marginTop: '0.25rem',
                }}
              >
                Cancel
              </button>
            </div>
          </>
        )}
      </main>
    </>
  );
}

function ActionButton({ label, onClick, primary }: { label: string; onClick: () => void; primary?: boolean }) {
  return (
    <button
      onClick={onClick}
      style={{
        background: primary ? 'var(--white)' : 'rgba(255,255,255,0.06)',
        color: primary ? 'var(--black)' : 'var(--white)',
        border: 'none',
        borderRadius: '0.625rem',
        padding: '1rem',
        fontSize: '0.95rem',
        fontWeight: primary ? 500 : 400,
        width: '100%',
        textAlign: 'center',
        cursor: 'pointer',
      }}
    >
      {label}
    </button>
  );
}
