import { Mic, Square } from "lucide-react";
import { useCallback, useEffect } from "react";
import { useAudioRecorder } from "@/hooks/useAudioRecorder";
import { useInferenceStore } from "@/store/inferenceStore";

/** Compact recorder. Playback + delete live in <NowPlaying />, so this
 * component only captures audio. UI state is derived from BOTH the
 * recorder hook AND the global store so the "recorded" indicator survives
 * tab switches that unmount this component. */
export default function MicRecorder() {
  const audio = useInferenceStore((s) => s.audio);
  const setAudio = useInferenceStore((s) => s.setAudio);
  const {
    state,
    start: startInternal,
    stop,
    reset,
    maxDurationMs,
  } = useAudioRecorder(15_000);

  const seconds = (state.durationMs / 1000).toFixed(1);

  // Push a fresh recording into the global audio source as soon as it lands.
  useEffect(() => {
    if (state.blob && state.objectUrl) {
      setAudio({
        kind: "recording",
        blob: state.blob,
        objectUrl: state.objectUrl,
      });
    }
  }, [state.blob, state.objectUrl, setAudio]);

  // If the user picks a different audio source elsewhere, free the recorder.
  useEffect(() => {
    if (audio?.kind !== "recording" && state.blob) {
      reset();
    }
  }, [audio, state.blob, reset]);

  // Wrap start: when the user re-records, immediately clear the previous
  // recording from the store so NowPlaying doesn't keep showing a stale
  // (and now revoked) blob URL while the new recording is in progress.
  const start = useCallback(async () => {
    if (audio?.kind === "recording") {
      setAudio(null);
    }
    await startInternal();
  }, [audio, setAudio, startInternal]);

  // The "recorded" indicator is true whenever either:
  //   • this component holds a freshly-stopped blob, OR
  //   • the global store already holds a recording (we may have just
  //     remounted via a tab switch and lost local state).
  const hasRecording = state.blob != null || audio?.kind === "recording";

  return (
    <div className="panel p-4">
      <div className="flex items-center justify-between gap-3">
        <div className="min-w-0">
          <div className="label">microphone</div>
          <div className="mt-1 truncate font-mono text-sm">
            {state.isRecording ? (
              <span className="text-danger">● rec {seconds} s</span>
            ) : hasRecording ? (
              <span className="text-cyber">
                ● recorded {state.blob ? `${seconds} s · ` : ""}
                play above
              </span>
            ) : (
              <span className="text-ink-dim">
                15 s max · grants browser mic permission
              </span>
            )}
          </div>
        </div>

        {state.isRecording ? (
          <button onClick={stop} className="btn-danger">
            <Square className="h-3.5 w-3.5" /> Stop
          </button>
        ) : (
          <button onClick={start} className="btn-primary">
            <Mic className="h-3.5 w-3.5" />
            {hasRecording ? "Re-record" : "Record"}
          </button>
        )}
      </div>

      {/* Recording progress bar (only meaningful while recording) */}
      <div className="mt-3 h-1 overflow-hidden rounded-full bg-surface-alt">
        <div
          className={`h-full transition-all ${
            state.isRecording ? "bg-danger/70" : "bg-cyber/40"
          }`}
          style={{
            width: state.isRecording
              ? `${(state.durationMs / maxDurationMs) * 100}%`
              : hasRecording
                ? "100%"
                : "0%",
          }}
        />
      </div>

      {state.error && (
        <div className="mt-2 font-mono text-xs text-danger">{state.error}</div>
      )}
    </div>
  );
}
