'use client';

import * as React from 'react';
import clsx from 'clsx';
import {
  InformationCircleIcon,
  CheckCircleIcon,
  ExclamationTriangleIcon,
  XCircleIcon,
  XMarkIcon,
} from '@heroicons/react/20/solid';

export type AlertTone = 'info' | 'success' | 'warning' | 'error';

export interface AlertProps {
  /** Farbschema / Typ des Alerts */
  tone?: AlertTone;

  /** Überschrift (z.B. "Attention needed") */
  title?: React.ReactNode;

  /** Beschreibungstext (als string oder JSX) */
  description?: React.ReactNode;

  /** Bullet-List-Einträge wie im "With list"-Beispiel */
  listItems?: React.ReactNode[];

  /** Eigene Icon-Komponente (null = Icon komplett ausblenden) */
  icon?: React.ReactNode | null;

  /** Bereich für Buttons / Actions unter dem Text */
  actions?: React.ReactNode;

  /** Inhalt rechts (z.B. ein "Details →"-Link) */
  rightContent?: React.ReactNode;

  /** Linker Accent-Border (statt Outlines im Dark Mode) */
  accent?: boolean;

  /** Wenn gesetzt, wird ein Dismiss-X angezeigt und dieser Handler aufgerufen */
  onDismiss?: () => void;

  className?: string;
}

const toneConfig: Record<
  AlertTone,
  {
    bg: string;
    outline: string;
    accentBorder: string;
    title: string;
    text: string;
    icon: string;
    dismissBtn: string;
  }
> = {
  info: {
    bg: 'bg-blue-50 dark:bg-blue-500/10',
    outline: 'dark:outline dark:outline-blue-500/20',
    accentBorder: 'border-l-4 border-blue-400 dark:border-blue-500',
    title: 'text-blue-800 dark:text-blue-200',
    text: 'text-blue-700 dark:text-blue-300',
    icon: 'text-blue-400 dark:text-blue-300',
    dismissBtn:
      'inline-flex rounded-md bg-blue-50 p-1.5 text-blue-500 hover:bg-blue-100 ' +
      'focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 focus-visible:ring-offset-blue-50 focus-visible:outline-none ' +
      'dark:bg-transparent dark:text-blue-400 dark:hover:bg-blue-500/10 ' +
      'dark:focus-visible:ring-blue-500 dark:focus-visible:ring-offset-1 dark:focus-visible:ring-offset-blue-900',
  },
  success: {
    bg: 'bg-green-50 dark:bg-green-500/10',
    outline: 'dark:outline dark:outline-green-500/20',
    accentBorder: 'border-l-4 border-green-400 dark:border-green-500',
    title: 'text-green-800 dark:text-green-200',
    text: 'text-green-700 dark:text-green-200/85',
    icon: 'text-green-400 dark:text-green-300',
    dismissBtn:
      'inline-flex rounded-md bg-green-50 p-1.5 text-green-500 hover:bg-green-100 ' +
      'focus-visible:ring-2 focus-visible:ring-green-600 focus-visible:ring-offset-2 focus-visible:ring-offset-green-50 focus-visible:outline-none ' +
      'dark:bg-transparent dark:text-green-400 dark:hover:bg-green-500/10 ' +
      'dark:focus-visible:ring-green-500 dark:focus-visible:ring-offset-1 dark:focus-visible:ring-offset-green-900',
  },
  warning: {
    bg: 'bg-yellow-50 dark:bg-yellow-500/10',
    outline: 'dark:outline dark:outline-yellow-500/15',
    accentBorder: 'border-l-4 border-yellow-400 dark:border-yellow-500',
    title: 'text-yellow-800 dark:text-yellow-100',
    text: 'text-yellow-700 dark:text-yellow-100/80',
    icon: 'text-yellow-400 dark:text-yellow-300',
    dismissBtn:
      'inline-flex rounded-md bg-yellow-50 p-1.5 text-yellow-500 hover:bg-yellow-100 ' +
      'focus-visible:ring-2 focus-visible:ring-yellow-600 focus-visible:ring-offset-2 focus-visible:ring-offset-yellow-50 focus-visible:outline-none ' +
      'dark:bg-transparent dark:text-yellow-400 dark:hover:bg-yellow-500/10 ' +
      'dark:focus-visible:ring-yellow-500 dark:focus-visible:ring-offset-1 dark:focus-visible:ring-offset-yellow-900',
  },
  error: {
    bg: 'bg-red-50 dark:bg-red-500/15',
    outline: 'dark:outline dark:outline-red-500/25',
    accentBorder: 'border-l-4 border-red-400 dark:border-red-500',
    title: 'text-red-800 dark:text-red-200',
    text: 'text-red-700 dark:text-red-200/80',
    icon: 'text-red-400 dark:text-red-400',
    dismissBtn:
      'inline-flex rounded-md bg-red-50 p-1.5 text-red-500 hover:bg-red-100 ' +
      'focus-visible:ring-2 focus-visible:ring-red-600 focus-visible:ring-offset-2 focus-visible:ring-offset-red-50 focus-visible:outline-none ' +
      'dark:bg-transparent dark:text-red-400 dark:hover:bg-red-500/10 ' +
      'dark:focus-visible:ring-red-500 dark:focus-visible:ring-offset-1 dark:focus-visible:ring-offset-red-900',
  },
};

function getDefaultIcon(tone: AlertTone) {
  switch (tone) {
    case 'info':
      return (
        <InformationCircleIcon
          aria-hidden="true"
          className="size-5"
        />
      );
    case 'success':
      return (
        <CheckCircleIcon
          aria-hidden="true"
          className="size-5"
        />
      );
    case 'warning':
      return (
        <ExclamationTriangleIcon
          aria-hidden="true"
          className="size-5"
        />
      );
    case 'error':
      return (
        <XCircleIcon
          aria-hidden="true"
          className="size-5"
        />
      );
  }
}

function Alerts({
  tone = 'info',
  title,
  description,
  listItems,
  icon,
  actions,
  rightContent,
  accent = false,
  onDismiss,
  className,
}: AlertProps) {
  const cfg = toneConfig[tone];
  const hasList = !!listItems && listItems.length > 0;
  const showIcon = icon !== null;

  return (
    <div
      role="alert"
      className={clsx(
        'p-4',
        cfg.bg,
        accent ? cfg.accentBorder : 'rounded-md ' + cfg.outline,
        accent && 'rounded-none',
        className,
      )}
    >
      <div className="flex">
        {showIcon && (
          <div className="shrink-0">
            <span className={cfg.icon}>
              {icon ?? getDefaultIcon(tone)}
            </span>
          </div>
        )}

        <div
          className={clsx(
            'ml-3 flex-1',
            rightContent || onDismiss
              ? 'md:flex md:justify-between md:items-start'
              : undefined,
          )}
        >
          <div className="text-sm">
            {title && (
              <h3 className={clsx('font-medium', cfg.title)}>{title}</h3>
            )}

            {description && (
              <div className={clsx('mt-2', cfg.text)}>
                {typeof description === 'string' ? (
                  <p>{description}</p>
                ) : (
                  description
                )}
              </div>
            )}

            {hasList && (
              <div className={clsx(title || description ? 'mt-2' : undefined, cfg.text)}>
                <ul role="list" className="list-disc space-y-1 pl-5">
                  {listItems!.map((item, idx) => (
                    <li key={idx}>{item}</li>
                  ))}
                </ul>
              </div>
            )}

            {actions && <div className="mt-4">{actions}</div>}
          </div>

          {(rightContent || onDismiss) && (
            <div className="mt-3 md:mt-0 md:ml-6 flex items-start gap-2">
              {rightContent && <div className="text-sm">{rightContent}</div>}

              {onDismiss && (
                <button
                  type="button"
                  onClick={onDismiss}
                  className={cfg.dismissBtn}
                >
                  <span className="sr-only">Dismiss</span>
                  <XMarkIcon aria-hidden="true" className="size-5" />
                </button>
              )}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

export default Alerts;
