import { useEffect, useMemo, useState } from 'react'
import { useLocale } from '@meshkee/dashboard-ui'
import { ApiError } from '../lib/api'
import type {
  DailyActivityPoint,
  DualDailyActivityResponse,
} from '../services/dailyActivityService'
import { useT } from '../i18n/useT'
import type { BusinessMessageKey } from '../i18n/messages'
import styles from './DailyActivityChart.module.css'

const CHART_HEIGHT = 180
const BAR_GAP = 2

interface DailyActivityChartProps {
  titleKey: BusinessMessageKey
  subtitleKey: BusinessMessageKey
  primaryLegendKey: BusinessMessageKey
  secondaryLegendKey: BusinessMessageKey
  loadingKey: BusinessMessageKey
  errorKey: BusinessMessageKey
  primaryBarTitleKey: BusinessMessageKey
  secondaryBarTitleKey: BusinessMessageKey
  load: (signal: AbortSignal) => Promise<DualDailyActivityResponse>
}

function formatDayLabel(dateKey: string, locale: string): string {
  const [year, month, day] = dateKey.split('-').map(Number)
  const date = new Date(year, month - 1, day)
  return date.toLocaleString(locale === 'fa' ? 'fa-IR' : 'en-US', {
    day: 'numeric',
    numberingSystem: 'latn',
  })
}

export function DailyActivityChart({
  titleKey,
  subtitleKey,
  primaryLegendKey,
  secondaryLegendKey,
  loadingKey,
  errorKey,
  primaryBarTitleKey,
  secondaryBarTitleKey,
  load,
}: DailyActivityChartProps) {
  const t = useT()
  const { locale } = useLocale()
  const [primaryItems, setPrimaryItems] = useState<DailyActivityPoint[]>([])
  const [secondaryItems, setSecondaryItems] = useState<DailyActivityPoint[]>([])
  const [primaryTotal, setPrimaryTotal] = useState(0)
  const [secondaryTotal, setSecondaryTotal] = useState(0)
  const [isLoading, setIsLoading] = useState(true)
  const [error, setError] = useState('')

  useEffect(() => {
    const controller = new AbortController()

    async function run() {
      setIsLoading(true)
      setError('')
      try {
        const data = await load(controller.signal)
        if (controller.signal.aborted) return
        setPrimaryItems(data.primary.items)
        setSecondaryItems(data.secondary.items)
        setPrimaryTotal(data.primary.total)
        setSecondaryTotal(data.secondary.total)
      } catch (err) {
        if (err instanceof DOMException && err.name === 'AbortError') return
        if (err instanceof ApiError) {
          setError(err.message)
        } else {
          setError(t(errorKey))
        }
      } finally {
        if (!controller.signal.aborted) setIsLoading(false)
      }
    }

    void run()
    return () => controller.abort()
  }, [load, t, errorKey])

  const maxValue = useMemo(() => {
    const peak = Math.max(
      ...primaryItems.map((item) => item.count),
      ...secondaryItems.map((item) => item.count),
      0,
    )
    return peak > 0 ? peak : 1
  }, [primaryItems, secondaryItems])

  return (
    <section className={styles.card} aria-label={t(titleKey)}>
      <div className={styles.header}>
        <div>
          <h3 className={styles.title}>{t(titleKey)}</h3>
          <p className={styles.subtitle}>{t(subtitleKey)}</p>
        </div>
        <div className={styles.legend}>
          <span className={styles.legendItem}>
            <span className={`${styles.legendDot} ${styles.tonePrimary}`} />
            {t(primaryLegendKey, { count: primaryTotal })}
          </span>
          <span className={styles.legendItem}>
            <span className={`${styles.legendDot} ${styles.toneAccent}`} />
            {t(secondaryLegendKey, { count: secondaryTotal })}
          </span>
        </div>
      </div>

      {isLoading ? (
        <p className={styles.status}>{t(loadingKey)}</p>
      ) : error ? (
        <p className={styles.error} role="alert">
          {error}
        </p>
      ) : (
        <div className={styles.chartWrap}>
          <div
            className={styles.chart}
            style={{ height: CHART_HEIGHT + 28 }}
            role="img"
            aria-label={t(titleKey)}
          >
            {primaryItems.map((item, index) => {
              const secondary = secondaryItems[index]
              const secondaryCount = secondary?.count ?? 0
              const primaryHeight = (item.count / maxValue) * CHART_HEIGHT
              const secondaryHeight = (secondaryCount / maxValue) * CHART_HEIGHT
              const label = formatDayLabel(item.date, locale)

              return (
                <div key={item.date} className={styles.group}>
                  <div className={styles.bars} style={{ gap: BAR_GAP }}>
                    <div
                      className={`${styles.bar} ${styles.barPrimary}`}
                      style={{ height: Math.max(primaryHeight, item.count > 0 ? 4 : 0) }}
                      title={t(primaryBarTitleKey, { day: label, count: item.count })}
                    />
                    <div
                      className={`${styles.bar} ${styles.barAccent}`}
                      style={{
                        height: Math.max(secondaryHeight, secondaryCount > 0 ? 4 : 0),
                      }}
                      title={t(secondaryBarTitleKey, {
                        day: label,
                        count: secondaryCount,
                      })}
                    />
                  </div>
                  <span className={styles.label} lang="en" dir="ltr">
                    {label}
                  </span>
                </div>
              )
            })}
          </div>
        </div>
      )}
    </section>
  )
}
