import React, { useMemo } from 'react'
import type { Color } from '../styles.js'
import { useFps, type FpsStats } from '../hooks/use-fps.js'
import Box from './Box.js'
import Text from './Text.js'

type FpsCounterProps = {
	/**
	 * Show detailed per-phase timing breakdown.
	 * @default false
	 */
	detailed?: boolean
	/**
	 * Rolling window for FPS calculation in milliseconds.
	 * @default 1000
	 */
	sampleWindowMs?: number
}

function fpsColor(fps: number): Color {
	if (fps >= 50) return 'ansi:green'
	if (fps >= 30) return 'ansi:yellow'
	return 'ansi:red'
}

function formatMs(ms: number): string {
	return ms < 1 ? '<1' : ms.toFixed(1)
}

/**
 * Displays real-time frame rate and render timing.
 *
 * Subscribes to Ink's frame events via `useFps` and shows:
 * - Current FPS (color-coded: green ≥50, yellow ≥30, red <30)
 * - Last frame duration
 * - Optionally: per-phase breakdown (renderer, diff, optimize, write, yoga)
 *
 * Usage:
 * ```tsx
 * <FpsCounter />
 * <FpsCounter detailed />
 * ```
 */
export function FpsCounter({
	detailed = false,
	sampleWindowMs,
}: FpsCounterProps): React.ReactNode {
	const stats = useFps(sampleWindowMs)

	if (detailed && stats.phases) {
		return <DetailedView stats={stats} />
	}

	return <CompactView stats={stats} />
}

const CompactView = React.memo(function CompactView({
	stats,
}: {
	stats: FpsStats
}) {
	const color = useMemo(() => fpsColor(stats.fps), [stats.fps])

	return (
		<Box gap={1}>
			<Text bold color={color}>
				{stats.fps.toFixed(0)} fps
			</Text>
			<Text dim>
				{formatMs(stats.lastFrameMs)}ms
			</Text>
			<Text dim>
				#{stats.totalFrames}
			</Text>
		</Box>
	)
})

const DetailedView = React.memo(function DetailedView({
	stats,
}: {
	stats: FpsStats
}) {
	const { phases } = stats
	if (!phases) return <CompactView stats={stats} />

	const color = useMemo(() => fpsColor(stats.fps), [stats.fps])

	return (
		<Box flexDirection="column">
			<Box gap={1}>
				<Text bold color={color}>
					{stats.fps.toFixed(0)} fps
				</Text>
				<Text dim>
					frame {formatMs(stats.lastFrameMs)}ms
				</Text>
				<Text dim>
					#{stats.totalFrames}
				</Text>
			</Box>
			<Box gap={1} paddingLeft={1}>
				<Text dim>render:</Text>
				<Text>{formatMs(phases.renderer)}ms</Text>
				<Text dim>diff:</Text>
				<Text>{formatMs(phases.diff)}ms</Text>
				<Text dim>write:</Text>
				<Text>{formatMs(phases.write)}ms</Text>
				<Text dim>yoga:</Text>
				<Text>{formatMs(phases.yoga)}ms</Text>
				<Text dim>patches:</Text>
				<Text>{phases.patches}</Text>
			</Box>
		</Box>
	)
})
