import api from "src/api";
import { Capacitor } from "@capacitor/core";
import { Filesystem, Directory } from "@capacitor/filesystem";
import { Share } from "@capacitor/share";

// ─── Guia do agendamento ──────────────────────────────────────────────────────

const blobErrorMessage = async (blob) => {
  try {
    return JSON.parse(await blob.text())?.message ?? null;
  } catch {
    return null;
  }
};

const blobToBase64 = (blob) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onerror = reject;
    reader.onload = () => resolve(String(reader.result).split(",")[1]);
    reader.readAsDataURL(blob);
  });

const saveNative = async (blob, fileName) => {
  const { uri } = await Filesystem.writeFile({
    path: fileName,
    data: await blobToBase64(blob),
    directory: Directory.Cache,
  });

  await Share.share({ title: fileName, url: uri });
};

const saveWeb = (blob, fileName) => {
  const blobUrl = window.URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = blobUrl;
  link.setAttribute("download", fileName);
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  window.URL.revokeObjectURL(blobUrl);
};

export const downloadMyAppointmentGuide = async (id, orderNumber) => {
  let response;

  try {
    response = await api.get(`/associado/appointment/${id}/guide`, { responseType: "blob" });
  } catch (error) {
    const payload = error?.response?.data;
    const message = payload instanceof Blob ? await blobErrorMessage(payload) : null;

    throw message ? new Error(message) : error;
  }

  const blob = new Blob([response.data], { type: "application/pdf" });
  const fileName = `guia_${orderNumber}.pdf`;

  if (Capacitor.isNativePlatform()) {
    await saveNative(blob, fileName);
    return;
  }

  saveWeb(blob, fileName);
};

// ─── Rotas do Associado ───────────────────────────────────────────────────────

export const getMyAppointments = async () => {
  const { data } = await api.get("/associado/appointment/my");
  return data.payload;
};

export const createAppointment = async (appointment) => {
  const { data } = await api.post("/associado/appointment", appointment);
  return data.payload;
};

export const acceptExamAppointment = async (id) => {
  const { data } = await api.put(`/associado/appointment/${id}/accept`);
  return data.payload;
};

export const refuseExamAppointment = async (id, refusalReason) => {
  const { data } = await api.put(`/associado/appointment/${id}/refuse`, {
    refusal_reason: refusalReason,
  });
  return data.payload;
};

export const cancelAppointment = async (id) => {
  const { data } = await api.put(`/associado/appointment/${id}`, { status: "cancelado" });
  return data.payload;
};

export const updateAppointment = async (id, payload) => {
  const { data } = await api.put(`/associado/appointment/${id}`, payload);
  return data.payload;
};

// ─── Rotas do Parceiro ────────────────────────────────────────────────────────

export const getPartnerAppointments = async () => {
  const { data } = await api.get("/parceiro/appointment");
  return data.payload;
};

export const approveAppointmentParceiro = async (id, payload) => {
  const { data } = await api.put(`/parceiro/appointment/${id}/approve`, payload);
  return data.payload;
};

export const rejectAppointmentParceiro = async (id) => {
  const { data } = await api.put(`/parceiro/appointment/${id}/reject`);
  return data.payload;
};

export const getAdminCounters = async () => {
  const { data } = await api.get("/appointment/admin/counters");
  return data.payload;
};

export const getAdminAppointmentsPaginated = async ({ page = 1, perPage = 10, filter, status } = {}) => {
  const params = { page, per_page: perPage };
  if (filter) params.search = filter;
  if (status) params.status = status;
  const { data } = await api.get("/appointment/admin/list", { params });
  return { data: { result: data.payload } };
};

export const approveAppointment = async (id, payload) => {
  const { data } = await api.put(`/appointment/${id}/approve`, payload);
  return data.payload;
};

export const rejectAppointment = async (id) => {
  const { data } = await api.put(`/appointment/${id}/reject`);
  return data.payload;
};
