import { Typography, Tooltip } from 'antd';
import { ArrowUpOutlined, ArrowDownOutlined, MinusOutlined } from '@ant-design/icons';
import { formatCurrency } from '@/lib/formatters';
import { accountingColors } from '@/styles/theme';
import { typography, getAmountColor } from '@/styles/designTokens';

const { Text } = Typography;

export type AmountType = 'debit' | 'credit' | 'neutral' | 'auto';

export interface AmountTextProps {
  /** The amount to display */
  amount: number;
  /** Override automatic color detection */
  type?: AmountType;
  /** Whether to show the sign (+/-) */
  showSign?: boolean;
  /** Whether to show currency suffix */
  showCurrency?: boolean;
  /** Currency suffix text */
  currencySuffix?: string;
  /** Text size variant */
  size?: 'small' | 'default' | 'large';
  /** Whether to use tabular (monospace) numbers */
  tabular?: boolean;
  /** Whether to show tooltip with full precision */
  showTooltip?: boolean;
  /** Show icon indicator for accessibility (not color-only) */
  showIcon?: boolean;
  /** Additional CSS class */
  className?: string;
  /** Inline style overrides */
  style?: React.CSSProperties;
}

/**
 * A consistent component for displaying monetary amounts.
 * Automatically colors based on value (positive = credit/green, negative = debit/red).
 *
 * @example
 * <AmountText amount={1234.56} />
 * <AmountText amount={-500} type="debit" showSign />
 * <AmountText amount={0} type="neutral" />
 */
export function AmountText({
  amount,
  type = 'auto',
  showSign = false,
  showCurrency = true,
  currencySuffix = 'kr.',
  size = 'default',
  tabular = true,
  showTooltip = false,
  showIcon = false,
  className,
  style,
}: AmountTextProps) {
  const getColor = (): string => {
    if (type === 'auto') {
      return getAmountColor(amount);
    }
    if (type === 'neutral') {
      return accountingColors.neutral;
    }
    return accountingColors[type];
  };

  const getFontSize = (): number => {
    switch (size) {
      case 'small':
        return typography.caption.fontSize;
      case 'large':
        return typography.h3.fontSize;
      default:
        return typography.body.fontSize;
    }
  };

  const formatAmount = (): string => {
    const formatted = formatCurrency(Math.abs(amount));
    // Always show +/- prefix for non-zero amounts (accessibility: not color-only)
    // When showSign is explicitly true, same behavior; kept for API compatibility
    const alwaysSign = showSign;
    const sign = alwaysSign && amount !== 0 ? (amount > 0 ? '+' : '-') : amount < 0 ? '-' : '';
    const suffix = showCurrency ? ` ${currencySuffix}` : '';

    return `${sign}${formatted}${suffix}`;
  };

  // Determine icon for accessibility (not relying on color alone)
  const getIcon = () => {
    if (!showIcon) return null;

    const effectiveType = type === 'auto'
      ? (amount > 0 ? 'credit' : amount < 0 ? 'debit' : 'neutral')
      : type;

    const iconStyle = { marginRight: 4, fontSize: getFontSize() - 2 };

    switch (effectiveType) {
      case 'credit':
        return <ArrowUpOutlined style={iconStyle} aria-label="Kredit" />;
      case 'debit':
        return <ArrowDownOutlined style={iconStyle} aria-label="Debet" />;
      default:
        return <MinusOutlined style={iconStyle} aria-label="Nul" />;
    }
  };

  const textStyle: React.CSSProperties = {
    color: getColor(),
    fontSize: getFontSize(),
    fontVariantNumeric: tabular ? 'tabular-nums' : undefined,
    ...style,
  };

  const content = (
    <Text className={className} style={textStyle}>
      {getIcon()}
      {formatAmount()}
    </Text>
  );

  if (showTooltip) {
    return (
      <Tooltip title={`${amount.toLocaleString('da-DK', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} ${currencySuffix}`}>
        {content}
      </Tooltip>
    );
  }

  return content;
}

/**
 * Displays a balance with label
 */
export interface BalanceDisplayProps {
  label: string;
  amount: number;
  showChange?: boolean;
  change?: number;
  size?: 'small' | 'default' | 'large';
}

export function BalanceDisplay({ label, amount, size = 'default' }: BalanceDisplayProps) {
  return (
    <div>
      <Text type="secondary" style={{ fontSize: typography.caption.fontSize }}>
        {label}
      </Text>
      <div>
        <AmountText amount={amount} size={size} />
      </div>
    </div>
  );
}

/**
 * Displays debit and credit columns for double-entry bookkeeping
 */
export interface DoubleEntryAmountProps {
  debit?: number;
  credit?: number;
  showZero?: boolean;
}

export function DoubleEntryAmount({ debit, credit, showZero = false }: DoubleEntryAmountProps) {
  const showDebit = debit !== undefined && (debit !== 0 || showZero);
  const showCredit = credit !== undefined && (credit !== 0 || showZero);

  return (
    <>
      <span style={{ display: 'inline-block', minWidth: 100, textAlign: 'right' }}>
        {showDebit && <AmountText amount={debit!} type="debit" showCurrency={false} />}
      </span>
      <span style={{ display: 'inline-block', minWidth: 100, textAlign: 'right', marginLeft: 16 }}>
        {showCredit && <AmountText amount={credit!} type="credit" showCurrency={false} />}
      </span>
    </>
  );
}

/**
 * Displays a running balance with optional delta indicator
 */
export interface RunningBalanceProps {
  balance: number;
  previousBalance?: number;
}

export function RunningBalance({ balance, previousBalance }: RunningBalanceProps) {
  const delta = previousBalance !== undefined ? balance - previousBalance : undefined;

  return (
    <span className="tabular-nums">
      <AmountText amount={balance} type="auto" />
      {delta !== undefined && delta !== 0 && (
        <Text
          type="secondary"
          style={{
            fontSize: typography.small.fontSize,
            marginLeft: 4,
            color: delta > 0 ? accountingColors.credit : accountingColors.debit,
          }}
        >
          ({delta > 0 ? '+' : ''}
          {formatCurrency(delta)})
        </Text>
      )}
    </span>
  );
}

export default AmountText;
