/**
 * @file ContentCard.tsx - Reusable Bootstrap card wrapper with optional collapsible header, title/subtitle, right-aligned header content, and flexible padding options.
 * Used throughout the application to wrap page sections in a consistent card layout.
 */

import { type FC, type ReactNode, useEffect, useRef, useState } from 'react';
import { Collapse, Nav } from 'react-bootstrap';
import { Icon } from './Icon.tsx';
import {
  getStoredCardExpanded,
  setStoredCardExpanded,
} from '../utils/localStorage.ts';
import { useTranslation } from 'react-i18next';

/**
 * Props for the ContentCard component.
 */
interface ContentCardProps {
  /** Either a structured header (title/subtitle/rightAlignedContent) or arbitrary ReactNode children to render inside the card header */
  headerContent?:
    | {
        title?: string;
        subtitle?: string;

        /** Additional ReactNode to display to the right of title/description, with optional setter function to disable child nodes (used when card is collapsible) */
        rightAlignedContent?: {
          content: ReactNode;
          setIsDisabled?: (disabled: boolean) => void;
        };
      }
    | { children: ReactNode };

  /** Whether the card is collapsible */
  collapsible?: boolean;

  /** Expansion state key for persisting expansion in localStorage */
  expansionStateKey?: string;

  /** Whether the card should have padding */
  padding?: boolean;

  /** Whether the card should fill the remaining container height */
  fillPage?: boolean;

  /** Child nodes to render inside card body */
  children: ReactNode;
}

/**
 * Bootstrap-style card component for wrapping page section content.
 * Automatically expands to fill page content when it is the last element and fillPage is enabled.
 */
export const ContentCard: FC<ContentCardProps> = ({
  headerContent,
  collapsible = false,
  expansionStateKey,
  padding = true,
  fillPage = false,
  children,
}) => {
  const divRef = useRef<HTMLDivElement>(null);
  // Track sibling position so the card can grow to fill remaining space
  const [isLastElement, setIsLastElement] = useState(false);
  const [isOnlyElement, setIsOnlyElement] = useState(false);

  // Restore persisted expansion state from localStorage, defaulting to expanded
  const [isExpanded, setIsExpanded] = useState(
    getStoredCardExpanded(expansionStateKey as string) ?? true
  );
  useEffect(() => {
    // Update stored expansion state
    if (expansionStateKey) {
      setStoredCardExpanded(expansionStateKey, isExpanded);
    }
    // Auto-disable rightAlignedContent if collapsed
    if (
      headerContent &&
      'rightAlignedContent' in headerContent &&
      headerContent.rightAlignedContent?.setIsDisabled
    ) {
      headerContent.rightAlignedContent.setIsDisabled(!isExpanded);
    }
  }, [isExpanded]);

  // Monitor parent container via MutationObserver to re-check sibling position when children change
  useEffect(() => {
    /**
     * Checks if the card is the last element within its parent.
     */
    const checkIfLastElement = () => {
      if (divRef.current && divRef.current.parentElement) {
        setIsLastElement(divRef.current.nextElementSibling === null);
      }
    };

    /**
     * Checks if the card is the only element within its parent.
     */
    const checkIfOnlyElement = () => {
      if (divRef.current && divRef.current.parentElement) {
        setIsOnlyElement(
          divRef.current.previousElementSibling === null &&
            divRef.current.nextElementSibling === null
        );
      }
    };

    checkIfLastElement();
    checkIfOnlyElement();

    const observer = new MutationObserver(() => {
      checkIfLastElement();
      checkIfOnlyElement();
    });

    if (divRef.current?.parentElement) {
      observer.observe(divRef.current.parentElement, { childList: true });
    }

    return () => observer.disconnect();
  });

  const { t } = useTranslation(undefined, {
    keyPrefix: 'components.content_card',
  });

  return (
    <>
      {
        // Right-aligned collapse/expand button for collapsible cards
        collapsible && (
          <Nav
            variant={'tabs'}
            defaultActiveKey={'collapseButton'}
            className={'justify-content-end border-bottom-0'}
          >
            <Nav.Item
              onClick={() => {
                setIsExpanded(!isExpanded);
              }}
            >
              <Nav.Link
                eventKey={'collapseButton'}
                className={'bg-white'}
                style={{
                  borderBottomColor:
                    'rgba(var(--bs-white-rgb),var(--bs-bg-opacity))',
                }}
              >
                <div
                  className={'d-flex align-items-center justify-content-center'}
                >
                  <span className={'me-1'}>
                    {isExpanded
                      ? `${t('collapse.expanded')}`
                      : `${t('collapse.default')}`}
                  </span>
                  <Icon
                    size={20}
                    iconName={isExpanded ? 'ArrowBarUp' : 'ArrowBarDown'}
                  />
                </div>
              </Nav.Link>
            </Nav.Item>
          </Nav>
        )
      }

      <div
        ref={divRef}
        className={`card border-dark ${isLastElement ? '' : 'mb-3'} ${fillPage && (isLastElement || isOnlyElement) && isExpanded ? 'flex-grow-1' : ''}`}
        style={collapsible ? { borderTopRightRadius: '0' } : undefined}
      >
        {
          // Title, subtitle, and rightAlignedContent
          headerContent &&
            ('title' in headerContent || 'subtitle' in headerContent) && (
              <div className={'card-header'}>
                <div
                  className={
                    'd-flex justify-content-between align-items-center'
                  }
                >
                  <div>
                    {headerContent.title && (
                      <h5 className={'text-bold lh-lg mb-0'}>
                        {headerContent.title}
                      </h5>
                    )}
                    {headerContent.subtitle && (
                      <div className={'card-subtitle text-muted lh-sm mb-2'}>
                        {headerContent.subtitle}
                      </div>
                    )}
                  </div>
                  {'rightAlignedContent' in headerContent &&
                    headerContent.rightAlignedContent?.content && (
                      <div className={'ms-2'}>
                        {headerContent.rightAlignedContent.content}
                      </div>
                    )}
                </div>
              </div>
            )
        }

        {
          // Child nodes in header
          headerContent && 'children' in headerContent && (
            <>{headerContent.children}</>
          )
        }

        {
          // Collapse handling
          collapsible && (
            <Collapse in={isExpanded}>
              <div>
                <div className={`card-body ${padding ? '' : 'p-0'}`}>
                  {children}
                </div>
              </div>
            </Collapse>
          )
        }

        {
          // Non-collapsible content
          !collapsible && (
            <div className={`card-body ${padding ? '' : 'p-0'}`}>
              {children}
            </div>
          )
        }
      </div>
    </>
  );
};
