import { getAuthHeaders } from "./api-client";
import {
  CreateRentalDTO,
  Rental,
  RentalFilterParams,
  RentalItem,
  RentalStats,
  UpdateRentalDTO,
} from "@/types/rental";

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

const INITIAL_MOCK_RENTALS: Rental[] = [];

let localRentalStore: Rental[] = [...INITIAL_MOCK_RENTALS];

export async function getRentals(params?: RentalFilterParams): Promise<{
  items: Rental[];
  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?.page) queryParams.set("page", String(params.page));
    if (params?.limit) queryParams.set("limit", String(params.limit));

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

  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.customer && r.customer.document.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);
  }

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

  const total = localRentalStore.length;
  const inProgress = localRentalStore.filter((r) => r.status === "IN_PROGRESS").length;
  const quote = localRentalStore.filter((r) => r.status === "QUOTE").length;
  const finished = localRentalStore.filter((r) => r.status === "FINISHED").length;
  const reserved = localRentalStore.filter((r) => r.status === "RESERVED").length;
  const canceled = localRentalStore.filter((r) => r.status === "CANCELED").length;
  const totalRevenue = localRentalStore
    .filter((r) => r.status === "IN_PROGRESS" || r.status === "FINISHED")
    .reduce((acc, r) => acc + (Number(r.total) || 0), 0);

  return { total, inProgress, quote, finished, reserved, canceled, totalRevenue };
}

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

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

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

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

  const start = new Date(data.startDate);
  const end = new Date(data.endDate);
  const days = Math.max(Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)), 1);

  let subtotal = 0;
  const items: RentalItem[] = data.items.map((item, idx) => {
    const total = item.quantity * item.dailyRate * days;
    subtotal += total;
    return {
      id: `ri-${Date.now()}-${idx}`,
      equipmentId: item.equipmentId,
      quantity: item.quantity,
      dailyRate: item.dailyRate,
      total,
      equipment: {
        id: item.equipmentId,
        code: "EQ-AUT",
        assetTag: "PAT-AUT",
        brand: "Equipamento",
        model: "Locado",
      },
    };
  });

  const freight = Number(data.freight) || 0;
  const discount = Number(data.discount) || 0;
  const total = Math.max(subtotal + freight - discount, 0);

  const prefix = data.status === "QUOTE" ? "ORC" : "LOC";
  const code = `${prefix}-2026-${String(localRentalStore.length + 100).padStart(4, "0")}`;

  const newRental: Rental = {
    id: `rent-${Date.now()}`,
    companyId: "comp-default",
    customerId: data.customerId,
    code,
    startDate: data.startDate,
    endDate: data.endDate,
    subtotal,
    freight,
    discount,
    total,
    operator: data.operator || null,
    notes: data.notes || null,
    status: data.status || "QUOTE",
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
    customer: {
      id: data.customerId,
      name: "Cliente Selecionado",
      document: "00.000.000/0001-00",
    },
    items,
  };

  localRentalStore = [newRental, ...localRentalStore];
  return newRental;
}

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

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

    const errText = await res.text();
    console.error("Failed to update rental API:", res.status, errText);
  } catch (err) {
    console.error("Error fetching update rental API:", err);
  }

  const index = localRentalStore.findIndex((r) => r.id === id);
  if (index !== -1) {
    const current = localRentalStore[index];
    const updated: Rental = {
      ...current,
      ...data,
      items: data.items
        ? data.items.map((item, idx) => ({
            id: `ri-${id}-${idx}`,
            equipmentId: item.equipmentId,
            quantity: item.quantity,
            dailyRate: item.dailyRate,
            total: item.quantity * item.dailyRate * 30,
          }))
        : current.items,
      updatedAt: new Date().toISOString(),
    };

    localRentalStore[index] = updated;
    return updated;
  }

  throw new Error("Erro ao atualizar contrato de locação no servidor.");
}

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

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

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

export async function rebuildAllFinancials(): Promise<{ message: string; results: any[] }> {
  const res = await fetch(`${API_BASE}/rentals/rebuild-all-financials`, {
    method: "POST",
    headers: getAuthHeaders(),
  });
  if (res.ok) {
    return await res.json();
  }
  return { message: "Erro ao reconstruir lançamentos.", results: [] };
}

export async function rebuildRentalFinancials(rentalId: string): Promise<any> {
  const res = await fetch(`${API_BASE}/rentals/${rentalId}/rebuild-financials`, {
    method: "POST",
    headers: getAuthHeaders(),
  });
  if (res.ok) {
    return await res.json();
  }
  return null;
}
