import { getAuthHeaders } from "./api-client";
import {
  CreateReservationDTO,
  Reservation,
  ReservationFilterParams,
  ReservationStats,
  UpdateReservationDTO,
} from "@/types/reservation";

const API_BASE = (process.env.NEXT_PUBLIC_API_URL || "http://localhost:3333").replace(/\/$/, "") + "/api";

const INITIAL_MOCK_RESERVATIONS: Reservation[] = [];

let localReservationStore: Reservation[] = [...INITIAL_MOCK_RESERVATIONS];

export async function getReservations(params?: ReservationFilterParams): Promise<{
  items: Reservation[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}> {
  try {
    const queryParams = new URLSearchParams();
    if (params?.search) queryParams.set("search", params.search);
    if (params?.status && params.status !== "ALL") queryParams.set("status", params.status);
    if (params?.customerId && params.customerId !== "ALL") queryParams.set("customerId", params.customerId);
    if (params?.equipmentId && params.equipmentId !== "ALL") queryParams.set("equipmentId", params.equipmentId);
    if (params?.page) queryParams.set("page", String(params.page));
    if (params?.limit) queryParams.set("limit", String(params.limit));

    const res = await fetch(`${API_BASE}/reservations?${queryParams.toString()}`, {
      headers: getAuthHeaders(),
      cache: "no-store",
    });

    if (res.ok) {
      const data = await res.json();
      if (data && Array.isArray(data.items)) {
        return data;
      }
      if (Array.isArray(data)) {
        return { items: data, total: data.length, page: 1, limit: 50, totalPages: 1 };
      }
    }
  } catch {
    // fallback
  }

  let filtered = [...localReservationStore];

  if (params?.search) {
    const term = params.search.toLowerCase();
    filtered = filtered.filter(
      (r) =>
        r.code.toLowerCase().includes(term) ||
        (r.customer && r.customer.name.toLowerCase().includes(term)) ||
        (r.equipment && r.equipment.code.toLowerCase().includes(term)) ||
        (r.equipment && r.equipment.model.toLowerCase().includes(term))
    );
  }

  if (params?.status && params.status !== "ALL") {
    filtered = filtered.filter((r) => r.status === params.status);
  }

  if (params?.customerId && params.customerId !== "ALL") {
    filtered = filtered.filter((r) => r.customerId === params.customerId);
  }

  if (params?.equipmentId && params.equipmentId !== "ALL") {
    filtered = filtered.filter((r) => r.equipmentId === params.equipmentId);
  }

  const page = params?.page || 1;
  const limit = params?.limit || 20;
  const total = filtered.length;
  const totalPages = Math.ceil(total / limit) || 1;
  const startIndex = (page - 1) * limit;
  const items = filtered.slice(startIndex, startIndex + limit);

  return { items, total, page, limit, totalPages };
}

export async function getReservationStats(): Promise<ReservationStats> {
  try {
    const res = await fetch(`${API_BASE}/reservations/stats`, {
      headers: getAuthHeaders(),
      cache: "no-store",
    });
    if (res.ok) {
      const stats = await res.json();
      if (stats && (stats.total > 0 || stats.confirmed > 0)) {
        return stats;
      }
    }
  } catch {
    // fallback
  }

  const total = localReservationStore.length;
  const confirmed = localReservationStore.filter((r) => r.status === "CONFIRMED").length;
  const pending = localReservationStore.filter((r) => r.status === "PENDING").length;
  const converted = localReservationStore.filter((r) => r.status === "CONVERTED").length;
  const totalDeposit = localReservationStore.reduce(
    (acc, r) => acc + (Number(r.depositAmount) || 0),
    0
  );
  const conversionRate = total > 0 ? Math.round((converted / total) * 100) : 0;

  return { total, confirmed, pending, converted, totalDeposit, conversionRate };
}

export async function getReservationById(id: string): Promise<Reservation | null> {
  try {
    const res = await fetch(`${API_BASE}/reservations/${id}`, {
      headers: getAuthHeaders(),
      cache: "no-store",
    });
    if (res.ok) {
      return await res.json();
    }
  } catch {
    // fallback
  }

  return localReservationStore.find((r) => r.id === id) || null;
}

export async function createReservation(data: CreateReservationDTO): Promise<Reservation> {
  try {
    const res = await fetch(`${API_BASE}/reservations`, {
      method: "POST",
      headers: getAuthHeaders(),
      body: JSON.stringify(data),
    });

    if (res.ok) {
      return await res.json();
    }
  } catch {
    // fallback
  }

  const code = `RES-2026-${String(localReservationStore.length + 20).padStart(4, "0")}`;

  const newRes: Reservation = {
    id: `res-${Date.now()}`,
    companyId: "comp-default",
    code,
    customerId: data.customerId,
    equipmentId: data.equipmentId,
    startDate: data.startDate,
    endDate: data.endDate,
    depositAmount: Number(data.depositAmount) || 0,
    validUntil: data.validUntil || data.startDate,
    notes: data.notes || null,
    status: data.status || "CONFIRMED",
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
    customer: {
      id: data.customerId,
      name: "Cliente Selecionado",
      document: "00.000.000/0001-00",
    },
    equipment: {
      id: data.equipmentId,
      code: "EQ-RES",
      assetTag: "PAT-RES",
      brand: "Equipamento",
      model: "Reservado",
      dailyRate: 500,
    },
  };

  localReservationStore = [newRes, ...localReservationStore];
  return newRes;
}

export async function updateReservation(
  id: string,
  data: UpdateReservationDTO
): Promise<Reservation> {
  try {
    const res = await fetch(`${API_BASE}/reservations/${id}`, {
      method: "PATCH",
      headers: getAuthHeaders(),
      body: JSON.stringify(data),
    });

    if (res.ok) {
      return await res.json();
    }
  } catch {
    // fallback
  }

  const index = localReservationStore.findIndex((r) => r.id === id);
  if (index === -1) {
    throw new Error("Reserva não encontrada.");
  }

  const updated: Reservation = {
    ...localReservationStore[index],
    ...data,
    depositAmount:
      data.depositAmount !== undefined
        ? Number(data.depositAmount)
        : localReservationStore[index].depositAmount,
    updatedAt: new Date().toISOString(),
  };

  localReservationStore[index] = updated;
  return updated;
}

export async function convertReservationToRental(id: string): Promise<Reservation> {
  try {
    const res = await fetch(`${API_BASE}/reservations/${id}/convert`, {
      method: "POST",
      headers: getAuthHeaders(),
    });

    if (res.ok) {
      return await res.json();
    }
  } catch {
    // fallback
  }

  return updateReservation(id, { status: "CONVERTED" });
}

export async function deleteReservation(id: string): Promise<boolean> {
  try {
    const res = await fetch(`${API_BASE}/reservations/${id}`, {
      method: "DELETE",
      headers: getAuthHeaders(),
    });

    if (res.ok) {
      return true;
    }
  } catch {
    // fallback
  }

  localReservationStore = localReservationStore.filter((r) => r.id !== id);
  return true;
}
