// @File: src/lib/dhlApi.ts
// @Desc: Typed fetch wrappers for the DHL shipping admin endpoints and the
//        public customer tracking endpoint. Mirrors the conventions in
//        uptimerobotApi.ts.
import { getToken } from "@/lib/auth";

function authHeaders(): HeadersInit {
  const token = getToken();
  return {
    "Content-Type": "application/json",
    ...(token ? { Authorization: `Bearer ${token}` } : {}),
  };
}

async function handle<T>(res: Response): Promise<T> {
  const raw = await res.text();
  let data: unknown = null;
  if (raw) {
    try {
      data = JSON.parse(raw);
    } catch {
      data = raw;
    }
  }
  if (!res.ok) {
    const detail =
      (data && typeof data === "object" && "detail" in (data as Record<string, unknown>)
        ? String((data as Record<string, unknown>).detail)
        : null) ||
      res.statusText ||
      "Request failed";
    throw new Error(detail);
  }
  return data as T;
}

// ---------- types ----------
export interface DhlSettings {
  api_key: string | null;
  api_secret: string | null;
  account_number: string | null;
  environment: "sandbox" | "production" | string;
  configured: boolean;
}

export interface DhlSettingsUpdate {
  api_key?: string | null;
  api_secret?: string | null;
  account_number?: string | null;
  environment?: "sandbox" | "production" | string;
}

export interface DhlTestResult {
  ok: boolean;
  stub: boolean;
  message: string;
}

export interface DhlShipmentResult {
  order_id: number;
  tracking_number: string;
  label_url: string | null;
  stub: boolean;
  message: string;
}

export interface DhlTrackingEvent {
  timestamp: string | null;
  description: string;
  location: string | null;
}

export interface DhlTrackingResult {
  tracking_number: string;
  status: string;
  stub: boolean;
  message: string;
  events: DhlTrackingEvent[];
  order?: {
    order_number?: string;
    status?: string;
    total?: number;
    currency?: string;
  } | null;
}

// ---------- admin endpoints ----------
export async function adminGetDhlSettings(): Promise<DhlSettings> {
  const res = await fetch("/api/v1/admin/dhl/settings", { headers: authHeaders() });
  return handle<DhlSettings>(res);
}

export async function adminSaveDhlSettings(
  update: DhlSettingsUpdate
): Promise<DhlSettings> {
  const res = await fetch("/api/v1/admin/dhl/settings", {
    method: "PUT",
    headers: authHeaders(),
    body: JSON.stringify(update),
  });
  return handle<DhlSettings>(res);
}

export async function adminTestDhlConnection(): Promise<DhlTestResult> {
  const res = await fetch("/api/v1/admin/dhl/settings/test", {
    method: "POST",
    headers: authHeaders(),
  });
  return handle<DhlTestResult>(res);
}

export async function adminCreateDhlShipment(
  orderId: number
): Promise<DhlShipmentResult> {
  const res = await fetch(`/api/v1/admin/dhl/orders/${orderId}/ship`, {
    method: "POST",
    headers: authHeaders(),
  });
  return handle<DhlShipmentResult>(res);
}

// ---------- notifications (admin) ----------
export interface DhlNotification {
  id: number;
  order_id: number | null;
  order_number: string | null;
  tracking_number: string;
  recipient_email: string;
  previous_status: string | null;
  new_status: string;
  event_description: string | null;
  event_location: string | null;
  event_timestamp: string | null;
  success: boolean;
  error_message: string | null;
  stub: boolean;
  created_at: string | null;
}

export interface DhlNotificationList {
  items: DhlNotification[];
}

export interface DhlNotificationCheckResult {
  sent: boolean;
  reason: string;
  status: string | null;
  previous_status: string | null;
  tracking_number: string | null;
  recipient: string | null;
  notification_id: number | null;
  error: string | null;
  stub: boolean | null;
}

export interface AdminListNotificationsParams {
  order_id?: number;
  tracking_number?: string;
  success?: boolean;
  limit?: number;
}

export async function adminListDhlNotifications(
  params: AdminListNotificationsParams = {}
): Promise<DhlNotificationList> {
  const qs = new URLSearchParams();
  if (params.order_id != null) qs.set("order_id", String(params.order_id));
  if (params.tracking_number) qs.set("tracking_number", params.tracking_number.trim());
  if (params.success != null) qs.set("success", params.success ? "true" : "false");
  if (params.limit) qs.set("limit", String(params.limit));
  const url =
    "/api/v1/admin/dhl/notifications" + (qs.toString() ? `?${qs.toString()}` : "");
  const res = await fetch(url, { headers: authHeaders() });
  return handle<DhlNotificationList>(res);
}

export async function adminCheckDhlTracking(
  orderId: number,
  force = false
): Promise<DhlNotificationCheckResult> {
  const qs = force ? "?force=true" : "";
  const res = await fetch(
    `/api/v1/admin/dhl/orders/${orderId}/check-tracking${qs}`,
    { method: "POST", headers: authHeaders() }
  );
  return handle<DhlNotificationCheckResult>(res);
}

// ---------- public endpoint ----------
export async function trackShipment(
  trackingNumber: string
): Promise<DhlTrackingResult> {
  const res = await fetch(
    `/api/v1/shop/tracking/${encodeURIComponent(trackingNumber.trim())}`,
    { headers: { "Content-Type": "application/json" } }
  );
  return handle<DhlTrackingResult>(res);
}

export interface PublicShipmentNotification {
  previous_status: string | null;
  new_status: string;
  event_description: string | null;
  event_location: string | null;
  event_timestamp: string | null;
  sent: boolean;
  recipient_masked: string | null;
  created_at: string | null;
}

export interface PublicShipmentNotificationList {
  items: PublicShipmentNotification[];
}

export async function getShipmentNotifications(
  trackingNumber: string
): Promise<PublicShipmentNotificationList> {
  const res = await fetch(
    `/api/v1/shop/tracking/${encodeURIComponent(
      trackingNumber.trim()
    )}/notifications`,
    { headers: { "Content-Type": "application/json" } }
  );
  return handle<PublicShipmentNotificationList>(res);
}