"use client";

import React, { useContext, useState, useEffect, startTransition, ReactNode, createContext } from "react";
import { useAuth } from "@/contexts/AuthContext";
import * as productsApi from "@/lib/api/products";
import * as bookingsApi from "@/lib/api/bookings";
import { Product } from "@/data/products";
import { ApiError } from "@/lib/api";

// Adapter: maps BookingApi to the Reservation shape used by admin pages
export interface Reservation {
  id: string;
  clientName: string;
  email: string;
  phone: string;
  service: string;
  date: string;
  time: string;
  status: "pending" | "confirmed" | "cancelled";
  createdAt: string;
}

function toReservation(b: bookingsApi.BookingApi): Reservation {
  return {
    id: b.id,
    clientName: b.client_name ?? "—",
    email: b.client_email ?? "—",
    phone: b.client_phone ?? "—",
    service: b.service_note ?? "—",
    date: b.slot_date,
    time: b.slot_start,
    status: b.status === "completed" || b.status === "no_show" ? "confirmed" : b.status as Reservation["status"],
    createdAt: b.created_at.slice(0, 10),
  };
}

interface AdminContextType {
  isAdmin: boolean;
  products: Product[];
  productsLoading: boolean;
  refreshProducts: () => Promise<void>;
  addProduct: (payload: productsApi.ProductPayload) => Promise<Product>;
  updateProduct: (id: string, payload: Partial<productsApi.ProductPayload>) => Promise<void>;
  deleteProduct: (id: string) => Promise<void>;
  reservations: Reservation[];
  reservationsLoading: boolean;
  refreshReservations: (silent?: boolean) => Promise<void>;
  updateReservationStatus: (id: string, status: "confirmed" | "cancelled") => Promise<void>;
  deleteReservation: (id: string) => Promise<void>;
}

const AdminContext = createContext<AdminContextType | undefined>(undefined);

export const AdminProvider = ({ children }: { children: ReactNode }) => {
  const { isAdmin } = useAuth();
  const [products, setProducts] = useState<Product[]>([]);
  const [productsLoading, setProductsLoading] = useState(false);
  const [reservations, setReservations] = useState<Reservation[]>([]);
  const [reservationsLoading, setReservationsLoading] = useState(false);

  const refreshProducts = async () => {
    if (!isAdmin) return;
    setProductsLoading(true);
    try {
      const res = await productsApi.adminListProducts();
      setProducts(res.data);
    } finally {
      setProductsLoading(false);
    }
  };

  const refreshReservations = async (silent = false) => {
    if (!isAdmin) return;
    if (!silent) setReservationsLoading(true);
    try {
      const res = await bookingsApi.adminListBookings();
      setReservations(res.data.map(toReservation));
    } finally {
      if (!silent) setReservationsLoading(false);
    }
  };

  useEffect(() => {
    if (isAdmin) {
      startTransition(() => {
        refreshProducts();
        refreshReservations();
      });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isAdmin]);

  const addProduct = async (payload: productsApi.ProductPayload): Promise<Product> => {
    const newProduct = await productsApi.adminCreateProduct(payload);
    setProducts((prev) => [newProduct, ...prev]);
    return newProduct;
  };

  const updateProduct = async (id: string, payload: Partial<productsApi.ProductPayload>) => {
    const updated = await productsApi.adminUpdateProduct(id, payload);
    setProducts((prev) => prev.map((p) => (p.id === id ? updated : p)));
  };

  const deleteProduct = async (id: string) => {
    await productsApi.adminDeleteProduct(id);
    setProducts((prev) => prev.filter((p) => p.id !== id));
  };

  const updateReservationStatus = async (id: string, status: "confirmed" | "cancelled") => {
    await bookingsApi.adminUpdateBookingStatus(id, status);
    setReservations((prev) =>
      prev.map((r) => (r.id === id ? { ...r, status } : r))
    );
    // Sync with server silently — no loading flash
    refreshReservations(true);
  };

  const deleteReservation = async (id: string) => {
    await bookingsApi.adminDeleteBooking(id);
    setReservations((prev) => prev.filter((r) => r.id !== id));
  };

  return (
    <AdminContext.Provider
      value={{
        isAdmin,
        products,
        productsLoading,
        refreshProducts,
        addProduct,
        updateProduct,
        deleteProduct,
        reservations,
        reservationsLoading,
        refreshReservations,
        updateReservationStatus,
        deleteReservation,
      }}
    >
      {children}
    </AdminContext.Provider>
  );
};

export const useAdmin = () => {
  const ctx = useContext(AdminContext);
  if (!ctx) throw new Error("useAdmin must be used within AdminProvider");
  return ctx;
};
