"use client";

import { NEXT_PUBLIC_API_URL } from "@/config/api";
import { UserResult } from "./index";

export const exportUserQrCode = async (userIds: number[]): Promise<{ blobValue: Uint8Array; filename: string }> => {

  const token = localStorage.getItem("accessToken");
  
  const response = await fetch(`${NEXT_PUBLIC_API_URL}/user/export-qrcode`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      ...(token && { Authorization: `Bearer ${token}` }),
    },
    body: JSON.stringify({ userIds }),
  });

  if (!response.ok) {
    if (response.status === 401) {
      throw new Error("Unauthorized: Please log in again");
    }
    throw new Error(`Failed to export QR code: ${response.status} ${response.statusText}`);
  }

  const filename = response.headers.get("Content-Disposition")?.split("filename=")[1]?.replace(/"/g, "") || "user_qrcode.pdf";
  
  const blob = await response.blob();
  const arrayBuffer = await blob.arrayBuffer();
  const blobValue = new Uint8Array(arrayBuffer);

  return { blobValue, filename };
};

export interface PrintUserQrCodeRequest {
  userIds: number[];
  printerId: number;
  printQty?: number;
}

export const printUserQrCode = async (data: PrintUserQrCodeRequest): Promise<void> => {
  const token = localStorage.getItem("accessToken");

  const response = await fetch(`${NEXT_PUBLIC_API_URL}/user/print-qrcode`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      ...(token && { Authorization: `Bearer ${token}` }),
    },
    body: JSON.stringify(data),
  });

  if (!response.ok) {
    if (response.status === 401) {
      throw new Error("Unauthorized: Please log in again");
    }
    throw new Error(`Failed to print QR code: ${response.status} ${response.statusText}`);
  }
};

export const searchUsersByUsernameOrName = async (searchTerm: string): Promise<UserResult[]> => {
  if (!searchTerm.trim()) {
    return [];
  }

  const token = localStorage.getItem("accessToken");
  
  const [usernameResults, nameResults] = await Promise.all([
    fetch(`${NEXT_PUBLIC_API_URL}/user?username=${encodeURIComponent(searchTerm)}`, {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
        ...(token && { Authorization: `Bearer ${token}` }),
      },
    }).then(res => {
      if (!res.ok) {
        if (res.status === 401) {
          throw new Error("Unauthorized: Please log in again");
        }
        throw new Error("Failed to search by username");
      }
      return res.json();
    }),
    fetch(`${NEXT_PUBLIC_API_URL}/user?name=${encodeURIComponent(searchTerm)}`, {
      method: "GET",
      headers: {
        "Content-Type": "application/json",
        ...(token && { Authorization: `Bearer ${token}` }),
      },
    }).then(res => {
      if (!res.ok) {
        if (res.status === 401) {
          throw new Error("Unauthorized: Please log in again");
        }
        throw new Error("Failed to search by name");
      }
      return res.json();
    }),
  ]);

  const mergedResults = [...usernameResults, ...nameResults];
  const uniqueResults = mergedResults.filter(
    (user, index, self) => index === self.findIndex((u) => u.id === user.id)
  );

  return uniqueResults;
};

export const searchUsers = async (searchParams: {
  username?: string;
  name?: string;
  staffNo?: string;
}): Promise<UserResult[]> => {
  const token = localStorage.getItem("accessToken");
  
  const params = new URLSearchParams();
  if (searchParams.username) params.append("username", searchParams.username);
  if (searchParams.name) params.append("name", searchParams.name);
  if (searchParams.staffNo) params.append("staffNo", searchParams.staffNo);
  
  const response = await fetch(`${NEXT_PUBLIC_API_URL}/user?${params.toString()}`, {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      ...(token && { Authorization: `Bearer ${token}` }),
    },
  });

  if (!response.ok) {
    if (response.status === 401) {
      throw new Error("Unauthorized: Please log in again");
    }
    throw new Error(`Failed to search users: ${response.status} ${response.statusText}`);
  }

  return response.json();
};

export interface UpdateUserRequest {
  username: string;
  name: string;
  staffNo?: string;
  locked?: boolean;
  addAuthIds?: number[];
  removeAuthIds?: number[];
}

export const updateUser = async (
  id: number,
  data: UpdateUserRequest,
): Promise<void> => {
  const token = localStorage.getItem("accessToken");

  const response = await fetch(`${NEXT_PUBLIC_API_URL}/user/${id}`, {
    method: "PUT",
    headers: {
      "Content-Type": "application/json",
      ...(token && { Authorization: `Bearer ${token}` }),
    },
    body: JSON.stringify(data),
  });

  if (!response.ok) {
    if (response.status === 401) {
      throw new Error("Unauthorized: Please log in again");
    }
    throw new Error(`Failed to update user: ${response.status} ${response.statusText}`);
  }
};