import * as React from 'react';
import { Text as RNText, TextProps as RNTextProps } from 'react-native';
import { getColor } from './style-utils';

type TextFace = 'display' | 'title' | 'body' | 'paragraph' | 'caption';
type DisplaySize = 'small' | 'medium' | 'large' | 'xlarge';
type TitleSize = 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | '2xlarge';
type BodySize = 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | '2xlarge';
type ParagraphSize =
  | 'xsmall'
  | 'small'
  | 'medium'
  | 'large'
  | 'xlarge'
  | '2xlarge';
type CaptionSize = 'xsmall' | 'small' | 'medium';
type TextWeight =
  | 'thin'
  | 'light'
  | 'regular'
  | 'medium'
  | 'semibold'
  | 'bold'
  | 'extrabold';

type TextSize = ParagraphSize;

interface CustomTextProps {
  face: TextFace;
  size: TextSize;
  weight?: TextWeight;
  textColor?: string;
  children: any;
  className?: string;
  underline?: boolean;
  restProps?: any;
}

type TextProps = Omit<RNTextProps, 'style'> & CustomTextProps;

type TextSizeMap = {
  display: Record<DisplaySize, string>;
  title: Record<TitleSize, string>;
  body: Record<BodySize, string>;
  paragraph: Record<ParagraphSize, string>;
  caption: Record<CaptionSize, string>;
};

const PRIME_TEXT_FACE_PRESETS: TextSizeMap = {
  display: {
    small: 'text-prime-text-36',
    medium: 'text-prime-text-40',
    large: 'text-prime-text-48',
    xlarge: 'text-prime-text-56',
  },
  title: {
    xsmall: 'text-prime-text-16',
    small: 'text-prime-text-18',
    medium: 'text-prime-text-20',
    large: 'text-prime-text-22',
    xlarge: 'text-prime-text-24',
    '2xlarge': 'text-prime-text-28',
  },
  body: {
    xsmall: 'text-prime-text-13',
    small: 'text-prime-text-14',
    medium: 'text-prime-text-15',
    large: 'text-prime-text-16',
    xlarge: 'text-prime-text-18',
    '2xlarge': 'text-prime-text-20',
  },
  paragraph: {
    xsmall: 'text-prime-text-13',
    small: 'text-prime-text-14',
    medium: 'text-prime-text-15',
    large: 'text-prime-text-16',
    xlarge: 'text-prime-text-18',
    '2xlarge': 'text-prime-text-20',
  },
  caption: {
    xsmall: 'text-prime-text-10',
    small: 'text-prime-text-11',
    medium: 'text-prime-text-12',
  },
};

const WEIGHT_MAPPING: Record<TextWeight, string> = {
  thin: 'font-pretendard100',
  light: 'font-pretendard300',
  regular: 'font-pretendard400',
  medium: 'font-pretendard500',
  semibold: 'font-pretendard600',
  bold: 'font-pretendard700',
  extrabold: 'font-pretendard800',
};

export default function Text({
  face,
  size,
  weight = 'regular',
  textColor = 'black',
  children,
  className = '',
  underline = false,
  ...restProps
}: TextProps) {
  const preset = PRIME_TEXT_FACE_PRESETS[face][size];
  const weightClass = weight
    ? WEIGHT_MAPPING[weight]
    : WEIGHT_MAPPING['regular'];
  const colorClass = `${getColor(textColor)}`;
  const underlineClass = underline ? 'underline' : '';

  return (
    <RNText
      {...restProps}
      className={`${preset} ${weightClass} ${underlineClass} ${className}`.trim()}
      style={{ color: colorClass }}
    >
      {children}
    </RNText>
  );
}
