import { UploadAudioResponse, TranscribeFileResponse } from "@/types/api";
import { useToastStore } from "@/store/toast.store";
import { getAuthToken } from "@/lib/utils";

const BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? "";

function getToken(): string | null {
  return getAuthToken() || (typeof window !== "undefined" ? localStorage.getItem("auth_token") : null);
}

function handleUnauthorized() {
  sessionStorage.removeItem("auth_token");
  localStorage.removeItem("auth_token");
  document.cookie = "auth_token=; path=/; max-age=0";
  window.location.href = "/login";
}

function showUploadToast(variant: "success" | "error", message: string) {
  useToastStore.getState().add({
    variant,
    title: variant === "success" ? "Success" : "Error",
    description: message,
  });
}

// ─── POST /upload-audio — multipart/form-data (file + title) ─────────────────
export async function uploadAudio(
  file: File,
  title: string,
  onProgress?: (percent: number) => void
): Promise<UploadAudioResponse> {
  const token = getToken();
  const formData = new FormData();
  formData.append("audio_file", file);
  formData.append("title", title);

  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();

    xhr.upload.addEventListener("progress", (e) => {
      if (e.lengthComputable && onProgress) {
        onProgress(Math.round((e.loaded / e.total) * 100));
      }
    });

    xhr.addEventListener("load", () => {
      if (xhr.status === 401) { handleUnauthorized(); return; }
      try {
        const data = JSON.parse(xhr.responseText);
        const message = data?.message ?? `Upload failed with status ${xhr.status}`;
        if (xhr.status >= 200 && xhr.status < 300) {
          if (typeof data?.success === "boolean" && data.message) {
            showUploadToast(data.success ? "success" : "error", data.message);
          }
          resolve(data);
        } else {
          showUploadToast("error", message);
          reject(new Error(message));
        }
      } catch {
        showUploadToast("error", "Invalid response from server");
        reject(new Error("Invalid response from server"));
      }
    });

    xhr.addEventListener("error", () => {
      showUploadToast("error", "Network error — upload failed");
      reject(new Error("Network error — upload failed"));
    });
    xhr.addEventListener("abort", () => {
      showUploadToast("error", "Upload cancelled");
      reject(new Error("Upload cancelled"));
    });

    xhr.open("POST", `${BASE_URL}/upload-audio`);
    if (token) xhr.setRequestHeader("Authorization", `Bearer ${token}`);
    xhr.setRequestHeader("ngrok-skip-browser-warning", "true");
    xhr.send(formData);
  });
}

// ─── POST /transcribe-file — multipart/form-data (file only) ─────────────────
// Returns transcript directly in the response — no polling needed
export async function transcribeFile(
  file: File,
  onProgress?: (percent: number) => void
): Promise<TranscribeFileResponse> {
  const token = getToken();
  const formData = new FormData();
  formData.append("file", file);   // key is "file" per API spec

  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();

    xhr.upload.addEventListener("progress", (e) => {
      if (e.lengthComputable && onProgress) {
        onProgress(Math.round((e.loaded / e.total) * 100));
      }
    });

    xhr.addEventListener("load", () => {
      if (xhr.status === 401) { handleUnauthorized(); return; }
      try {
        const data = JSON.parse(xhr.responseText);
        const message = data?.message ?? data?.detail ?? `Transcription failed with status ${xhr.status}`;
        if (xhr.status >= 200 && xhr.status < 300) {
          if (typeof data?.success === "boolean" && data.message) {
            showUploadToast(data.success ? "success" : "error", data.message);
          }
          resolve(data);
        } else {
          showUploadToast("error", message);
          reject(new Error(message));
        }
      } catch {
        showUploadToast("error", "Invalid response from server");
        reject(new Error("Invalid response from server"));
      }
    });

    xhr.addEventListener("error", () => {
      showUploadToast("error", "Network error — transcription failed");
      reject(new Error("Network error — transcription failed"));
    });
    xhr.addEventListener("abort", () => {
      showUploadToast("error", "Transcription cancelled");
      reject(new Error("Transcription cancelled"));
    });

    xhr.open("POST", `${BASE_URL}/transcribe-file`);
    if (token) xhr.setRequestHeader("Authorization", `Bearer ${token}`);
    xhr.setRequestHeader("ngrok-skip-browser-warning", "true");
    xhr.send(formData);
  });
}
