import React from 'react'

import { Card, CardBody, CardHeader } from '@brudi/react-panel'
import { twMerge } from 'tailwind-merge'

import BarGauge from './metric-card-bar-gauge'
import Footer from './metric-card-footer'

// TODO replace CardProps once from @brudi/react-panel
type CardProps = {
  className?: string
  hoverable?: boolean
}

export interface MetricCardProps extends CardProps {
  title: string | React.ReactNode
  value: number | React.ReactElement
  unit?: string
  locale?: string
  digits: number
  loading: boolean
}

const defaultProps = {
  className: '',
  locale: 'de-CH',
  digits: 2,
  loading: false
}

const Skeleton: React.FC<{ className?: string }> = ({ className }) => {
  return <div className={twMerge('h-3 w-6 bg-grayscale-3 dark:bg-grayscale-12', className)} />
}

type NativeAttrs = Omit<React.HTMLAttributes<any>, keyof MetricCardProps>
export type RowProps = MetricCardProps & typeof defaultProps & NativeAttrs

const Container: React.FC<React.PropsWithChildren<RowProps>> = ({
  children,
  title,
  value,
  unit,
  className,
  locale,
  digits,
  loading,
  ...props
}) => {
  const valueComponent = React.isValidElement(value)
    ? value
    : value.toLocaleString(locale, {
        maximumFractionDigits: digits
      })

  return (
    <Card className={className} {...props}>
      {title && <CardHeader>{loading ? <Skeleton className="w-6" /> : title}</CardHeader>}
      <CardBody>
        <div className="flex items-baseline">
          <span className="mr-1.5 text-[2.5rem]">{loading ? <Skeleton /> : valueComponent}</span>
          {!loading && unit && <span className="text-grayscale-11 text-lg">{unit}</span>}
        </div>
      </CardBody>
      {children && <div className="chart">{children}</div>}
    </Card>
  )
}

type MemoCardComponent<P> = React.NamedExoticComponent<P> & {
  BarGauge: typeof BarGauge
  Footer: typeof Footer
}
type ComponentProps = CardProps &
  Partial<typeof defaultProps> &
  Omit<MetricCardProps, keyof typeof defaultProps> &
  NativeAttrs

export default React.memo(Container) as MemoCardComponent<ComponentProps>
