import { Stack, useRouter } from 'expo-router';
import { useState } from 'react';
import { Pressable, StyleSheet, View } from 'react-native';

import { PreCaptureSheet, type PreCaptureResult } from '@/components/PreCaptureSheet';
import { ThemedText } from '@/components/themed-text';
import { ThemedView } from '@/components/themed-view';
import { MaxContentWidth, Spacing } from '@/constants/theme';
import { useTheme } from '@/hooks/use-theme';
import { useRecorder, type RecordingResult } from '@/hooks/useRecorder';
import { formatClock } from '@/lib/format';
import { useTranscribe } from '@/stores/transcribeStore';

export default function RecordScreen() {
  const theme = useTheme();
  const router = useRouter();
  const rec = useRecorder();
  const [pending, setPending] = useState<RecordingResult | null>(null);

  const onStop = async () => {
    const r = await rec.stop();
    if (r) setPending(r);
    else router.back();
  };

  const onStart = async (meta: PreCaptureResult) => {
    const r = pending;
    setPending(null);
    if (!r) return;
    const id = await useTranscribe.getState().start({ data: r.data, name: r.name }, meta);
    if (id) router.replace({ pathname: '/transcript/[id]', params: { id } });
    else router.back();
  };

  if (!rec.supported) {
    return (
      <ThemedView style={[styles.fill, styles.center]}>
        <Stack.Screen options={{ title: 'Record' }} />
        <ThemedText type="small" themeColor="textSecondary" style={styles.notice}>
          In-app recording is available in the browser for now. On mobile, use your phone&apos;s
          recorder and import the file (native live capture is coming).
        </ThemedText>
      </ThemedView>
    );
  }

  const recording = rec.status === 'recording';
  const paused = rec.status === 'paused';

  return (
    <ThemedView style={[styles.fill, styles.center]}>
      <Stack.Screen options={{ title: 'Record' }} />
      <View style={styles.stage}>
        <ThemedText style={styles.timer}>{formatClock(Math.floor(rec.elapsedMs / 1000))}</ThemedText>
        <ThemedText type="small" themeColor="textSecondary">
          {recording ? '● Recording — on your device' : paused ? 'Paused' : 'Ready to record'}
        </ThemedText>

        <View style={[styles.meterTrack, { backgroundColor: theme.backgroundElement }]}>
          <View
            style={[
              styles.meterFill,
              { width: `${Math.round((recording ? rec.level : 0) * 100)}%`, backgroundColor: '#e5484d' },
            ]}
          />
        </View>

        {rec.error && (
          <ThemedText type="small" style={styles.error}>{rec.error}</ThemedText>
        )}

        <View style={styles.controls}>
          {rec.status === 'idle' || rec.status === 'stopped' ? (
            <BigButton label="Start recording" color="#e5484d" onPress={() => void rec.start()} />
          ) : (
            <>
              {recording ? (
                <BigButton label="Pause" color={theme.backgroundElement} textColor={theme.text} onPress={rec.pause} />
              ) : (
                <BigButton label="Resume" color="#3c87f7" onPress={rec.resume} />
              )}
              <BigButton label="Stop & transcribe" color="#3c87f7" onPress={() => void onStop()} />
            </>
          )}
        </View>

        <ThemedText type="small" themeColor="textSecondary" style={styles.hint}>
          Keep this tab in front while recording. Everything stays on your device.
        </ThemedText>
      </View>

      <PreCaptureSheet
        visible={pending !== null}
        defaultTitle={defaultName()}
        onStart={(m) => void onStart(m)}
        onCancel={() => {
          setPending(null);
          router.back();
        }}
      />
    </ThemedView>
  );
}

function BigButton({
  label,
  color,
  textColor,
  onPress,
}: {
  label: string;
  color: string;
  textColor?: string;
  onPress: () => void;
}) {
  return (
    <Pressable onPress={onPress} style={({ pressed }) => [styles.btn, { backgroundColor: color, opacity: pressed ? 0.85 : 1 }]}>
      <ThemedText style={[styles.btnText, textColor ? { color: textColor } : styles.btnTextLight]}>{label}</ThemedText>
    </Pressable>
  );
}

function defaultName(): string {
  const d = new Date();
  const pad = (n: number) => String(n).padStart(2, '0');
  return `Lecture ${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
}

const styles = StyleSheet.create({
  fill: { flex: 1 },
  center: { alignItems: 'center', justifyContent: 'center' },
  stage: { width: '100%', maxWidth: MaxContentWidth, padding: Spacing.four, gap: Spacing.three, alignItems: 'center' },
  timer: { fontSize: 56, fontWeight: '700', fontVariant: ['tabular-nums'] },
  meterTrack: { width: '80%', height: 8, borderRadius: 4, overflow: 'hidden' },
  meterFill: { height: 8, borderRadius: 4 },
  controls: { flexDirection: 'row', gap: Spacing.two, marginTop: Spacing.three, flexWrap: 'wrap', justifyContent: 'center' },
  btn: { paddingVertical: Spacing.three, paddingHorizontal: Spacing.four, borderRadius: Spacing.three, alignItems: 'center' },
  btnText: { fontWeight: '700', fontSize: 16 },
  btnTextLight: { color: '#fff' },
  error: { color: '#e5484d' },
  notice: { padding: Spacing.four, textAlign: 'center', maxWidth: 480 },
  hint: { textAlign: 'center', marginTop: Spacing.two },
});
