'use client';

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from 'react';
import { cn } from '@/lib/utils';

export type FeedbackTone = 'success' | 'danger';

type FeedbackItem = {
  id: string;
  message: string;
  tone: FeedbackTone;
  leaving?: boolean;
};

type FeedbackContextValue = {
  push: (message: string, tone?: FeedbackTone) => void;
  success: (message: string) => void;
  error: (message: string) => void;
};

const FeedbackContext = createContext<FeedbackContextValue | null>(null);

const SHOW_MS = 3400;
const EXIT_MS = 260;

/** Browsers over plain HTTP (LAN IP) often lack crypto.randomUUID. */
function newFeedbackId() {
  if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
    return crypto.randomUUID();
  }
  return `fb-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
}

export function FeedbackProvider({ children }: { children: ReactNode }) {
  const [items, setItems] = useState<FeedbackItem[]>([]);

  const dismiss = useCallback((id: string) => {
    setItems(current => current.map(item => (item.id === id ? { ...item, leaving: true } : item)));
    window.setTimeout(() => {
      setItems(current => current.filter(item => item.id !== id));
    }, EXIT_MS);
  }, []);

  const push = useCallback((message: string, tone: FeedbackTone = 'success') => {
    const id = newFeedbackId();
    setItems(current => [...current.slice(-3), { id, message, tone }]);
    window.setTimeout(() => dismiss(id), SHOW_MS);
  }, [dismiss]);

  const value = useMemo<FeedbackContextValue>(() => ({
    push,
    success: message => push(message, 'success'),
    error: message => push(message, 'danger'),
  }), [push]);

  return (
    <FeedbackContext.Provider value={value}>
      {children}
      <div
        className="pointer-events-none fixed inset-x-0 top-[calc(var(--panel-header-h)+var(--safe-top)+0.75rem)] z-[80] flex flex-col items-center gap-2 px-3 lg:items-end lg:px-6"
        aria-live="polite"
        aria-relevant="additions"
      >
        {items.map(item => (
          <div
            key={item.id}
            role={item.tone === 'danger' ? 'alert' : 'status'}
            className={cn(
              'pointer-events-auto w-full max-w-sm rounded-[var(--radius-md)] border px-4 py-3 text-sm font-semibold shadow-[var(--shadow-lg)]',
              item.leaving ? 'feedback-toast-leave' : 'feedback-toast-enter',
              item.tone === 'success'
                ? 'border-success/20 bg-success-soft text-success'
                : 'border-danger/20 bg-danger-soft text-danger',
            )}
          >
            {item.message}
          </div>
        ))}
      </div>
    </FeedbackContext.Provider>
  );
}

export function useFeedback() {
  const ctx = useContext(FeedbackContext);
  if (!ctx) throw new Error('useFeedback must be used within FeedbackProvider');
  return ctx;
}

/** Inline animated banner for form-level messages. */
export function FeedbackBanner({
  tone,
  children,
  className,
}: {
  tone: FeedbackTone;
  children: ReactNode;
  className?: string;
}) {
  const [visible, setVisible] = useState(false);
  useEffect(() => {
    const id = requestAnimationFrame(() => setVisible(true));
    return () => cancelAnimationFrame(id);
  }, [children, tone]);

  return (
    <p
      role={tone === 'danger' ? 'alert' : 'status'}
      className={cn(
        'rounded-[var(--radius-md)] px-3 py-2 text-sm font-medium transition-[opacity,transform] duration-300 ease-out',
        visible ? 'translate-y-0 opacity-100' : 'translate-y-1 opacity-0',
        tone === 'success' ? 'bg-success-soft text-success' : 'bg-danger-soft text-danger',
        className,
      )}
    >
      {children}
    </p>
  );
}
