"use client";

import { useState } from "react";
import toast from "react-hot-toast";
import { csrfFetch, addCSRFTokenToFormData, getCSRFCookie, initializeCSRF } from "@/lib/csrf-client";
import { TRADES } from "@/lib/constants";
import type { Step, WorkerData } from "../types";
import { EXPERIENCE_OPTIONS } from "../types";

interface VoiceProcessingState {
  processing: boolean;
  status: string;
  error: string | null;
  transcript: string | null;
}

export function useVoiceProcessing(
  setSelectedTrades: (trades: string[]) => void,
  setExperience: (exp: number) => void,
  setSuburb: (suburb: string) => void,
  setAvailability: (availability: WorkerData["availability"]) => void,
  setStep: (step: Step) => void
) {
  const [voiceState, setVoiceState] = useState<VoiceProcessingState>({
    processing: false,
    status: "",
    error: null,
    transcript: null,
  });

  async function handleVoiceComplete(blob: Blob) {
    setVoiceState({
      processing: true,
      status: "Transcribing your voice...",
      error: null,
      transcript: null,
    });

    try {
      // Ensure CSRF token exists before making requests
      if (!getCSRFCookie()) {
        await initializeCSRF();
      }

      // Step 1: Transcribe (FormData with CSRF token)
      const formData = new FormData();
      formData.append("audio", blob, "recording.webm");
      addCSRFTokenToFormData(formData);

      const transcribeRes = await csrfFetch("/api/ai/transcribe-voice", {
        method: "POST",
        body: formData,
      });

      if (!transcribeRes.ok) {
        if (transcribeRes.status === 429) {
          throw new Error("Too many requests. Please wait a few minutes.");
        }
        const errData = await transcribeRes.json().catch(() => ({}));
        throw new Error(errData.error || "Failed to transcribe audio");
      }

      const { text } = await transcribeRes.json();
      if (!text) throw new Error("No speech detected. Please try again.");

      // Store the raw transcript for the bio generator
      setVoiceState(prev => ({ ...prev, transcript: text, status: "Understanding your details..." }));

      // Step 2: Parse profile fields (JSON with CSRF header)
      const parseRes = await csrfFetch("/api/ai/parse-profile-voice", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ transcript: text }),
      });

      if (!parseRes.ok) {
        const errData = await parseRes.json().catch(() => ({}));
        throw new Error(errData.error || "Failed to parse your details");
      }

      const parsed = await parseRes.json();

      // Pre-fill fields — handle multiple trades
      if (parsed.trades && parsed.trades.length > 0) {
        setSelectedTrades(parsed.trades);
      } else if (parsed.trade) {
        setSelectedTrades([parsed.trade]);
      }
      if (parsed.experience_years !== null && parsed.experience_years !== undefined) {
        // Find closest experience option
        const closest = EXPERIENCE_OPTIONS.reduce((prev, curr) =>
          Math.abs(curr.value - parsed.experience_years) < Math.abs(prev.value - parsed.experience_years) ? curr : prev
        );
        setExperience(closest.value);
      }
      if (parsed.location) setSuburb(parsed.location);
      if (parsed.availability) setAvailability(parsed.availability);

      // Check what we got and move to the right step
      setVoiceState(prev => ({ ...prev, status: "" }));

      const hasTrade = parsed.trades && parsed.trades.length > 0;
      const hasExp = parsed.experience_years !== null && parsed.experience_years !== undefined;
      const hasLoc = !!parsed.location;
      const hasAvail = !!parsed.availability;

      if (hasTrade && hasExp && hasLoc && hasAvail) {
        // All fields filled — go straight to review
        setStep("review");
      } else if (!hasTrade) {
        setStep("trade");
      } else if (!hasExp) {
        setStep("experience");
      } else if (!hasLoc) {
        setStep("location");
      } else {
        setStep("availability");
      }
    } catch (error) {
      setVoiceState(prev => ({
        ...prev,
        error: error instanceof Error ? error.message : "Something went wrong. Please try again.",
        status: "",
      }));
    } finally {
      setVoiceState(prev => ({ ...prev, processing: false }));
    }
  }

  return {
    voiceState,
    handleVoiceComplete,
  };
}