import { apiClient } from "./client";
import type { TranscriptViewResponse, TranscriptStatusData } from "@/types/api";
import { getAuthToken } from "@/lib/utils";

export type TranscriptViewResult =
  | { success: true; data: TranscriptStatusData; message?: string }
  | { success: false; data: null; message: string };

function formatTime(seconds: number): string {
  const h = Math.floor(seconds / 3600);
  const m = Math.floor((seconds % 3600) / 60);
  const s = Math.floor(seconds % 60);
  if (h > 0) return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
  return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
}

function getFileNameFromContentDisposition(disposition: string | null): string | null {
  if (!disposition) return null;

  const encodedFileName = disposition.match(/filename\*\s*=\s*UTF-8''([^;]+)/i)?.[1];
  if (encodedFileName) {
    try {
      return decodeURIComponent(encodedFileName.trim());
    } catch {
      return encodedFileName.trim();
    }
  }

  const fileName = disposition.match(/filename\s*=\s*(?:"([^"]+)"|([^;]+))/i);
  return fileName?.[1]?.trim() ?? fileName?.[2]?.trim() ?? null;
}

// GET /transcript-view/{meeting_id}
export async function getTranscriptView(meetingId: number): Promise<TranscriptViewResult> {
  const res = await apiClient.get<TranscriptViewResponse>(`/transcript-view/${meetingId}`);

  if (!res.success) {
    return {
      success: false,
      data: null,
      message: res.message ?? "Transcript is not available yet.",
    };
  }

  const { data } = res;

  const transcript = data.segments.map((seg) => ({
    speaker:         seg.speaker,
    speaker_label:   seg.speaker,
    text:            seg.text,
    start:           seg.start,
    end:             seg.end,
    start_formatted: formatTime(seg.start),
    end_formatted:   formatTime(seg.end),
  }));

  const duration_seconds = data.segments.length > 0
    ? Math.ceil(data.segments[data.segments.length - 1].end)
    : 0;

  // Use audio for playback and video for the download action.
  // These are pre-signed S3 URLs, so no auth header is needed.
  const audioUrl = data.recording?.audio_download_url ?? null;
  const videoUrl = data.recording?.video_download_url ?? data.video_download_url ?? null;
  const hasRecording = !!(audioUrl || videoUrl);

  const mapped: TranscriptStatusData = {
    transcript_id:   data.transcript_id,
    meeting_id:      data.meeting_id,
    status:          data.status as TranscriptStatusData["status"],
    language:        "auto",
    duration_seconds,
    error_message:   null,
    created_at:      new Date().toISOString(),
    completed_at:    new Date().toISOString(),
    participants:    data.participants,
    speaker_map:     data.speaker_map,
    transcript,
    full_text:       data.full_text,
    // Map recording into audio shape used by TranscriptViewer.
    audio: hasRecording ? {
      recording_id: data.transcript_id,
      status:       "done",
      file_name:    audioUrl ? `meeting_${data.meeting_id}.mp3` : "Audio recording unavailable",
      file_path:    "",
      content_type: "audio/mpeg",
      available:    !!audioUrl,
      download_url: "",        // not used for S3 flow
      direct_url:   audioUrl,  // pre-signed S3 URL used by playback
      download_direct_url: videoUrl ?? audioUrl,
      download_file_name: videoUrl ? `meeting_${data.meeting_id}.mp4` : undefined,
      download_content_type: videoUrl ? "video/mp4" : undefined,
    } : undefined,
  };

  return { success: true, data: mapped };
}

// Download transcript as PDF — GET /transcript-pdf/{meeting_id}
export async function downloadTranscriptPdf(meetingId: string): Promise<void> {
  const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL;
  const token = getAuthToken() || (typeof window !== "undefined" ? localStorage.getItem("auth_token") : null) || "";

  const res = await fetch(`${baseUrl}/transcript-pdf/${meetingId}`, {
    headers: {
      Authorization: `Bearer ${token}`,
      "ngrok-skip-browser-warning": "true",
    },
  });

  if (!res.ok) throw new Error("Failed to download PDF");

  const fileName = getFileNameFromContentDisposition(res.headers.get("content-disposition"));

  if (!fileName) {
    throw new Error(
      "PDF filename is missing from Content-Disposition. Backend must expose the Content-Disposition header."
    );
  }

  const blob = await res.blob();
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = fileName;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
}

// Download from a pre-signed S3 URL — no auth header needed
export async function downloadFromS3(s3Url: string, fileName: string): Promise<void> {
  const res = await fetch(s3Url);
  if (!res.ok) throw new Error("Failed to download recording");
  const blob = await res.blob();
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = fileName;
  a.click();
  URL.revokeObjectURL(url);
}

// Download via backend proxy (old flow — kept for backward compat)
export async function downloadRecordingAudio(downloadUrl: string, fileName: string): Promise<void> {
  const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL;
  const token = getAuthToken() || (typeof window !== "undefined" ? localStorage.getItem("auth_token") : null) || "";

  const res = await fetch(`${baseUrl}${downloadUrl}`, {
    headers: { Authorization: `Bearer ${token}` },
  });

  if (!res.ok) throw new Error("Failed to download audio");

  const blob = await res.blob();
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = fileName;
  a.click();
  URL.revokeObjectURL(url);
}
