"use client";

import { useEffect, useRef, type ReactNode } from "react";
import { IconXCircle } from "@/components/icons";

type Size = "sm" | "md" | "lg" | "xl";

const SIZE_CLASS: Record<Size, string> = {
  sm: "max-w-sm",
  md: "max-w-md",
  lg: "max-w-2xl",
  xl: "max-w-5xl",
};

type Props = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  title?: string;
  description?: string;
  children?: ReactNode;
  footer?: ReactNode;
  size?: Size;
};

export function Dialog({
  open,
  onOpenChange,
  title,
  description,
  children,
  footer,
  size = "md",
}: Props) {
  const dialogRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!open) return;

    function handleKey(e: KeyboardEvent) {
      if (e.key === "Escape") {
        e.preventDefault();
        onOpenChange(false);
        return;
      }
      // Focus trap simple : tab cycle dans les éléments focusables du dialog
      if (e.key !== "Tab" || !dialogRef.current) return;
      const focusables = dialogRef.current.querySelectorAll<HTMLElement>(
        'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
      );
      if (focusables.length === 0) return;
      const first = focusables[0];
      const last = focusables[focusables.length - 1];
      if (e.shiftKey && document.activeElement === first) {
        e.preventDefault();
        last.focus();
      } else if (!e.shiftKey && document.activeElement === last) {
        e.preventDefault();
        first.focus();
      }
    }

    document.addEventListener("keydown", handleKey);
    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";

    // Focus le premier élément focusable
    requestAnimationFrame(() => {
      const first = dialogRef.current?.querySelector<HTMLElement>(
        'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
      );
      first?.focus();
    });

    return () => {
      document.removeEventListener("keydown", handleKey);
      document.body.style.overflow = previousOverflow;
    };
  }, [open, onOpenChange]);

  if (!open) return null;

  return (
    <div
      className="fixed inset-0 z-[90] flex items-center justify-center p-4 mf-fade-in"
      role="presentation"
    >
      <div
        className="absolute inset-0 bg-foreground/40 backdrop-blur-[2px]"
        onClick={() => onOpenChange(false)}
      />
      <div
        ref={dialogRef}
        role="dialog"
        aria-modal="true"
        aria-labelledby={title ? "mf-dialog-title" : undefined}
        aria-describedby={description ? "mf-dialog-desc" : undefined}
        className={`relative z-10 w-full ${SIZE_CLASS[size]} max-h-[90vh] flex flex-col rounded-xl bg-surface border border-border shadow-lg overflow-hidden`}
      >
        {(title || description) && (
          <div className="px-5 py-4 border-b border-border">
            {title && (
              <div className="flex items-start justify-between gap-3">
                <h2
                  id="mf-dialog-title"
                  className="text-base font-semibold tracking-tight text-foreground"
                >
                  {title}
                </h2>
                <button
                  type="button"
                  onClick={() => onOpenChange(false)}
                  aria-label="Fermer"
                  className="text-subtle-foreground hover:text-foreground transition-colors"
                >
                  <IconXCircle size={16} />
                </button>
              </div>
            )}
            {description && (
              <p
                id="mf-dialog-desc"
                className="mt-1 text-sm text-muted-foreground"
              >
                {description}
              </p>
            )}
          </div>
        )}
        {children && (
          <div className="flex-1 overflow-y-auto px-5 py-4 text-sm">
            {children}
          </div>
        )}
        {footer && (
          <div className="flex items-center justify-end gap-2 px-5 py-3 border-t border-border bg-surface-2">
            {footer}
          </div>
        )}
      </div>
    </div>
  );
}
