// frontend/src/components/Card.tsx

import type { ReactNode } from 'react'

type CardVariant =
  | 'basic'
  | 'edge-to-edge-mobile'
  | 'with-header'
  | 'with-footer'
  | 'with-header-footer'
  | 'with-gray-header'
  | 'with-gray-footer'
  | 'with-gray-header-footer'
  | 'gray-footer'
  | 'gray-body'
  | 'well'
  | 'well-on-gray'
  | 'well-edge-to-edge-mobile'

type CardHeaderVariant =
  | 'simple'
  | 'with-action'
  | 'with-description'
  | 'with-description-action'
  | 'with-avatar-actions'
  | 'with-avatar-meta-actions'
  | 'custom'

type CardProps = {
  children?: ReactNode
  header?: ReactNode
  footer?: ReactNode

  headerVariant?: CardHeaderVariant
  headerTitle?: ReactNode
  headerDescription?: ReactNode
  headerMeta?: ReactNode
  headerAction?: ReactNode
  headerActions?: ReactNode
  headerAvatar?: ReactNode

  variant?: CardVariant
  className?: string
  headerClassName?: string
  bodyClassName?: string
  footerClassName?: string
}

function classNames(...classes: Array<string | false | null | undefined>) {
  return classes.filter(Boolean).join(' ')
}

export default function Card({
  children,
  header,
  footer,

  headerVariant = 'custom',
  headerTitle,
  headerDescription,
  headerMeta,
  headerAction,
  headerActions,
  headerAvatar,

  variant = 'basic',
  className,
  headerClassName,
  bodyClassName,
  footerClassName,
}: CardProps) {
  const isEdgeToEdgeMobile =
    variant === 'edge-to-edge-mobile' || variant === 'well-edge-to-edge-mobile'

  const isWell =
    variant === 'well' ||
    variant === 'well-on-gray' ||
    variant === 'well-edge-to-edge-mobile'

  const hasGrayHeader =
    variant === 'with-gray-header' ||
    variant === 'with-gray-header-footer'

  const hasGrayFooter =
    variant === 'with-gray-footer' ||
    variant === 'with-gray-header-footer' ||
    variant === 'gray-footer'

  const hasDivider =
    variant === 'with-header' ||
    variant === 'with-footer' ||
    variant === 'with-header-footer' ||
    variant === 'with-gray-header' ||
    variant === 'with-gray-footer' ||
    variant === 'with-gray-header-footer'

  const renderedHeader = renderHeader()

  const hasHeader =
    Boolean(renderedHeader) &&
    (variant === 'with-header' ||
      variant === 'with-header-footer' ||
      variant === 'with-gray-header' ||
      variant === 'with-gray-header-footer' ||
      variant === 'gray-body')

  const hasFooter =
    Boolean(footer) &&
    (variant === 'with-footer' ||
      variant === 'with-header-footer' ||
      variant === 'with-gray-footer' ||
      variant === 'with-gray-header-footer' ||
      variant === 'gray-footer')

  function renderHeader() {
    if (header) {
      return header
    }

    if (!headerTitle && !headerDescription && !headerAction && !headerActions && !headerAvatar && !headerMeta) {
      return null
    }

    const actions = headerActions ?? headerAction

    if (headerVariant === 'with-action') {
      return (
        <div className="-mt-2 -ml-4 flex flex-wrap items-center justify-between sm:flex-nowrap">
          <div className="mt-2 ml-4 min-w-0">
            <h3 className="truncate text-base font-semibold text-gray-900 dark:text-white">
              {headerTitle}
            </h3>
          </div>

          {actions && (
            <div className="mt-2 ml-4 shrink-0">
              {actions}
            </div>
          )}
        </div>
      )
    }

    if (headerVariant === 'with-description-action') {
      return (
        <div className="-mt-4 -ml-4 flex flex-wrap items-center justify-between sm:flex-nowrap">
          <div className="mt-4 ml-4 min-w-0">
            <h3 className="truncate text-base font-semibold text-gray-900 dark:text-white">
              {headerTitle}
            </h3>

            {headerDescription && (
              <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
                {headerDescription}
              </p>
            )}
          </div>

          {actions && (
            <div className="mt-4 ml-4 shrink-0">
              {actions}
            </div>
          )}
        </div>
      )
    }

    if (headerVariant === 'with-description') {
      return (
        <>
          <h3 className="text-base font-semibold text-gray-900 dark:text-white">
            {headerTitle}
          </h3>

          {headerDescription && (
            <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
              {headerDescription}
            </p>
          )}
        </>
      )
    }

    if (headerVariant === 'with-avatar-actions') {
      return (
        <div className="-mt-4 -ml-4 flex flex-wrap items-center justify-between sm:flex-nowrap">
          <div className="mt-4 ml-4 min-w-0">
            <div className="flex items-center">
              {headerAvatar && (
                <div className="shrink-0">
                  {headerAvatar}
                </div>
              )}

              <div className={classNames(headerAvatar ? 'ml-4' : false, 'min-w-0')}>
                <h3 className="truncate text-base font-semibold text-gray-900 dark:text-white">
                  {headerTitle}
                </h3>

                {headerDescription && (
                  <p className="truncate text-sm text-gray-500 dark:text-gray-400">
                    {headerDescription}
                  </p>
                )}
              </div>
            </div>
          </div>

          {actions && (
            <div className="mt-4 ml-4 flex shrink-0">
              {actions}
            </div>
          )}
        </div>
      )
    }

    if (headerVariant === 'with-avatar-meta-actions') {
      return (
        <div className="flex space-x-3">
          {headerAvatar && (
            <div className="shrink-0">
              {headerAvatar}
            </div>
          )}

          <div className="min-w-0 flex-1">
            <p className="truncate text-sm font-semibold text-gray-900 dark:text-white">
              {headerTitle}
            </p>

            {headerMeta && (
              <p className="truncate text-sm text-gray-500 dark:text-gray-400">
                {headerMeta}
              </p>
            )}
          </div>

          {actions && (
            <div className="flex shrink-0 self-center">
              {actions}
            </div>
          )}
        </div>
      )
    }

    return (
      <h3 className="text-base font-semibold text-gray-900 dark:text-white">
        {headerTitle}
      </h3>
    )
  }

  return (
    <div
      className={classNames(
        'overflow-hidden',
        isEdgeToEdgeMobile ? 'sm:rounded-lg' : 'rounded-lg',
        isWell
          ? variant === 'well-on-gray'
            ? 'bg-gray-200 dark:bg-gray-800/50'
            : 'bg-gray-100 dark:bg-gray-800'
          : 'bg-white shadow-sm dark:bg-gray-800/50 dark:shadow-none dark:outline dark:-outline-offset-1 dark:outline-white/10',
        hasDivider && 'divide-y divide-gray-200 dark:divide-white/10',
        className,
      )}
    >
      {hasHeader && (
        <div
          className={classNames(
            'px-4 py-5 sm:px-6',
            hasGrayHeader && 'bg-gray-100 dark:bg-gray-800',
            headerClassName,
          )}
        >
          {renderedHeader}
        </div>
      )}

      <div
        className={classNames(
          'px-4 py-5 sm:p-6',
          variant === 'gray-body' && 'bg-gray-100 dark:bg-gray-800',
          bodyClassName,
        )}
      >
        {children}
      </div>

      {hasFooter && (
        <div
          className={classNames(
            'px-4 py-4 sm:px-6',
            hasGrayFooter && 'bg-gray-100 dark:bg-gray-800',
            footerClassName,
          )}
        >
          {footer}
        </div>
      )}
    </div>
  )
}