import React from 'react';
import Box from '@mui/material/Box';
import type { SxProps, Theme } from '@mui/material/styles';
import { Card } from '../../atoms/Card';
import { Collapse } from '../../atoms/Collapse';
import { Divider } from '../../atoms/Divider';
import { Typography } from '../../atoms/Typography';
import { Switch } from '../../atoms/Switch';
import { Link } from '../../atoms/Link';

// ─── Types ───────────────────────────────────────────────────────────────────

/** Props for the FA AddOnOption molecule */
export interface AddOnOptionProps {
  /** Add-on name/heading */
  name: string;
  /** Description text explaining the add-on */
  description?: string;
  /** Price in dollars — shown below the heading */
  price?: number;
  /** Custom price label (e.g. "Price on application") — overrides formatted price */
  priceLabel?: string;
  /** Whether this add-on is currently enabled */
  checked?: boolean;
  /** Called when the toggle changes */
  onChange?: (checked: boolean) => void;
  /** Whether this add-on is disabled/unavailable */
  disabled?: boolean;
  /** Max visible lines for description before "View more" toggle. Omit for no limit. */
  maxDescriptionLines?: number;
  /** Sub-options rendered inside the card when checked. Appears below a divider. */
  children?: React.ReactNode;
  /** MUI sx prop for style overrides */
  sx?: SxProps<Theme>;
}

// ─── Component ───────────────────────────────────────────────────────────────

/**
 * Toggleable add-on option for the FA design system.
 *
 * Used in the arrangement flow for optional extras — catering, memorial
 * video, flowers, transport upgrades, etc. Users toggle the switch to
 * include or exclude; multiple add-ons can be active simultaneously.
 *
 * Composes Card + Typography + Switch. Maps to the Figma
 * "ListItemAddItem" component (desktop + mobile viewports).
 *
 * For mutually exclusive options (single-select), use ServiceOption instead.
 *
 * Usage:
 * ```tsx
 * <AddOnOption
 *   name="Memorial video"
 *   description="Professional video tribute played during the service."
 *   price={350}
 *   checked={addOns.memorialVideo}
 *   onChange={(on) => setAddOns({ ...addOns, memorialVideo: on })}
 * />
 * ```
 */
export const AddOnOption = React.forwardRef<HTMLDivElement, AddOnOptionProps>(
  (
    {
      name,
      description,
      price,
      priceLabel,
      checked = false,
      onChange,
      disabled = false,
      maxDescriptionLines,
      children,
      sx,
    },
    ref,
  ) => {
    const switchId = React.useId();
    const [expanded, setExpanded] = React.useState(false);
    const [isClamped, setIsClamped] = React.useState(false);
    const descRef = React.useRef<HTMLElement>(null);

    // Detect whether the description is actually truncated
    React.useEffect(() => {
      const el = descRef.current;
      if (el && maxDescriptionLines) {
        setIsClamped(el.scrollHeight > el.clientHeight + 1);
      }
    }, [description, maxDescriptionLines]);

    const handleToggle = () => {
      if (!disabled && onChange) {
        onChange(!checked);
      }
    };

    const handleSwitchChange = (_e: React.ChangeEvent<HTMLInputElement>, value: boolean) => {
      if (onChange) {
        onChange(value);
      }
    };

    return (
      <Card
        ref={ref}
        interactive={!disabled}
        selected={checked}
        padding="none"
        onClick={handleToggle}
        aria-disabled={disabled || undefined}
        sx={[
          {
            p: 'var(--fa-card-padding-compact)',
            cursor: disabled ? 'not-allowed' : 'pointer',
            ...(disabled && {
              opacity: 'var(--fa-opacity-disabled)',
              pointerEvents: 'none' as const,
            }),
          },
          ...(Array.isArray(sx) ? sx : [sx]),
        ]}
      >
        {/* Top row: name + switch */}
        <Box
          sx={{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-between',
            gap: 2,
          }}
        >
          <Typography
            variant="h6"
            component="span"
            id={`${switchId}-label`}
            sx={{ flex: 1, minWidth: 0 }}
          >
            {name}
          </Typography>

          <Switch
            checked={checked}
            onChange={handleSwitchChange}
            disabled={disabled}
            onClick={(e) => e.stopPropagation()}
            inputProps={{ 'aria-labelledby': `${switchId}-label` }}
            sx={{ flexShrink: 0 }}
          />
        </Box>

        {/* Price — tucks directly under heading */}
        {priceLabel ? (
          <Typography variant="body2" color="primary" sx={{ fontStyle: 'italic' }}>
            {priceLabel}
          </Typography>
        ) : (
          price != null && (
            <Typography variant="body2" color="primary">
              ${price.toLocaleString('en-AU')}
            </Typography>
          )
        )}

        {/* Description with optional line clamping */}
        {description && (
          <>
            <Typography
              ref={descRef}
              variant="body2"
              color="text.secondary"
              sx={{
                mt: 0.5,
                ...(maxDescriptionLines &&
                  !expanded && {
                    display: '-webkit-box',
                    WebkitLineClamp: maxDescriptionLines,
                    WebkitBoxOrient: 'vertical',
                    overflow: 'hidden',
                  }),
              }}
            >
              {description}
            </Typography>
            {maxDescriptionLines && isClamped && (
              <Link
                component="button"
                variant="caption"
                onClick={(e: React.MouseEvent) => {
                  e.stopPropagation();
                  setExpanded((prev) => !prev);
                }}
                sx={{ mt: 0.5, color: 'text.secondary', fontWeight: 400 }}
              >
                {expanded ? 'View less' : 'View more'}
              </Link>
            )}
          </>
        )}

        {/* Sub-options — rendered inside the card when checked */}
        {children && (
          <Collapse in={checked}>
            <Divider sx={{ my: 1.5 }} />
            <Box onClick={(e) => e.stopPropagation()}>{children}</Box>
          </Collapse>
        )}
      </Card>
    );
  },
);

AddOnOption.displayName = 'AddOnOption';
export default AddOnOption;
