import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from "react";

const ToastlyContext = createContext();

const soundMap = {
  success: "/sounds/success.mp3",
  error: "/sounds/error.mp3",
  warning: "/sounds/warning.mp3",
  info: "/sounds/info.mp3",
};

export function ToastlyProvider({ children }) {
  const [toasts, setToasts] = useState([]);
  const timers = useRef(new Map());

  const playSound = (type) => {
    const soundPath = soundMap[type];
    if (soundPath) {
      const audio = new Audio(soundPath);
      audio.play().catch((e) => console.warn("Sound play failed:", e));
    }
  };

  const removeToast = useCallback((id) => {
    setToasts((prev) => prev.filter((t) => t.id !== id));
    timers.current.delete(id);
  }, []);

  const addToast = useCallback(({ type, message, content, duration = 3000 }) => {
    const id = Date.now() + Math.random();
    setToasts((prev) => [...prev, { id, type, message, content }]);
    playSound(type);

    const timerId = setTimeout(() => {
      removeToast(id);
    }, duration);

    timers.current.set(id, timerId);
  }, [removeToast]);

  // Clear timers on unmount to avoid leaks
  useEffect(() => {
    return () => {
      timers.current.forEach((timerId) => clearTimeout(timerId));
      timers.current.clear();
    };
  }, []);

  const success = (msg, opts = {}) => addToast({ type: "success", message: msg, ...opts });
  const error = (msg, opts = {}) => addToast({ type: "error", message: msg, ...opts });
  const warning = (msg, opts = {}) => addToast({ type: "warning", message: msg, ...opts });
  const info = (msg, opts = {}) => addToast({ type: "info", message: msg, ...opts });
  const custom = (content, opts = {}) => addToast({ type: "custom", content, ...opts });

  // Promise-based toast helper
  const promise = (promise, { loading, success: successMsg, error: errorMsg }) => {
    const id = Date.now() + Math.random();
    setToasts((prev) => [...prev, { id, type: "info", message: loading }]);
    playSound("info");

    return promise
      .then((res) => {
        removeToast(id);
        addToast({ type: "success", message: successMsg });
        return res;
      })
      .catch((err) => {
        removeToast(id);
        addToast({ type: "error", message: errorMsg });
        throw err;
      });
  };

  return (
    <ToastlyContext.Provider value={{ success, error, warning, info, custom, promise }}>
      {children}

      <div
        style={{
          position: "fixed",
          top: 10,
          right: 10,
          display: "flex",
          flexDirection: "column",
          gap: 10,
          zIndex: 9999,
          maxWidth: 320,
        }}
      >
        {toasts.map(({ id, type, message, content }) => (
          <div
            key={id}
            role="alert"
            aria-live="assertive"
            aria-atomic="true"
            style={{
              padding: "12px 20px",
              borderRadius: 8,
              color: "white",
              fontWeight: "bold",
              backgroundColor:
                type === "success"
                  ? "#4caf50"
                  : type === "error"
                  ? "#f44336"
                  : type === "warning"
                  ? "#ff9800"
                  : type === "info"
                  ? "#2196f3"
                  : "#555",
              boxShadow: "0 2px 6px rgba(0,0,0,0.3)",
              opacity: 0.9,
              animation: "slideIn 0.3s ease forwards",
            }}
          >
            {content || message}
          </div>
        ))}
      </div>

      <style>{`
        @keyframes slideIn {
          from {
            opacity: 0;
            transform: translateX(100%);
          }
          to {
            opacity: 0.9;
            transform: translateX(0);
          }
        }
      `}</style>
    </ToastlyContext.Provider>
  );
}

export function useToastly() {
  const context = useContext(ToastlyContext);
  if (!context) throw new Error("useToastly must be used within ToastlyProvider");
  return context;
}
