import { getAuthHeaders } from "./api-client";
import {
  CreateCustomerDTO,
  Customer,
  CustomerFilterParams,
  CustomerStats,
  UpdateCustomerDTO,
} from "@/types/customer";

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

const INITIAL_MOCK_CUSTOMERS: Customer[] = [];

let localCustomersStore: Customer[] = [...INITIAL_MOCK_CUSTOMERS];

export async function fetchAddressByCep(cep: string): Promise<{
  zipCode: string;
  street: string;
  district: string;
  city: string;
  state: string;
} | null> {
  const cleanCep = cep.replace(/\D/g, "");
  if (cleanCep.length !== 8) return null;

  try {
    const res = await fetch(`https://viacep.com.br/ws/${cleanCep}/json/`);
    if (!res.ok) return null;
    const data = await res.json();
    if (data.erro) return null;

    return {
      zipCode: data.cep || cep,
      street: data.logradouro || "",
      district: data.bairro || "",
      city: data.localidade || "",
      state: data.uf || "",
    };
  } catch {
    return null;
  }
}

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

    const res = await fetch(`${API_BASE}/customers?${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 {
    // API server offline or unreachable, fallback to memory store
  }

  // Fallback memory filter
  let filtered = [...localCustomersStore];

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

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

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

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

  const total = localCustomersStore.length;
  const active = localCustomersStore.filter((c) => c.status === "ACTIVE").length;
  const inactive = localCustomersStore.filter((c) => c.status === "INACTIVE").length;
  const delinquent = localCustomersStore.filter((c) => c.status === "DELINQUENT").length;
  const totalCreditLimit = localCustomersStore.reduce((acc, c) => acc + (Number(c.creditLimit) || 0), 0);

  return { total, active, inactive, delinquent, totalCreditLimit };
}

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

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

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

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

  const newCust: Customer = {
    id: `cust-${Date.now()}`,
    companyId: "comp-default",
    type: data.type,
    name: data.name,
    document: data.document,
    email: data.email || null,
    phone: data.phone || null,
    mobile: data.mobile || null,
    contactName: data.contactName || null,
    creditLimit: Number(data.creditLimit) || 0,
    status: data.status || "ACTIVE",
    notes: data.notes || null,
    zipCode: data.zipCode || null,
    street: data.street || null,
    number: data.number || null,
    complement: data.complement || null,
    district: data.district || null,
    city: data.city || null,
    state: data.state || null,
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
    _count: { rentals: 0, receivables: 0, documents: 0 },
    rentals: [],
    receivables: [],
    documents: [],
  };

  localCustomersStore = [newCust, ...localCustomersStore];
  return newCust;
}

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

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

  const index = localCustomersStore.findIndex((c) => c.id === id);
  if (index === -1) {
    throw new Error("Cliente não encontrado.");
  }

  const updated: Customer = {
    ...localCustomersStore[index],
    ...data,
    creditLimit: data.creditLimit !== undefined ? Number(data.creditLimit) : localCustomersStore[index].creditLimit,
    updatedAt: new Date().toISOString(),
  };

  localCustomersStore[index] = updated;
  return updated;
}

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

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

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