import { getAuthHeaders } from "./api-client";
import {
  Category,
  CategoryFilterParams,
  CategoryStats,
  CreateCategoryDTO,
  UpdateCategoryDTO,
} from "@/types/category";

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

const INITIAL_MOCK_CATEGORIES: Category[] = [];

let localCategoryStore: Category[] = [...INITIAL_MOCK_CATEGORIES];

export async function getCategories(params?: CategoryFilterParams): Promise<{
  items: Category[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}> {
  try {
    const queryParams = new URLSearchParams();
    if (params?.search) queryParams.set("search", params.search);
    if (params?.page) queryParams.set("page", String(params.page));
    if (params?.limit) queryParams.set("limit", String(params.limit));

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

  if (params?.search) {
    const term = params.search.toLowerCase();
    filtered = filtered.filter(
      (c) =>
        c.name.toLowerCase().includes(term) ||
        (c.description && c.description.toLowerCase().includes(term))
    );
  }

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

  const totalCategories = localCategoryStore.length;
  const totalEquipment = localCategoryStore.reduce(
    (acc, cat) => acc + (cat._count?.equipment || 0),
    0
  );

  const sorted = [...localCategoryStore].sort(
    (a, b) => (b._count?.equipment || 0) - (a._count?.equipment || 0)
  );

  const topCategory = sorted[0]
    ? { name: sorted[0].name, count: sorted[0]._count?.equipment || 0 }
    : null;

  return { totalCategories, totalEquipment, topCategory };
}

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

  return localCategoryStore.find((c) => c.id === id) || null;
}

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

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

  const newCat: Category = {
    id: `cat-${Date.now()}`,
    companyId: "comp-default",
    name: data.name,
    description: data.description || null,
    color: data.color || "#2563eb",
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
    _count: { equipment: 0 },
    equipment: [],
  };

  localCategoryStore = [newCat, ...localCategoryStore];
  return newCat;
}

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

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

  const index = localCategoryStore.findIndex((c) => c.id === id);
  if (index === -1) {
    throw new Error("Categoria não encontrada.");
  }

  const updated: Category = {
    ...localCategoryStore[index],
    ...data,
    updatedAt: new Date().toISOString(),
  };

  localCategoryStore[index] = updated;
  return updated;
}

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

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

  const cat = localCategoryStore.find((c) => c.id === id);
  if (cat && (cat._count?.equipment || 0) > 0) {
    throw new Error(`Não é possível excluir a categoria pois existem ${cat._count?.equipment} equipamentos vinculados a ela.`);
  }

  localCategoryStore = localCategoryStore.filter((c) => c.id !== id);
  return true;
}
