import { useEffect, useMemo, useState } from 'react'
import { AnimatePresence, motion } from 'framer-motion'
import { Plus, Pause, Play, Flame, Activity, TrendingUp } from 'lucide-react'
import { useAppStore } from '../store/appStore'
import { ExerciseCard } from '../components/ExerciseCard'
import { ExerciseEditor } from '../components/ExerciseEditor'
import { HistoryHeatmap } from '../components/HistoryHeatmap'
import { Button } from '../components/ui/Button'
import type { Exercise, HistoryEntry } from '@shared/types'
import { formatCountdown } from '../lib/format'
import { useT } from '../i18n'
import { currentStreak, dailyReps, todayKey } from '../lib/history'

export default function Dashboard(): JSX.Element {
  const state = useAppStore((s) => s.state)
  const ticks = useAppStore((s) => s.ticks)
  const [editorOpen, setEditorOpen] = useState(false)
  const [editing, setEditing] = useState<Exercise | null>(null)
  const { t, lang } = useT()

  const exercises = state?.exercises ?? []
  const settings = state?.settings
  const gamesEnabled = Object.values(state?.gamesEnabled ?? {}).some(Boolean)

  // Local history mirror; reloaded whenever app-state changes.
  const [history, setHistory] = useState<HistoryEntry[]>([])
  useEffect(() => {
    void window.api.getHistory().then(setHistory)
  }, [state])

  const todayDone = useMemo(
    () => dailyReps(history, exercises, todayKey()),
    [history, exercises]
  )
  const streak = useMemo(() => currentStreak(history), [history])

  const stats = useMemo(() => {
    const enabled = exercises.filter((e) => e.enabled)
    const next = enabled
      .map((e) => ({ id: e.id, ms: e.nextFireAt - Date.now() }))
      .sort((a, b) => a.ms - b.ms)[0]
    return {
      total: exercises.length,
      active: enabled.length,
      nextMs: next?.ms ?? Infinity,
      totalReps: enabled.reduce((s, e) => s + e.reps, 0)
    }
  }, [exercises, ticks])

  const paused = !settings?.globalEnabled

  function openCreate(): void {
    setEditing(null)
    setEditorOpen(true)
  }
  function openEdit(ex: Exercise): void {
    setEditing(ex)
    setEditorOpen(true)
  }
  async function handleSave(draft: {
    name: string
    reps: number
    icon: string
    intervalMinutes: number
    enabled: boolean
  }): Promise<void> {
    if (editing) await window.api.updateExercise(editing.id, draft)
    else await window.api.addExercise(draft)
    setEditorOpen(false)
  }
  async function togglePause(): Promise<void> {
    if (!settings) return
    await window.api.updateSettings({ globalEnabled: !settings.globalEnabled })
  }

  const today = new Date().toLocaleDateString(
    lang === 'en' ? 'en-US' : 'ru-RU',
    { weekday: 'long', day: 'numeric', month: 'long' }
  )

  return (
    <div className="h-full overflow-y-auto">
      <div className="max-w-5xl mx-auto px-4 sm:px-6 lg:px-10 pt-8 pb-12">
        <div className="flex flex-col sm:flex-row sm:items-end sm:justify-between gap-4 mb-8">
          <div className="min-w-0">
            <div className="text-[14px] text-text/65 font-semibold capitalize">
              {today}
            </div>
            <h1 className="font-serif text-[34px] sm:text-[40px] leading-[1.02] tracking-tight mt-1 font-bold">
              {t('dashboard.title')}
            </h1>
          </div>
          <div className="flex items-center gap-2">
            <Button variant="tinted" onClick={togglePause}>
              {!paused ? (
                <>
                  <Pause size={14} strokeWidth={2.5} /> {t('btn.pause')}
                </>
              ) : (
                <>
                  <Play size={14} strokeWidth={2.5} /> {t('btn.start')}
                </>
              )}
            </Button>
            <Button onClick={openCreate}>
              <Plus size={15} strokeWidth={2.5} /> {t('btn.add')}
            </Button>
          </div>
        </div>

        <div className="grid grid-cols-2 lg:grid-cols-4 gap-3 mb-8">
          <HeroStat
            tone="accent"
            label={t('dashboard.stat.today_done')}
            value={`${todayDone}`}
            subvalue={t('dashboard.stat.today_done.subtitle')}
            icon={<TrendingUp size={14} strokeWidth={2.6} />}
          />
          <HeroStat
            tone={streak > 0 ? 'warning' : 'muted'}
            label={t('dashboard.stat.streak')}
            value={`${streak}`}
            subvalue={t('dashboard.stat.streak.subtitle', { n: streak })}
            icon={<Flame size={14} strokeWidth={2.6} />}
          />
          <HeroStat
            tone="info"
            label={t('dashboard.stat.next')}
            value={
              stats.nextMs === Infinity
                ? '—'
                : stats.nextMs <= 0
                  ? t('dashboard.stat.next.now')
                  : formatCountdown(stats.nextMs, lang)
            }
            subvalue={
              paused
                ? t('dashboard.stat.next.subtitle_paused')
                : t('dashboard.stat.next.subtitle_running')
            }
            icon={<Activity size={14} strokeWidth={2.6} />}
          />
          <HeroStat
            tone={gamesEnabled ? 'success' : 'muted'}
            label={t('dashboard.stat.tracking')}
            value={
              gamesEnabled
                ? t('dashboard.stat.tracking.on')
                : t('dashboard.stat.tracking.off')
            }
            subvalue={
              gamesEnabled
                ? t('dashboard.stat.tracking.subtitle_on')
                : t('dashboard.stat.tracking.subtitle_off')
            }
            icon={
              <span
                className={[
                  'w-1.5 h-1.5 rounded-full',
                  gamesEnabled ? 'bg-white' : 'bg-text/30'
                ].join(' ')}
              />
            }
          />
        </div>

        {history.length > 0 && (
          <div className="mb-8">
            <HistoryHeatmap
              history={history}
              exercises={exercises}
              lang={lang}
            />
          </div>
        )}

        {paused && (
          <motion.div
            initial={{ opacity: 0, y: -4 }}
            animate={{ opacity: 1, y: 0 }}
            className="mb-6 rounded-2xl bg-warning/12 p-4 flex items-center gap-3"
          >
            <div className="w-10 h-10 rounded-xl bg-warning/18 text-warning grid place-items-center shrink-0">
              <Pause size={18} strokeWidth={2.5} />
            </div>
            <div className="flex-1 min-w-0">
              <div className="text-[16px] font-semibold leading-tight">
                {t('dashboard.paused.title')}
              </div>
              <div className="text-[14px] text-text/70 mt-1">
                {t('dashboard.paused.hint')}
              </div>
            </div>
            <Button variant="filled" size="sm" onClick={togglePause}>
              <Play size={14} strokeWidth={2.5} /> {t('btn.start')}
            </Button>
          </motion.div>
        )}

        <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-2 gap-4">
          <AnimatePresence>
            {exercises.map((ex) => (
              <ExerciseCard
                key={ex.id}
                exercise={ex}
                tick={ticks[ex.id]}
                onEdit={() => openEdit(ex)}
                onDelete={() => window.api.deleteExercise(ex.id)}
                onToggle={(v) => window.api.toggleExercise(ex.id, v)}
                onMarkDone={() => window.api.markDone(ex.id)}
              />
            ))}
          </AnimatePresence>
        </div>

        {exercises.length === 0 && (
          <div className="mt-12 text-center">
            <div className="inline-flex w-14 h-14 rounded-2xl bg-accent text-white items-center justify-center mb-4">
              <Plus size={24} strokeWidth={2.5} />
            </div>
            <div className="font-display text-[20px] font-semibold">
              {t('dashboard.empty.title')}
            </div>
            <p className="text-[14px] text-text/55 mt-1">
              {t('dashboard.empty.hint')}
            </p>
          </div>
        )}

        <ExerciseEditor
          open={editorOpen}
          exercise={editing}
          onClose={() => setEditorOpen(false)}
          onSave={handleSave}
        />
      </div>
    </div>
  )
}

function HeroStat({
  tone,
  label,
  value,
  subvalue,
  icon
}: {
  tone: 'accent' | 'info' | 'success' | 'warning' | 'muted'
  label: string
  value: string
  subvalue?: string
  icon?: React.ReactNode
}): JSX.Element {
  const toneBg =
    tone === 'accent'
      ? 'bg-accent'
      : tone === 'info'
        ? 'bg-info'
        : tone === 'success'
          ? 'bg-success'
          : tone === 'warning'
            ? 'bg-warning'
            : 'bg-text/40'

  return (
    <div className="bg-surface rounded-2xl p-5 shadow-card dark:ring-0.5 dark:ring-hairline/30">
      <div className="flex items-center gap-2 mb-3">
        <div
          className={[
            'w-7 h-7 rounded-lg grid place-items-center text-white',
            toneBg
          ].join(' ')}
        >
          {icon}
        </div>
        <div className="text-[14px] text-text/75 font-semibold">{label}</div>
      </div>
      <div className="font-display text-[28px] font-bold tracking-tight leading-none">
        {value}
      </div>
      {subvalue && (
        <div className="text-[13px] text-text/60 mt-2 font-medium">
          {subvalue}
        </div>
      )}
    </div>
  )
}
