import { useEffect, useRef } from 'react';
import { Pressable, StyleSheet, Text, View } from 'react-native';
import { Mic } from 'lucide-react-native';
import {
  RecordingPresets,
  useAudioRecorder,
  useAudioRecorderState,
} from 'expo-audio';
import { logError } from '@/lib/errors';
import {
  acquireRecordingAudioSession,
  releaseRecordingAudioSession,
} from '@/lib/recording-audio-session';

const MAX_DURATION_S = 60;

interface AudioRecordingOverlayProps {
  onComplete: (result: { uri: string; durationMs: number }) => void;
  onCancel: () => void;
}

export function AudioRecordingOverlay({
  onComplete,
  onCancel,
}: AudioRecordingOverlayProps) {
  const recorder = useAudioRecorder(RecordingPresets.HIGH_QUALITY);
  const state = useAudioRecorderState(recorder, 250);
  const finalizedRef = useRef(false);

  useEffect(() => {
    let active = true;
    (async () => {
      try {
        await acquireRecordingAudioSession();
        await recorder.prepareToRecordAsync();
        if (!active) return;
        recorder.record();
      } catch (err) {
        logError(err, { scope: 'compose.audio.start' });
        if (active) onCancel();
      }
    })();

    return () => {
      active = false;
      if (!finalizedRef.current) {
        finalizedRef.current = true;
        recorder.stop().catch(() => {});
      }
      void releaseRecordingAudioSession().catch((err) =>
        logError(err, { scope: 'compose.audio.exit' }),
      );
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const elapsedMs = state.durationMillis ?? 0;

  const finish = async (kind: 'commit' | 'cancel') => {
    if (finalizedRef.current) return;
    finalizedRef.current = true;
    const durationMs = state.durationMillis ?? 0;
    try {
      await recorder.stop();
    } catch (err) {
      logError(err, { scope: 'compose.audio.stop' });
    }
    if (kind === 'cancel') {
      onCancel();
      return;
    }
    const uri = recorder.uri;
    if (!uri) {
      onCancel();
      return;
    }
    onComplete({ uri, durationMs });
  };

  // Auto-commit when we hit the max duration.
  useEffect(() => {
    if (elapsedMs >= MAX_DURATION_S * 1000 && !finalizedRef.current) {
      void finish('commit');
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [elapsedMs]);

  const elapsedSec = Math.floor(elapsedMs / 1000);

  return (
    <View
      style={StyleSheet.absoluteFill}
      className="bg-black items-center justify-center px-8"
    >
      <View className="bg-red-500/30 h-32 w-32 items-center justify-center rounded-full">
        <View className="bg-red-500/60 h-24 w-24 items-center justify-center rounded-full">
          <Mic color="white" size={42} strokeWidth={1.5} />
        </View>
      </View>
      <Text className="text-white mt-6 text-lg font-semibold">
        {state.isRecording ? 'Recording' : 'Starting…'}
      </Text>
      <Text className="text-white/60 mt-1 text-sm">
        {elapsedSec.toString().padStart(2, '0')}s · max {MAX_DURATION_S}s
      </Text>

      <View className="absolute inset-x-0 bottom-12 flex-row items-center justify-around px-8">
        <Pressable
          onPress={() => void finish('cancel')}
          accessibilityLabel="Cancel recording"
          className="rounded-full bg-white/15 px-6 py-3"
        >
          <Text className="text-white text-base font-medium">Cancel</Text>
        </Pressable>
        <Pressable
          onPress={() => void finish('commit')}
          accessibilityLabel="Stop recording"
          className="rounded-full bg-white px-7 py-3"
        >
          <Text className="text-black text-base font-semibold">Stop</Text>
        </Pressable>
      </View>
    </View>
  );
}
