import { useTranslation } from '@/hooks/useI18n.tsx';
import { clsx } from 'clsx';
import React from 'react';

export type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';

export type TranslationReplacements = Record<string, string | number>;

export interface HeadingProps extends Omit<React.HTMLAttributes<HTMLHeadingElement>, 'children'> {
  level?: HeadingLevel;
  as?: HeadingLevel;
  /** Translation key (e.g., 'dashboard.title') */
  tKey?: string;
  /** Translation replacements for interpolation (e.g., { name: 'John' }) */
  replacements?: TranslationReplacements;
  /** Direct text content (alternative to tKey) */
  children?: React.ReactNode;
  className?: string;
}

const headingStyles: Record<HeadingLevel, string> = {
  h1: 'font-serif text-2xl sm:text-3xl font-bold tracking-tight text-foreground',
  h2: 'text-2xl font-serif font-semibold text-foreground',
  h3: 'text-lg font-semibold text-foreground',
  h4: 'text-base font-semibold text-foreground',
  h5: 'text-sm font-semibold text-foreground',
  h6: 'text-xs font-semibold text-foreground',
};

/**
 * Heading component for semantic headings with consistent styling
 * Supports both translation keys and direct text content
 *
 * @example
 * <Heading tKey="dashboard.title" />
 * <Heading tKey="dashboard.greeting" replacements={{ name: 'John' }} />
 * <Heading level="h2">Direct Text</Heading>
 */
export const Heading = React.forwardRef<HTMLHeadingElement, HeadingProps>(
  ({ level = 'h1', as, tKey, replacements, children, className, ...props }, ref) => {
    const { t } = useTranslation();
    const Component = as || level;
    const baseStyles = headingStyles[level];

    // Use translation if tKey is provided, otherwise use children
    // If both are provided, tKey takes precedence
    const content = tKey ? t(tKey, replacements) : children;

    return (
      <Component ref={ref} className={clsx(baseStyles, className)} {...props}>
        {content}
      </Component>
    );
  }
);

Heading.displayName = 'Heading';

export type TextVariant = 'body' | 'small' | 'muted' | 'bold' | 'italic';

export interface TextProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {
  variant?: TextVariant;
  as?: 'p' | 'span' | 'div';
  /** Translation key (e.g., 'dashboard.description') */
  tKey?: string;
  /** Translation replacements for interpolation (e.g., { count: 5 }) */
  replacements?: TranslationReplacements;
  /** Direct text content (alternative to tKey) */
  children?: React.ReactNode;
  className?: string;
}

const textStyles: Record<TextVariant, string> = {
  body: 'text-base text-foreground',
  small: 'text-sm text-foreground',
  muted: 'text-sm text-muted-foreground',
  bold: 'text-base font-semibold text-foreground',
  italic: 'text-base text-muted-foreground italic',
};

/**
 * Text component for consistent text styling
 * Supports both translation keys and direct text content
 *
 * @example
 * <Text tKey="dashboard.description" />
 * <Text tKey="dashboard.itemsCount" replacements={{ count: 5 }} />
 * <Text variant="muted">Direct text content</Text>
 */
export const Text = React.forwardRef<HTMLElement, TextProps>(
  ({ variant = 'body', as = 'p', tKey, replacements, children, className, ...props }, ref) => {
    const { t } = useTranslation();
    const Component = as;
    const baseStyles = textStyles[variant];

    // Use translation if tKey is provided, otherwise use children
    // If both are provided, tKey takes precedence
    const content = tKey ? t(tKey, replacements) : children;

    return (
      <Component ref={ref as any} className={clsx(baseStyles, className)} {...props}>
        {content}
      </Component>
    );
  }
);

Text.displayName = 'Text';

export interface PriceProps {
  value: number;
  currency?: string;
  variant?: 'large' | 'medium' | 'small';
  showUnit?: boolean;
  /** Translation key for unit label (e.g., 'common.currency.unit') */
  unitTKey?: string;
  /** Direct unit text (alternative to unitTKey) */
  unit?: string;
  /** Use locale-aware number formatting based on current language */
  useLocale?: boolean;
  className?: string;
}

/**
 * Price component for displaying currency values with consistent formatting
 * Supports localized currency formatting and unit labels via translation keys
 *
 * @example
 * <Price value={99.99} currency="EUR" />
 * <Price value={99.99} showUnit unitTKey="common.currency.perUnit" />
 * <Price value={99.99} showUnit unit="per hour" />
 */
export const Price: React.FC<PriceProps> = ({
  value,
  currency = 'EUR',
  variant = 'large',
  showUnit = false,
  unitTKey,
  unit,
  useLocale = true,
  className,
}) => {
  const { t, lang } = useTranslation();

  // Get locale for number formatting (e.g., 'en-US', 'ru-RU', 'tt-TT')
  const localeMap: Record<string, string> = {
    en: 'en-US',
    ru: 'ru-RU',
    tt: 'tt-TT',
  };
  const locale = useLocale ? localeMap[lang] || 'en-US' : 'en-US';

  const formattedValue = new Intl.NumberFormat(locale, {
    style: 'currency',
    currency,
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  }).format(value);

  const sizeClasses = {
    large: 'text-2xl font-bold',
    medium: 'text-lg font-semibold',
    small: 'text-base font-medium',
  };

  // Get unit label from translation or use direct unit
  const unitLabel = unitTKey ? t(unitTKey) : unit;

  return (
    <span className={clsx(sizeClasses[variant], 'text-primary', className)}>
      {formattedValue}
      {showUnit && unitLabel && (
        <span className="text-sm text-muted-foreground ml-1">{unitLabel}</span>
      )}
    </span>
  );
};
