import { Link, useFocusEffect, useRouter } from 'expo-router';
import { useCallback } from 'react';
import {
  ActivityIndicator,
  Platform,
  Pressable,
  ScrollView,
  StyleSheet,
  TextInput,
  View,
} from 'react-native';

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 { formatClock } from '@/lib/format';
import { MODELS } from '@/lib/models/catalog';
import { pickAudio } from '@/lib/pickAudio';
import type { TranscriptMeta } from '@/lib/db';
import { useTranscribe } from '@/stores/transcribeStore';
import { useTranscripts } from '@/stores/transcriptsStore';

export default function LibraryScreen() {
  const theme = useTheme();
  const router = useRouter();
  const { items, loading, query, setQuery, refresh, remove } = useTranscripts();
  const job = useTranscribe();

  // Refresh the list whenever the screen regains focus (e.g. after a transcribe).
  useFocusEffect(
    useCallback(() => {
      void refresh();
    }, [refresh]),
  );

  const busy = job.status === 'loading' || job.status === 'transcribing';

  const onNew = useCallback(async () => {
    if (busy) return;
    const picked = await pickAudio();
    if (!picked) return;
    const id = await useTranscribe.getState().start(picked, { title: picked.name });
    if (id) router.push({ pathname: '/transcript/[id]', params: { id } });
  }, [busy, router]);

  return (
    <ThemedView style={styles.fill}>
      <ScrollView contentContainerStyle={styles.content}>
        <View style={styles.headerRow}>
          <View style={styles.flex}>
            <ThemedText type="subtitle">Wisp</ThemedText>
            <ThemedText type="small" themeColor="textSecondary">
              Private transcription — runs on your device, nothing uploaded.
            </ThemedText>
          </View>
          <Link href="/settings" asChild>
            <Pressable hitSlop={10}>
              <ThemedText type="link" themeColor="textSecondary">
                ⚙ Settings
              </ThemedText>
            </Pressable>
          </Link>
        </View>

        <Pressable
          onPress={onNew}
          disabled={busy}
          style={({ pressed }) => [
            styles.newButton,
            { backgroundColor: '#3c87f7', opacity: busy ? 0.5 : pressed ? 0.85 : 1 },
          ]}>
          <ThemedText style={styles.newButtonText}>＋ New transcription</ThemedText>
        </Pressable>

        {busy && <ActiveJob />}
        {job.status === 'error' && (
          <ThemedView type="backgroundElement" style={styles.card}>
            <ThemedText type="smallBold">Transcription failed</ThemedText>
            <ThemedText type="small" themeColor="textSecondary">
              {job.error}
            </ThemedText>
          </ThemedView>
        )}

        <TextInput
          value={query}
          onChangeText={(t) => void setQuery(t)}
          placeholder="Search transcripts…"
          placeholderTextColor={theme.textSecondary}
          style={[styles.search, { color: theme.text, backgroundColor: theme.backgroundElement }]}
        />

        {loading && items.length === 0 ? (
          <ActivityIndicator style={styles.pad} />
        ) : items.length === 0 ? (
          <ThemedText type="small" themeColor="textSecondary" style={styles.pad}>
            {query ? 'No matches.' : 'No transcripts yet. Pick an audio or video file to begin.'}
          </ThemedText>
        ) : (
          items.map((t) => (
            <TranscriptRow key={t.id} item={t} onOpen={() => router.push({ pathname: '/transcript/[id]', params: { id: t.id } })} onDelete={() => void remove(t.id)} />
          ))
        )}
      </ScrollView>
    </ThemedView>
  );
}

function ActiveJob() {
  const { stage, progress, partial, cancel } = useTranscribe();
  const pct = Math.round(progress * 100);
  return (
    <ThemedView type="backgroundElement" style={styles.card}>
      <View style={styles.rowBetween}>
        <ThemedText type="smallBold">
          {stage === 'loading' ? 'Loading model…' : 'Transcribing…'} {pct}%
        </ThemedText>
        <Pressable onPress={cancel} hitSlop={8}>
          <ThemedText type="small" themeColor="textSecondary">Cancel</ThemedText>
        </Pressable>
      </View>
      <ProgressBar value={progress} />
      {partial.length > 0 && (
        <ThemedText type="small" themeColor="textSecondary" numberOfLines={3}>
          {partial.map((s) => s.text).join(' ')}
        </ThemedText>
      )}
    </ThemedView>
  );
}

function ProgressBar({ value }: { value: number }) {
  return (
    <View style={styles.track}>
      <View style={[styles.bar, { width: `${Math.max(2, Math.min(100, value * 100))}%` }]} />
    </View>
  );
}

function TranscriptRow({ item, onOpen, onDelete }: { item: TranscriptMeta; onOpen: () => void; onDelete: () => void }) {
  const date = new Date(item.createdAt).toLocaleDateString();
  return (
    <Pressable onPress={onOpen} style={({ pressed }) => [pressed && styles.pressed]}>
      <ThemedView type="backgroundElement" style={styles.card}>
        <View style={styles.rowBetween}>
          <ThemedText type="smallBold" numberOfLines={1} style={styles.flex}>
            {item.title}
          </ThemedText>
          <Pressable onPress={onDelete} hitSlop={8}>
            <ThemedText type="small" themeColor="textSecondary">✕</ThemedText>
          </Pressable>
        </View>
        <ThemedText type="small" themeColor="textSecondary">
          {date} · {formatClock(item.durationSec)} · {MODELS[item.modelId]?.label ?? item.modelId} · {item.segmentCount} segments
        </ThemedText>
      </ThemedView>
    </Pressable>
  );
}

const styles = StyleSheet.create({
  fill: { flex: 1 },
  content: {
    padding: Spacing.three,
    gap: Spacing.three,
    maxWidth: MaxContentWidth,
    width: '100%',
    alignSelf: 'center',
  },
  flex: { flex: 1 },
  headerRow: { flexDirection: 'row', alignItems: 'flex-start', gap: Spacing.two },
  newButton: { paddingVertical: Spacing.three, borderRadius: Spacing.three, alignItems: 'center' },
  newButtonText: { color: '#fff', fontWeight: '700', fontSize: 16 },
  card: { padding: Spacing.three, borderRadius: Spacing.three, gap: Spacing.two },
  rowBetween: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: Spacing.two },
  search: { borderRadius: Spacing.two, paddingHorizontal: Spacing.three, paddingVertical: Spacing.two, fontSize: 15 },
  track: { height: 6, borderRadius: 3, backgroundColor: '#88888833', overflow: 'hidden' },
  bar: { height: 6, borderRadius: 3, backgroundColor: '#3c87f7' },
  pad: { paddingVertical: Spacing.four, textAlign: 'center' },
  pressed: { opacity: 0.7 },
});
