import { getAuthHeaders } from "./api-client";
import {
  CreateEquipmentDTO,
  Equipment,
  EquipmentCategory,
  EquipmentFilterParams,
  EquipmentStats,
  UpdateEquipmentDTO,
} from "@/types/equipment";

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

const INITIAL_MOCK_CATEGORIES: EquipmentCategory[] = [];

const INITIAL_MOCK_EQUIPMENT: Equipment[] = [];

let localEquipmentStore: Equipment[] = [...INITIAL_MOCK_EQUIPMENT];

export async function getEquipmentCategories(): Promise<EquipmentCategory[]> {
  try {
    const res = await fetch(`${API_BASE}/equipment/categories`, {
      headers: getAuthHeaders(),
      cache: "no-store",
    });
    if (res.ok) {
      const data = await res.json();
      if (Array.isArray(data)) return data;
    }
  } catch {
    // fallback
  }
  return INITIAL_MOCK_CATEGORIES;
}

export async function getEquipment(params?: EquipmentFilterParams): Promise<{
  items: Equipment[];
  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?.categoryId && params.categoryId !== "ALL") queryParams.set("categoryId", params.categoryId);
    if (params?.page) queryParams.set("page", String(params.page));
    if (params?.limit) queryParams.set("limit", String(params.limit));

    const res = await fetch(`${API_BASE}/equipment?${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 = [...localEquipmentStore];

  if (params?.search) {
    const term = params.search.toLowerCase();
    filtered = filtered.filter(
      (e) =>
        e.code.toLowerCase().includes(term) ||
        e.assetTag.toLowerCase().includes(term) ||
        e.brand.toLowerCase().includes(term) ||
        e.model.toLowerCase().includes(term) ||
        (e.serialNumber && e.serialNumber.toLowerCase().includes(term))
    );
  }

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

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

  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 getEquipmentStats(): Promise<EquipmentStats> {
  try {
    const res = await fetch(`${API_BASE}/equipment/stats`, {
      headers: getAuthHeaders(),
      cache: "no-store",
    });
    if (res.ok) {
      const stats = await res.json();
      if (stats && (stats.total > 0 || stats.available > 0)) {
        return stats;
      }
    }
  } catch {
    // fallback
  }

  const total = localEquipmentStore.length;
  const available = localEquipmentStore.filter((e) => e.status === "AVAILABLE").length;
  const rented = localEquipmentStore.filter((e) => e.status === "RENTED").length;
  const maintenance = localEquipmentStore.filter((e) => e.status === "MAINTENANCE").length;
  const reserved = localEquipmentStore.filter((e) => e.status === "RESERVED").length;
  const totalAcquisitionValue = localEquipmentStore.reduce(
    (acc, e) => acc + (Number(e.acquisitionValue) || 0),
    0
  );

  return { total, available, rented, maintenance, reserved, totalAcquisitionValue };
}

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

  return localEquipmentStore.find((e) => e.id === id) || null;
}

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

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

  const cat = INITIAL_MOCK_CATEGORIES.find((c) => c.id === data.categoryId) || INITIAL_MOCK_CATEGORIES[0] || { id: "", name: "Default", description: "", color: "" };

  const newEquip: Equipment = {
    id: `eq-${Date.now()}`,
    companyId: "comp-default",
    categoryId: data.categoryId,
    code: data.code,
    assetTag: data.assetTag,
    brand: data.brand,
    model: data.model,
    year: data.year || null,
    serialNumber: data.serialNumber || null,
    acquisitionValue: Number(data.acquisitionValue) || 0,
    dailyRate: Number(data.dailyRate) || 0,
    weeklyRate: Number(data.weeklyRate) || 0,
    monthlyRate: Number(data.monthlyRate) || 0,
    status: data.status || "AVAILABLE",
    hourMeter: data.hourMeter !== undefined ? Number(data.hourMeter) : null,
    mileage: data.mileage !== undefined ? Number(data.mileage) : null,
    qrCode: data.qrCode || null,
    notes: data.notes || null,
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
    category: cat,
    _count: { serviceOrders: 0, rentalItems: 0 },
    photos: [],
    serviceOrders: [],
    rentalItems: [],
  };

  localEquipmentStore = [newEquip, ...localEquipmentStore];
  return newEquip;
}

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

    if (res.ok) {
      return await res.json();
    }
  } catch (err) {
    console.warn("API updateEquipment failed, checking local store...", err);
  }

  const index = localEquipmentStore.findIndex((e) => e.id === id);
  if (index === -1) {
    throw new Error("Equipamento não encontrado no banco de dados.");
  }

  const cat = data.categoryId
    ? INITIAL_MOCK_CATEGORIES.find((c) => c.id === data.categoryId) || localEquipmentStore[index].category
    : localEquipmentStore[index].category;

  const updated: Equipment = {
    ...localEquipmentStore[index],
    ...data,
    acquisitionValue:
      data.acquisitionValue !== undefined
        ? Number(data.acquisitionValue)
        : localEquipmentStore[index].acquisitionValue,
    dailyRate: data.dailyRate !== undefined ? Number(data.dailyRate) : localEquipmentStore[index].dailyRate,
    weeklyRate: data.weeklyRate !== undefined ? Number(data.weeklyRate) : localEquipmentStore[index].weeklyRate,
    monthlyRate: data.monthlyRate !== undefined ? Number(data.monthlyRate) : localEquipmentStore[index].monthlyRate,
    hourMeter: data.hourMeter !== undefined ? Number(data.hourMeter) : localEquipmentStore[index].hourMeter,
    category: cat,
    updatedAt: new Date().toISOString(),
  };

  localEquipmentStore[index] = updated;
  return updated;
}

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

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

  localEquipmentStore = localEquipmentStore.filter((e) => e.id !== id);
  return true;
}
