"use client";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useAuth } from "./useAuth";
import { getEntityMetaConfig } from "../types/meta.types";
function useEntityWithMeta(entityType, entityId, options = {}) {
  var _a, _b;
  const {
    includeMeta = true,
    autoFetch = true,
    staleTime = 1e3 * 60 * 5,
    gcTime = 1e3 * 60 * 60
  } = options;
  const { user } = useAuth();
  const queryClient = useQueryClient();
  const config = getEntityMetaConfig(entityType);
  const queryKey = [
    "entity-with-meta",
    entityType,
    entityId,
    { includeMeta: includeMeta === true ? "all" : includeMeta }
  ];
  const query = useQuery({
    queryKey,
    queryFn: async () => {
      if (!config) {
        throw new Error(`Entity type '${entityType}' not configured`);
      }
      const params = new URLSearchParams();
      if (includeMeta === true) {
        params.set("includeMeta", "all");
      } else if (Array.isArray(includeMeta)) {
        params.set("includeMeta", includeMeta.join(","));
      }
      const url = `/api/v1/${config.apiPath}/${entityId}${params.toString() ? `?${params.toString()}` : ""}`;
      const response = await fetch(url, {
        headers: { "Content-Type": "application/json" }
      });
      if (!response.ok) {
        throw new Error(`Failed to fetch ${entityType}`);
      }
      const result = await response.json();
      return result.data;
    },
    enabled: autoFetch && !!user && !!entityId && !!config,
    staleTime,
    gcTime
  });
  const updateEntityMutation = useMutation({
    mutationFn: async ({
      updates,
      metaUpdates
    }) => {
      if (!config) {
        throw new Error(`Entity type '${entityType}' not configured`);
      }
      const payload = { ...updates };
      if (metaUpdates) {
        payload.meta = metaUpdates;
      }
      const response = await fetch(`/api/v1/${config.apiPath}/${entityId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload)
      });
      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.error || `Failed to update ${entityType}`);
      }
      const result = await response.json();
      return result.data;
    },
    onMutate: async ({ updates, metaUpdates }) => {
      await queryClient.cancelQueries({ queryKey });
      const previousData = queryClient.getQueryData(queryKey);
      queryClient.setQueryData(queryKey, (old) => {
        if (!old) return old;
        const newData = { ...old, ...updates };
        if (metaUpdates) {
          newData.meta = { ...old.meta, ...metaUpdates };
        }
        return newData;
      });
      return { previousData };
    },
    onError: (error, variables, context) => {
      if (context == null ? void 0 : context.previousData) {
        queryClient.setQueryData(queryKey, context.previousData);
      }
    },
    onSuccess: (data) => {
      queryClient.setQueryData(queryKey, data);
    }
  });
  const updateMeta = async (metaUpdates) => {
    return updateEntityMutation.mutateAsync({ metaUpdates });
  };
  const updateEntity = async (updates, metaUpdates) => {
    return updateEntityMutation.mutateAsync({ updates, metaUpdates });
  };
  const getMeta = (metaKey, defaultValue) => {
    var _a2, _b2;
    return ((_b2 = (_a2 = query.data) == null ? void 0 : _a2.meta) == null ? void 0 : _b2[metaKey]) ?? defaultValue;
  };
  const hasMeta = (metaKey) => {
    var _a2;
    return ((_a2 = query.data) == null ? void 0 : _a2.meta) ? metaKey in query.data.meta : false;
  };
  return {
    data: query.data,
    entity: query.data ? { ...query.data, meta: void 0 } : null,
    meta: ((_a = query.data) == null ? void 0 : _a.meta) || {},
    loading: query.isLoading,
    error: ((_b = query.error) == null ? void 0 : _b.message) || null,
    updateEntity,
    updateMeta,
    getMeta,
    hasMeta,
    refetch: query.refetch,
    isUpdating: updateEntityMutation.isPending
  };
}
function useUserWithMeta(userId, options) {
  return useEntityWithMeta("user", userId, options);
}
function useTaskWithMeta(taskId, options) {
  return useEntityWithMeta("task", taskId, options);
}
export {
  useEntityWithMeta,
  useTaskWithMeta,
  useUserWithMeta
};
